ANTLR规则调试错误
我正在尝试在 AntLRWorks 中测试以下语法中的 "whenDescriptor" 规则。当我开始调试时,我不断收到以下异常。用于测试的输入文本是“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
我能够成功测试“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();}
;
谢谢,
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,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这个语法有效。建议不要在语法层面使用回溯和记忆。必要时在规则级别使用它。
谢谢,
戈库尔。
This grammar works. Its advisable not to use backtrack and memoize at the grammar level. use it when necessary at the rule level.
Thanks,
Gokul.
这是一个奇怪的错误,但是当我调试并指定特定规则来开始调试时,该规则位于生成的“__Test__.java”文件中。然后,如果我更改调试器的启动规则并重新生成,则新的启动规则位于该文件中。我猜您最后生成了一个不同的调试起始规则,并且其他规则仍在文件中。
在不指定任何操作的情况下,您可以注释掉选项中的语言,并在 ANTLRWorks 中快速调试,而无需完成 C# 代码的所有编译。
更好的选择是创建一个始终被调用的主规则,您正在测试的其他规则应该位于主规则中,例如:
然后调用调试会话的主规则并生成文件与该主要规则。当您添加更多要调试的规则时,请添加到此主规则中。
所以我猜没有主要规则的解决方案是1)在ANTLRWorks中单击调试选项并选择您正在测试的规则,此时您可以停止调试。 2) 在 ANTLRWorks 中,调试器停止,生成代码(此时您应该能够检查 java 文件并确保它包含正确的规则。3)像您已经那样进行调试(编译 C# 代码,执行,然后 。
哦,你可能想研究规则whenDescriptor如何通过规则variableDef间接调用规则qualifiedName,variableDef中的两个选项都可以匹配“Identifier ':' Identifier” 根据您的测试,qualifiedName 规则对于规则 packageDescriptor 和 declareDescriptor 是正确的。当前语法应该按原样使用规则variableDef,但我建议删除第一个选项,并且不要从 ANTLR 收到任何有关针对特定输入禁用选项 2 的问题或投诉。
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:
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.