我正在尝试在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();}
;
谢谢,
答案 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();}
;
谢谢, 戈库尔。