[antlr-interest] C# Parser : problem with identifying a class declaration

Gavin Lambert antlr at mirality.co.nz
Mon Jan 14 03:59:53 PST 2008


At 00:36 15/01/2008, Aravinda Dassanayake wrote:
>The main issue is that the parser doesnt identify a class 
>declaration properly. It is trying to match it to a delegate 
>declaration no matter what I do. The rules in conflict are as 
>follows.
>
>
>type_declaration
>     :
>     class_declaration
>     |struct_declaration
>     |interface_declaration
>     |enum_declaration
>     |delegate_declaration
>     ;
>
>class_declaration
>     :
>     attributes? class_modifiers? 'class' IDENTIFIER class_base? 
> class_body ';'?
>     ;
>
>delegate_declaration
>     :
>     attributes? delegate_modifiers? 'delegate' return_type 
> IDENTIFIER '(' formal_parameter_list? ')' ';'
>     ;

ANTLR's default lookahead disambiguation can't see past loop 
constructs at the moment.  If you need it to, you'll need to tell 
it that it needs to check additional lookahead by adding syntactic 
predicates.  Also, you can probably factor the attributes out:

type_declaration
     :  attributes?
        (   (class_modifiers? 'class') => class_declaration
        |   (struct_modifiers? 'struct') => struct_declaration
        |   (interface_modifiers? 'interface') => 
interface_declaration
        |   (enum_modifiers? 'enum') => enum_declaration
        |   (delegate_modifiers? 'delegate') => 
delegate_declaration
        )
     ;

>class_modifiers
>     :
>     (class_modifier) (class_modifier)*
>     ;

That's a BNF-ism.  You should use this instead (generated code is 
simpler this way):

class_modifiers: class_modifier+;

>class_modifier
>     :
>     'new'
>     |'public'
>     |'protected'
>     |'internal'
>     |'private'
>     |'abstract'
>     |'sealed'
>     ;
[...]
>delegate_modifier
>     :
>     'new'
>     |'public'
>     |'protected'
>     |'internal'
>     |'private'
>     ;

Also, check the generated code for these; make sure it's not 
accidentally generating two separate tokens for e.g. 'new'.  If it 
is, for some reason, then you'll need to use named lexer tokens 
instead of string literals.



More information about the antlr-interest mailing list