[antlr-interest] PL/SQL grammar problems

Dussinger, Steven Steven.Dussinger at bcbsfl.com
Sun Dec 2 09:28:52 PST 2007


Hi All:

I recently was tasked to look into parsing PL/SQL from Oracle in order
to gather some metrics. I found the PL/SQL grammar on the Antlr site and
am trying to use it, but I've run into a problem that I just can't seem
to figure out how to fix.

My test case (as follows) contains three procedure definitions, each
containing a simple if-then statement. The only difference in the three
procedures is the location of the parens in the if clause. The first two
procedures parse just fine (with parens around the entire boolean
expression or with no parens at all), but the third procedure (with
parens surrounding only the calculation portion of the boolean
expression) fails with the following messages:

line 36:22: expecting "then", found '<'
line 39:11: unexpected token: IF
line 42:1: expecting EOF, found 'END'

The test case is as follows:

CREATE OR REPLACE 
PACKAGE BODY p_accounts_payable_1
IS

   PROCEDURE works (
      po_s_return_code      IN OUT   VARCHAR2
   )
   IS

   BEGIN
      IF     (X + Y < 100) -- Note the parens surround the entire
boolean expression
      THEN
         po_s_return_code := '0';
      END IF;
   END;

   PROCEDURE works2 (
      po_s_return_code      IN OUT   VARCHAR2
   )
   IS

   BEGIN
      IF     X + Y < 100 -- Note no parens at all
      THEN
         po_s_return_code := '0';
      END IF;
   END;

   PROCEDURE fails (
      po_s_return_code      IN OUT   VARCHAR2
   )
   IS

   BEGIN
      IF     (X + Y) < 100 -- Note the parens surround the calculation
only (not the boolean expression)
      			   -- This one fails to parse.
      THEN
         po_s_return_code := '0';
      END IF;
   END;

END;

I think I've narrowed the problem down to the following portion of the
grammar:

boolean_factor    returns [ CommonToken r = null ] :
          ( OPEN_PAREN boolean_exp CLOSE_PAREN ) =>
        o:OPEN_PAREN boolean_exp cp:CLOSE_PAREN 
      | user_defined_function
      | ( plsql_expression
      ( (relational_op plsql_expression) =>( r=relational_op
          plsql_expression )
      | ( "is" ) => ( i:"is" (no:"not")? n:"null" )
      | ( ( "not" ) ? "like") =>( (n1:"not")? l:"like" match_string )
      | ( ( "not" ) ? "between") => (n2:"not")? b:"between"
plsql_expression
                                a:"and" plsql_expression 
      | ( (n3:"not")? in:"in" op:OPEN_PAREN plsql_exp_list
c2:CLOSE_PAREN )
      | ( ( cursor_name | subquery )
           pc:PERCENTAGE
           (nf:"notfound"
            | fo:"found"
            | io:"isopen"
        ) ) )? )
      | ( cursor_name (p3:PERCENTAGE
          (n4:"notfound"
         |  f2:"found"
         | i2:"isopen"
      )))?
      | boolean_literal
      ;

It seems that I need to add parens around the plsql_expression
relational_op... portion of this rule, but that seems to add ambiguity
to the first clause, and no matter how I tried to add those parens, it
fails. Does anyone have some pointers they could give me (understanding
that I'm not the most advanced parser guy in the world :-))...

Thanks.

--Steve


Blue Cross Blue Shield of Florida, Inc., and its subsidiary and affiliate companies are not responsible for errors or omissions in this e-mail message. Any personal comments made in this e-mail do not reflect the views of Blue Cross Blue Shield of Florida, Inc.  The information contained in this document may be confidential and intended solely for the use of the individual or entity to whom it is addressed.  This document may contain material that is privileged or protected from disclosure under applicable law.  If you are not the intended recipient or the individual responsible for delivering to the intended recipient, please (1) be advised that any use, dissemination, forwarding, or copying of this document IS STRICTLY PROHIBITED; and (2) notify sender immediately by telephone and destroy the document. THANK YOU.



More information about the antlr-interest mailing list