[antlr-interest] Bug with nested syntactic predicates? Reduced C#2.0 test grammar.

Robin Davies rerdavies at rogers.com
Wed Jun 13 06:03:27 PDT 2007


The following grammar is a reduced test case to simulate resolution of the 
generic/expression ambiguity in C# 2.0 via syntactic predicates. I can't get 
it to work. I'm pretty sure it's a bug; but I'm still at the "a little 
knowledge is a dangerous thing" stage. It is  possible that I'm still 
missing an essential concept wrt/ syntactic predicates. I've been over 
chapters 12-14 backwards and forwards, and I firmly believe that the grammar 
is correct.

The conflict in C# is of the form
        methodCall(a<b,c>.StaticMethod())   // is a<b a boolean expression 
or the start of a generic type name)?
        methodCall(a<b,c>d)                         // is a<b a boolean 
expression or the start of a generic type name)?

The intended resolution is: if it's a generic name (e.g. a<b,c>) then it's a 
generic name. The second case should be treated as an error. (The actual 
rule in the standard is a bit more unpleasant, requiring an ad-hoc pre-scan 
of incoming tokens as a semantic predicate to locate a probably-matching '>' 
token).

Test input is:
    List<int,int>

In ANTLRWorks, this succesfully and correctly parses as an expr3, and a 
generic_type_expr, but fails to parse as an expr. The question is: why isn't 
the first option of the expr production taken for the given test input, 
since it is a valid generic_type_expr?

expr
    :    (generic_type_expr)=>   // e.g. generic   List<int>
         expr3    // bypass LT/GT expressions
    |     (expr3 LT  expr3)=> (expr3 LT expr3)  // (non-assoc, for clarity)
    |     (expr3 GT expr3)=> (expr3 GT expr3)
    |     (expr3)=> expr3
    ;

I've seen various behaviors depending on the state of my test grammar. In 
the supplied grammar -- if AntlrWorks is displaying syntactic predicate 
evaluation properly -- the (generic_type_expr) syntactic predicate doesn't 
seem to get run at all. But I've also seen cases where (generic_type_expr)=> 
succeeds, and expr3 fails for this input. And cases where an apparent 
pre-scan for generic_type_expr accepts "List<int,int", and then fails, 
despite the fact that the next token is the expected ">" token.

If I remove either of the LT or GT rules, the parse succeeds (probably 
through option 4). But shouldn't the semantic predicate in the first option 
prevent options 2 and 3 from running in the intact grammar?

The full grammar is attached. I've done my best to simplify it as much as 
possible.

As an aside,  "!=>" would be a very useful construct in ANTLR, allowing the 
following rule to cut off the '<' binary operator, in left-associative 
comparison expressions.

comparison_expr:   expr_next
                                    (
                                        ( (generic_arg_list)!=> '<' 
expr_next)
                                    |   ('>' expr_next)
                                    )*
                            ;

The nightmarish input case for this:   a < b < G<int,int>.StaticBoolMember() 
(a valid, but not very useful C# expression, I think; == != are 
non-associative (good thing), but <, > are right-assoc, for some bizarre 
reason).

Any help appreciated.



-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.g
Type: application/octet-stream
Size: 839 bytes
Desc: not available
Url : http://www.antlr.org/pipermail/antlr-interest/attachments/20070613/052357ee/attachment.obj 


More information about the antlr-interest mailing list