[antlr-interest] if-then-else - Grammar generates faultyparser code

Anthony Youngman Anthony.Youngman at ECA-International.com
Fri Apr 23 02:59:07 PDT 2004


Adding to this (and just giving a hint ...) I've been trying to get my
if-then-else to behave, and if I left-factor it blows up on me.
 
The following is the relelevant bit of my parser ...
 
ifst : ( IF^ expr ( thenclause (nl!)? elseclause | thenclause |
elseclause ) );
//ifst : ( IF^ expr ( thenclause ( (nl!)? elseclause)? | elseclause ) );
 
thenclause : ( THEN^
 ( statement_line
 | nl! statement_list "END"!
 ) );
 
elseclause : ( ELSE^
 ( statement_line
 | nl! statement_list "END"!
 ) );

 
The commented-out bit is, I think, a correct left-factor of the working
version, but it blows up antlr.Tool. Because an optional clause itself
starts with an optional clause? Unfortunately the "nl"s are significant,
and given that I need to handle a variety of clauses (where just one
such is necessary and sufficient) I don't want to have to specify all
the alternatives the first way ...
 
If my problem is related to the original, fine. If it isn't, don't worry
too much - I'll tackle it later
 
Cheers,
Wol

________________________________

From: Jeff Vincent [mailto:JVincent at Novell.Com] 
Sent: 22 April 2004 17:01
To: antlr-interest at yahoogroups.com
Subject: Re: [antlr-interest] if-then-else - Grammar generates
faultyparser code


Here is my if-then-else.  I didn't let ANTLR build the AST directly, I
did it myself to get things rooted the way I wanted with some imaginary
tokens.  I also didn't create special rules for the 'then' or the 'else'
part.  The ifFalseblock will be null if the else is omitted.
 
statement options {defaultErrorHandler=true;} :
  ( 
    ...

  |! stateIf:IF LPAREN! ifcond:expression RPAREN! iftrueblock:combo 
        ( options { greedy = true; } : ELSE! iffalseblock:combo )?
   {    #statement = #(#stateIf, #(#[EXPRESSION, "EXPRESSION"],
#ifcond), 
            #(#[COMBO, "COMBO"], #iftrueblock), #(#[COMBO, "COMBO"],
#iffalseblock)); 
    }
 
    ...
    ) ;
  
