[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