tags:

views:

59

answers:

2

I am trying to test "whenDescriptor" rule in following grammar in AntLRWorks. I keep getting following exception as soon as I start debugging. Input text for testing is "when order : OrderBll then"

[16:45:07] C:\Documents and Settings\RM\My Documents\My Tools\AntLRWorks\output\__Test__.java:14: cannot find symbol
[16:45:07] symbol  : method whenDescriptor()
[16:45:07] location: class RulesTranslatorParser
[16:45:07]             g.whenDescriptor();
[16:45:07]              ^
[16:45:07] 1 error

I am able to test "packageDescriptor" and "declareDescriptor" successfully. Does anyone knows resolution to the error message? I tried various combination of input string but rule debugging fails.

Here is my grammar.

grammar RulesTranslator;

options
{
    backtrack=true;
    memoize=true;
    language=CSharp2;
}

tokens {
    AND='and';
    OR='or';
    NOT='not';
    EXISTS='exists';
    EVAL='eval';
    FORALL='forall';
    CONTAINS='contains';
    IS='is';
    INSTANCEOF='instanceof';
    STRSIM='strsim';
    SOUNDSLIKE='soundslike';
    IN='in';
    NEW='new';
    WITH='with';
    ASSERT='assert';
    ISDEF='isdef';
}

packageDescriptor
    : 'package' qualifiedName
    ;

declareDescriptorList
    : (declareDescriptor)*
    ;

declareDescriptor
    : 'declare' qualifiedName (variableDef)+ 'end'
    ;

whenDescriptor
    : 'when' typeRef  'then'
    ;

typeRef
    :  (Identifier | variableDef)
    ;

qualifiedNameList
    : qualifiedName (',' qualifiedName)*
    ;

qualifiedName
    : Identifier ('.' Identifier)*
    ;

variableDef   
    : ( Identifier ':' Identifier | Identifier ':' qualifiedName )
    ;

// STATEMENTS / BLOCKS          
fieldseperator
    : (',' | ';')
    ;

logicalOperator
     : ('&&' | '||' | '~=')
    ;

// Lexar   
HexLiteral : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ;

DecimalLiteral : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ;

OctalLiteral : '0' ('0'..'7')+ IntegerTypeSuffix? ;

fragment
HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
IntegerTypeSuffix : ('l'|'L') ;

FloatingPointLiteral
    : ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?
    | '.' ('0'..'9')+ Exponent? FloatTypeSuffix?
    ;

fragment
Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
FloatTypeSuffix : ('f'|'F'|'d'|'D') ;

CharacterLiteral
    :   '\'' ( EscapeSequence | ~('\''|'\\') ) '\''
    ;

StringLiteral
    :  '"' ( EscapeSequence | ~('\\'|'"') )* '"'
    ;

fragment
EscapeSequence
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UnicodeEscape
    |   OctalEscape
    ;

fragment
OctalEscape
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UnicodeEscape
    :   '\\' 'u' HexDigit HexDigit HexDigit HexDigit
    ;

Identifier
        :   IdentifierStart (IdentifierStart|IdentifierPart)*
        ;

fragment
IdentifierStart
    :  '\u0024' |
       '\u0041'..'\u005a' |
       '\u005f' |
       '\u0061'..'\u007a' |
       '\u00c0'..'\u00d6' |
       '\u00d8'..'\u00f6' |
       '\u00f8'..'\u00ff' |
       '\u0100'..'\u1fff' |
       '\u3040'..'\u318f' |
       '\u3300'..'\u337f' |
       '\u3400'..'\u3d2d' |
       '\u4e00'..'\u9fff' |
       '\uf900'..'\ufaff'
    ;

fragment
IdentifierPart
    :  '\u0030'..'\u0039' |
       '\u0660'..'\u0669' |
       '\u06f0'..'\u06f9' |
       '\u0966'..'\u096f' |
       '\u09e6'..'\u09ef' |
       '\u0a66'..'\u0a6f' |
       '\u0ae6'..'\u0aef' |
       '\u0b66'..'\u0b6f' |
       '\u0be7'..'\u0bef' |
       '\u0c66'..'\u0c6f' |
       '\u0ce6'..'\u0cef' |
       '\u0d66'..'\u0d6f' |
       '\u0e50'..'\u0e59' |
       '\u0ed0'..'\u0ed9' |
       '\u1040'..'\u1049'
    |   '\uff10'..'\uff19'
   ;

