ANTLR规则调试错误

时间:2010-03-09 22:08:32

标签: antlr

我正在尝试在AntLRWorks中测试“whenDescriptor”规则遵循语法。我一开始调试就会一直跟踪异常。用于测试的输入文本是“当订单时:OrderBll然后”

[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

我能够成功测试“packageDescriptor”“declareDescriptor”。有谁知道错误消息的解决方案?我尝试了各种输入字符串组合,但规则调试失败。

这是我的语法。

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();}
    ;

谢谢,

2 个答案:

答案 0 :(得分:0)

这是一个奇怪的错误,但是当我调试并指定一个特定的规则来启动调试时,该规则就位于生成的“__Test__.java”文件中。然后,如果我更改调试器的启动规则并重新生成,则新的启动规则将在该文件中。我猜你上次使用不同的启动规则生成调试,而其他规则仍在文件中。

如果没有指定任何操作,您可以在选项中注释掉语言并在ANTLRWorks中快速调试,而无需完成所有C#代码的编译。

更好的选择是创建一个将一直调用的主规则,您正在测试的其他规则应该在主规则中,例如:

prog : packageDescriptor | declareDescriptor | whenDescriptor;

然后调用调试会话的主规则并生成具有该主规则的文件。当您添加要调试的更多规则时,请添加到此主规则中。

所以我猜没有主要规则的解决方案是1)在ANTLRWorks中单击调试选项并选择您正在测试的规则,此时可以停止调试。 2)在ANTLRWorks中,调试器停止,生成代码(此时你应该能够检查java文件,并确保它包含正确的规则.3)调试你已经存在的(编译C#代码,执行,和在ANTLRWorks中调试)

哦,您可能想要了解规则whenDescriptor如何通过规则variableDef间接调用rule qualifiedName,variableDef中的两个选项都可以匹配“Identifier”:'Identifier'。根据您测试的内容,qualifiedName规则对于规则packageDescriptor和declareDescriptor是正确的。当前的语法应该按规则使用规则variableDef,但我建议删除第一个选项,不要从ANTLR获得有关选项2被禁用的特定输入的任何问题或抱怨。

答案 1 :(得分:0)

这个语法有效。建议不要在语法级别使用回溯和memoize。必要时在规则级别使用它。

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();}
    ;

谢谢, 戈库尔。