[antlr-interest] best way to deal with nested statements

Gordon Tyler Gordon.Tyler at quest.com
Fri Jun 25 08:30:12 PDT 2010


Hmmm... Sorry, my experience with ANTLR is limited to grammars for known limited languages. I haven't had to do something like that with rules matching unknown contents.

-----Original Message-----
From: Scherer Markus [mailto:markus.scherer at inet-logistics.com] 
Sent: June 25, 2010 10:37 AM
To: Gordon Tyler; antlr-interest at antlr.org
Subject: Re: best way to deal with nested statements

Thanks for your quick response Gordon. 

Unfortunately, this solution does not seem to work. If I define "stuff" as generic as I want it to be (like (options {greedy=false;} : .)*)) it isn't able to compile either (The following alternatives can never be matched: 2). I guess because the END of a codeBlock would get matched by "stuff" in statement. If define stuff as

stuff	:	(options {greedy=false;} : ~(END))* ;

it does not match all tokens I am interested in :-/. 

-----Ursprüngliche Nachricht-----
Von: Gordon Tyler [mailto:Gordon.Tyler at quest.com] 
Gesendet: Freitag, 25. Juni 2010 15:53
An: Gordon Tyler; Scherer Markus; antlr-interest at antlr.org
Betreff: RE: best way to deal with nested statements

Sorry, this should be better:

statement: (stuff|codeBlock) SEMI ;
codeBlock: BEGIN statement* END ;

-----Original Message-----
From: antlr-interest-bounces at antlr.org [mailto:antlr-interest-bounces at antlr.org] On Behalf Of Gordon Tyler
Sent: June 25, 2010 9:51 AM
To: Scherer Markus; antlr-interest at antlr.org
Subject: Re: [antlr-interest] best way to deal with nested statements

Why not something like this:

statements: (stuff|codeBlock);
codeBlock: BEGIN statements END;

-----Original Message-----
From: antlr-interest-bounces at antlr.org [mailto:antlr-interest-bounces at antlr.org] On Behalf Of Scherer Markus
Sent: June 25, 2010 9:03 AM
To: antlr-interest at antlr.org
Subject: [antlr-interest] best way to deal with nested statements

Hi there antlr folk!

As I have mentioned in a former thread I am currently working on a grammar that splits SQL*PLUS files in normal SQL-statements and PL/SQL-blocks.

The PL/SQL-blocks are a bit tricky, because the can contain nested blocks like

BEGIN
            …
            BEGIN
                        …
            END;
END;

I thought about a mechanism, that increases a counter when a BEGIN is found and decreases it when a END; is found:

@members {
            int _iNestLevel = 0;
}

pl_sql_block
            :
            (           ((BEGIN {System.out.println("begin (nestlevel: " + (++_iNestLevel) + ")");})| DECLARE)
            |           CREATE         (OR REPLACE
                                   |PROCEDURE
                                   |FUNCTION
                                   |PACKAGE)
            )           pl_sql_block_content
            ;


pl_sql_block_content
            :           {_iNestLevel < 16}? (options {greedy=false;} : .)*
                        (           BEGIN {System.out.println("begin (nestlevel: " + (++_iNestLevel) + ")");}
                        |           END SEMI{System.out.println("end (nestlevel: " + (--_iNestLevel) + ")");})
                        (           {_iNestLevel > 0}? pl_sql_block_content
                        )
            ;

I tried to eliminate recursion-issues with the predicates, but antlr nevertheless considers the grammar wrong and throws following error when I try to compile it:

[14:46:43] error(206): PLSQLSplitter.g:62:34: Alternative 2: after matching input such as SEMI SL_COMMENT ML_COMMENT BEGIN BEGIN SEMI END SEMI END SEMI END SEMI BEGIN decision cannot predict what comes next due to recursion overflow to pl_sql_block_content from pl_sql_block_content


The second solution that came to my mind was a proper recursive grammar (like e.g. the expression grammar from the book), but I think that’s a little overkill for a simple splitter.

I attached the whole grammar in case the error isn’t obvious from the two rules above.

Thanks in advance
Markus



List: http://www.antlr.org/mailman/listinfo/antlr-interest
Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address


More information about the antlr-interest mailing list