[antlr-interest] Weird problem with semantic predicates. Incorrect warning message
John B. Brodie
jbb at acm.org
Wed Apr 29 14:48:50 PDT 2009
On Tuesday 28 April 2009 05:08:08 pm Gabriel Petrovay wrote:
> 1. warning(200): exit_test.g:9:3: Decision can match input such as
> "IF" using multiple alternatives: 1, 3
>
> The IF does not MATCH the first alternative, therefore, the warning is
> NOT correct.
I assume by now you have taken Jim's suggestion to view your grammar in
antlrworks and see the ambiguity on IF between alts 1 and 3 of the
p_ExprSingle rule.
> Why is the warning disappearing when I delete the second alternative?
> If the warning were correct, it should still be displayed.
Usually antlr can resolve this sort of ambiguity by increasing its lookahead.
In this case a lookahead of k=2 is needed to resolve the ambiguity (by seeing
a LPAREN after an IF we know we have a p_IfExpr otherwise we have a
p_StepExpr)
For some reason the predicate is preventing antlr from choosing k=2. perhaps
this is the normal way predicates are handled, i do not know, i try really
really hard to avoid any kind of predicates.
If you delete the alternative containing the predicate, antlr will now choose
k=2 for this decision and the ambiguity thereby disappears.
Also if you specify k=2; in an options{} block at the top of the file, the
warning also goes away.
> WITH PROBLEM
> p_ExprSingle
> ? ?: p_IfExpr
> ? ?| {false}?=> p_ExitExpr
> ? ?| p_StepExpr
> ? ?;
>
> WITHOUT PROBLEM
> p_ExprSingle
> ? ?: p_IfExpr
> // ? ?| {false}?=> p_ExitExpr
> ? ?| p_StepExpr
> ? ?;
>
>
>
> 2. I want to parse the following texts where p_ExprSingle is the start
> rule: --------
> if // rule 3
> --------
> if(blah) ?// rule 1 -> rule 3 for 'blah'
> --------
> if(if) // rule 1 -> rule 3 for the 'if' in parantheses
> --------
>
> So far the rule p_ExprSingle with only 2 alternatives does the job.
> What about the following texts:
>
> --------
> if(exit with a)
> --------
> if(exit with if)
> --------
> if(exit with exit with exit)
> --------
>
> The p_ExitExpr is only available once a flag is set (therefore I use
> the semantic predicate). If you delete the semantic predicate you will
> see some correct warnings. As long as you have the predicate, the
> warning is not correct anymore.
>
> The problem is for sure the grammar ambiguity that John pointed out in
> a previous e-mail.
>
> I hope these examples together with the shortened-revised parser
> grammar below makes a little more sense to you. I cannot make it
> simpler.
delete the ambiguous p_ReplaceExpr rule.
delete the predicate but keep the p_ExitExpr alternative in p_ExprSingle.
and now your grammar does what you want.
(i might have made some other changes, can't remember)
see attached complete example.
> PARSER GRAMMAR
> --------------------------
>
> p_ExprSingle
> ? ?: p_IfExpr
> ? ?| {false}?=> p_ExitExpr
> ? ?| p_StepExpr
> ? ?;
>
> p_IfExpr
> ? ?: IF LPAREN p_ExprSingle RPAREN
> ? ?;
>
> p_StepExpr
> ? ?: L_NCName | IF | EXIT
> ? ?| LBRACKET p_ExprSingle RBRACKET
> ? ?;
>
> p_ReplaceExpr
> ? ?: REPLACE p_ExprSingle WITH p_ExprSingle
> ? ?;
>
> p_ExitExpr
> ? ?: EXIT WITH p_ExprSingle
> ? ?;
>
>
>
> Regads,
> Gabriel
>
> Original message
>
> > Hi,
> >
> > Thanks a lot John for make it it clear. Although I see the problem and
> > I think that generates everyting, there are at least a couple of
> > problems with ANTLR:
> >
> > 1. The Warning is incorrect: Decision can match input such as "IF"
> > using multiple alternatives: 1, 4. ?As a result, alternative(s) 4 were
> > disabled for that input.
> >
> > This is non-sense to me since decision 1 in p_ExprSingle does not
> > match "IF". Only decision 4 can match it (p_StepExpr)
>
> No, the warning is perfectly correct. Use ANTLRWorks, do the Check
> Gramar, select the rule in red, select the syntax tab, turn on both
> paths, your problem will be obvious.
>
> > 2. What do those two alternatives (1 and 4) have to do with the
> > alternative 2 (p_ExitExpr) and a rule that is NOT used anywhere
> > (p_ReplaceExpr) ???
>
> Because in the look ahead set, you calculate all possible tokens that
> the grammar says can come next, not just the rule that you have
> provided. Basically your grammar does not make a lot of sense and ANTLR
> is trying to tell you this. You might be better starting with the
> examples and building up from there; trying to run before you can walk
> gets you in to trouble with grammars ;-)
>
> Jim
>
>
> --
> MSc Gabriel Petrovay
> MCSA, MCDBA, MCAD
> Mobile: +41(0)787978034
-------------- next part --------------
grammar Test;
options {
output = AST;
ASTLabelType = CommonTree;
}
@members {
private static final String [] x = new String[]{
"if", "if(a)", "if(if)",
"if(exit with a)", "if(exit with if)", "if(exit with exit with exit)"
};
public static void main(String [] args) {
for( int i = 0; i < x.length; ++i ) {
try {
System.out.println("about to parse:`"+x[i]+"`");
TestLexer lexer = new TestLexer(new ANTLRStringStream(x[i]));
CommonTokenStream tokens = new CommonTokenStream(lexer);
TestParser parser = new TestParser(tokens);
TestParser.start_return p_result = parser.start();
CommonTree ast = p_result.tree;
if( ast == null ) {
System.out.println("resultant tree: is NULL");
} else {
System.out.println("resultant tree: " + ast.toStringTree());
}
System.out.println();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
start : p_ExprSingle EOF!;
p_ExprSingle
: p_IfExpr
| p_ExitExpr
| p_StepExpr
;
p_IfExpr
: 'if' '(' p_ExprSingle ')'
;
p_StepExpr
: 'a' | 'if' | 'exit'
| '{' p_ExprSingle '}'
;
//p_ReplaceExpr
// : 'replace' p_ExprSingle 'with' p_ExprSingle
// ;
p_ExitExpr
: 'exit' 'with' p_ExprSingle
;
WS : ' '+ { $channel = HIDDEN; } ;
More information about the antlr-interest
mailing list