WS  :  (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
    ;

COMMENT
    :   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

LINE_COMMENT
    : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    ;

NEWLINE    : ('\r')? '\n' {skip();}
    ;

Thanks,

A: 

This is a strange error, but when I debug and specify a specific rule to start with the debugging, that rule is place in the "_Test_.java" file generated. Then if I change the starting rule for the debugger and regenerate, the new starting rule is in that file. I am guessing you last generated with a different starting rule for debugging and that other rule is still in the file.

Without any actions specified, you can comment out the language in your options and quickly debug within ANTLRWorks without going through all the compilation of C# code.

And an even better option would be to create a main rule that will be called all the time, these other rules you are testing should be in the main rule, something like:

prog : packageDescriptor | declareDescriptor | whenDescriptor;

And then call the main rule for the debugging session and generate the file with that main rule. As you add more rules that you want to debug, add into this main rule.

So I guess the solution without the main rule is 1) in ANTLRWorks click the debug option and select your rule you are testing, you can stop the debugging at this point. 2) in ANTLRWorks with the debugger stopped, generate the code (at this point you should be able to check the java file and make sure it contains the correct rule. 3) Debug as you already were (compiling the C# code, executing, and debug within ANTLRWorks)

Oh, you might want to work on how rule whenDescriptor indirectly calls rule qualifiedName through rule variableDef, both options in variableDef can match "Identifier ':' Identifier". And based on what you tested, the qualifiedName rule is correct for rules packageDescriptor and declareDescriptor. The current grammer should work with the rule variableDef as is, but I would recommend removing the first option and not getting any problems or complaint from ANTLR about option 2 being disabled for a certain input.

WayneH
A: 

This grammar works. Its advisable not to use backtrack and memoize at the grammar level. use it when necessary at the rule level.

grammar RulesTranslator;

options
{
    k = 5;
    language=Java;
}

tokens {
    AND='and';
    OR='or';
    NOT='not';
    EXISTS='exists';
    EVAL='eval';
    FORALL='forall';
    CONTAINS='contains';
    IS='is';
    INSTANCEOF='instanceof';
    STRSIM='strsim';
    SOUNDSLIKE='soundslike';
    IN='in';
    NEW='new';
    WITH='with';
    ASSERT='assert';
    ISDEF='isdef';
}

packageDescriptor
    : 'package' qualifiedName
    ;

declareDescriptorList
    : (declareDescriptor)*
    ;

declareDescriptor
    : 'declare' qualifiedName (variableDef)+ 'end'
    ;

whenDescriptor
    : 'when' typeRef  'then'
    ;

typeRef
    :  (Identifier | variableDef)
    ;

qualifiedNameList
    : qualifiedName (',' qualifiedName)*
    ;

qualifiedName
    : Identifier ('.' Identifier)*
    ;

qualifiedName_no_Identifier
    :
            ('.' Identifier)+
    ;

variableDef   
    : Identifier ':' Identifier
        (
              /*Empty*/
              |  qualifiedName_no_Identifier
        )
    ;

// STATEMENTS / BLOCKS          
fieldseperator
    : (',' | ';')
    ;

logicalOperator
     : ('&&' | '||' | '~=')
    ;

// Lexar   
HexLiteral : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ;

DecimalLiteral : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ;

OctalLiteral : '0' ('0'..'7')+ IntegerTypeSuffix? ;

fragment
HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
IntegerTypeSuffix : ('l'|'L') ;

FloatingPointLiteral
    : ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?
    | '.' ('0'..'9')+ Exponent? FloatTypeSuffix?
    ;

fragment
Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
FloatTypeSuffix : ('f'|'F'|'d'|'D') ;

CharacterLiteral
    :   '\'' ( EscapeSequence | ~('\''|'\\') ) '\''
    ;

StringLiteral
    :  '"' ( EscapeSequence | ~('\\'|'"') )* '"'
    ;

fragment
EscapeSequence
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UnicodeEscape
    |   OctalEscape
    ;

fragment
OctalEscape
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UnicodeEscape
    :   '\\' 'u' HexDigit HexDigit HexDigit HexDigit
    ;

Identifier
        :   IdentifierStart (IdentifierStart|IdentifierPart)*
        ;

fragment
IdentifierStart
    :  '\u0024' |
       '\u0041'..'\u005a' |
       '\u005f' |
       '\u0061'..'\u007a' |
       '\u00c0'..'\u00d6' |
       '\u00d8'..'\u00f6' |
       '\u00f8'..'\u00ff' |
       '\u0100'..'\u1fff' |
       '\u3040'..'\u318f' |
       '\u3300'..'\u337f' |
       '\u3400'..'\u3d2d' |
       '\u4e00'..'\u9fff' |
       '\uf900'..'\ufaff'
    ;

fragment
IdentifierPart
    :  '\u0030'..'\u0039' |
       '\u0660'..'\u0669' |
       '\u06f0'..'\u06f9' |
       '\u0966'..'\u096f' |
       '\u09e6'..'\u09ef' |
       '\u0a66'..'\u0a6f' |
       '\u0ae6'..'\u0aef' |
       '\u0b66'..'\u0b6f' |
       '\u0be7'..'\u0bef' |
       '\u0c66'..'\u0c6f' |
       '\u0ce6'..'\u0cef' |
       '\u0d66'..'\u0d6f' |
       '\u0e50'..'\u0e59' |
       '\u0ed0'..'\u0ed9' |
       '\u1040'..'\u1049'
    |   '\uff10'..'\uff19'
   ;

WS  :  (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
    ;

COMMENT
    :   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

LINE_COMMENT
    : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    ;

NEWLINE    : ('\r')? '\n' {skip();}
    ;

Thanks, Gokul.

Gokul