This has worked since ANTLR 2.7.0 (or 2.7.1? - ack! - I can't recall)
and I am currently using ANTLR 2.7.3.
 
If you care, I also rolled my own AST parser rules for all conditional
expressions (for, if-then-else, while, do-while, switch-case,
try-catch-finally) so I can control when the conditional parts actually
get parsed.  I am using all this as part of a run-time scripting
language (initially based loosly on 'C' w/ some Java-isms) using ANTLR
at the core.  The code that does the work is built into the AST parser
(action code), so the act of running the parser causes the actual
run-time execution.  I therefore had to only let the AST parser parse
things that actually should be "executed".  Here is a snippet of the AST
parser rule for my IF-THEN-ELSE statement:
 
statement :
(
 ...
 
   | #( astIF:IF
     {
      MyResult result = null;
      AST cond = null, ifTrue = null, ifFalse = null;
 
      //
      //Pull individual IF components of AST
      //
      cond = #astIF.getFirstChild();
      ifTrue = cond.getNextSibling();
      ifFalse = ifTrue.getNextSibling();
 
      cond = cond.getFirstChild();
      ifTrue = ifTrue.getFirstChild();
      ifFalse = ifFalse.getFirstChild();
 
      //
      //Execute the IF condition
      //
      result = assignmentExpression(cond); //<-- ANTLR parses (executes)
conditional
 
      if (result.getType() == BOOL) {
         if (result.getBooleanValue() == true)
            combo(ifTrue);   //<-- ANTLR parses (executes) "then" block
         else if (ifFalse != null) //optional ELSE block
            combo(ifFalse);  //<-- ANTLR parses (executes) "else" block
      }
      else
       throw new RecognitionException("Error: TreeParser.statement:
malformed IF: condition MUST evaluate as BOOLEAN");
     }
    . )
     |
 
  ...
 
) ;
 
I have similar rules for the other conditional statements.  If I do say
so myself, it works really well!  The ANTLR experts out there may have a
slicker way to do it, and I am open to suggestions.  I assume I would
need to semantic predicates somehow.  However, getting into the looping
structures I wasn't sure how to handle those, not to mention my
try-catch-finally rule.  Not sure if that helped or not.
 
Enjoy!

>>> poornima.prakash at cgi.com 4/22/2004 1:16:48 AM >>>

We have a classic 'if-then-else' rule in the grammar file. The 
problem we are facing is with the ANTLR versions 2.7.2 and 2.7.4rc1.

The 'rule' in the grammar file is defined as follows :

  rule options { defaultErrorHandler = true;} :
    ifPart thenPart 
    (options {warnWhenFollowAmbig = false;} :
        elsePart
        )?;
        
  ifPart: "if"^ LPARENTHESIS! conditional_expression RPARENTHESIS!;
    
  thenPart  : "then"^ stmt_blk;
    
  elsePart  :"else"^ stmt_blk;

Since the 'else' part is optional, when we give an input rule with 
only the 'if-then' and without the 'else', AST is not generated 
correctly. It stops at the root node!

However, if we manipulate the generated C# code, AST is correctly 
generated. We have to  move the line "rule_AST = currentAST.root;" in 
the generated sources such that it is traversed even when only 'if-
then' input rule is given. 

To be more precise, the line "rule_AST = currentAST.root;"  at the 
end of the 'try' block in the below (automatically generated parser) 
code has to be moved into the 'default' case of switch-case for the 
correct AST to get generated.

public void rule() //throws RecognitionException, TokenStreamException
{
        
        returnAST = null;
        ASTPair currentAST = new ASTPair();
        AST rule_AST = null;
        
        try {      // for error handling
            ifPart();
            astFactory.addASTChild(currentAST, returnAST);
            thenPart();
            astFactory.addASTChild(currentAST, returnAST);
            {
                switch ( LA(1) )
                {
                case LITERAL_else:
                {
                    elsePart();
                    astFactory.addASTChild
(currentAST, returnAST);
                    break;
                }
                case LITERAL_if:
                ....
                case IDENTIFIER:
                {
                    break;
                }
                default:
                {
                    throw new NoViableAltException
(LT(1), getFilename());
                }
                }
            }
            rule_AST = currentAST.root;
        }
        catch (RecognitionException ex)
        {...
        }
        returnAST = rule_AST;
    }


Please advice the required grammar change such that the AST gets 
generated properly without moving around the generated code.

Looking forward to your reply.

regards,
Poornima and Raghu.
    






Yahoo! Groups Links







________________________________

Yahoo! Groups Links


*	To visit your group on the web, go to:
	http://groups.yahoo.com/group/antlr-interest/
	  
*	To unsubscribe from this group, send an email to:
	antlr-interest-unsubscribe at yahoogroups.com
<mailto:antlr-interest-unsubscribe at yahoogroups.com?subject=Unsubscribe> 	  
*	Your use of Yahoo! Groups is subject to the Yahoo! Terms of
Service <http://docs.yahoo.com/info/terms/> . 




****************************************************************************

This transmission is intended for the named recipient only. It may contain private and confidential information. If this has come to you in error you must not act on anything disclosed in it, nor must you copy it, modify it, disseminate it in any way, or show it to anyone. Please e-mail the sender to inform us of the transmission error or telephone ECA International immediately and delete the e-mail from your information system.

Telephone numbers for ECA International offices are: Sydney +61 (0)2 9911 7799, Hong Kong + 852 2121 2388, London +44 (0)20 7351 5000 and New York +1 212 582 2333.

****************************************************************************

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/antlr-interest/attachments/20040423/8ceb71c5/attachment.html


More information about the antlr-interest mailing list