【问题】
antlr v3,在antlrworks中,用如下语法:
grammar DDParserDemo; options { output = AST; ASTLabelType = CommonTree; // type of $stat.tree ref etc... } //NEWLINE : '\r'? '\n' ; //NEWLINE : '\r' '\n' ; fragment NEWLINE : '\r'? '\n' ; fragment ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* ; fragment FLOAT : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? | '.' ('0'..'9')+ EXPONENT? | ('0'..'9')+ EXPONENT ; COMMENT : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} | '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} ; fragment WS : ( ' ' | '\t' | '\r' | '\n' ) {skip();} ; STRING : '"' ( ESC_SEQ | ~('\\'|'"') )* '"' ; CHAR: '\'' ( ESC_SEQ | ~('\''|'\\') ) '\'' ; fragment EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; ESC_SEQ : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | UNICODE_ESC | OCTAL_ESC ; fragment OCTAL_ESC : '\\' ('0'..'3') ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ; fragment UNICODE_ESC : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT ; fragment DIGIT : '0'..'9'; //FAKE_TOKEN : '1' '2' '3'; /* DECIMAL_VALUE : '1'..'9' DIGIT*; */ DECIMAL_VALUE : DIGIT*; HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; HEX_VALUE : '0x' HEX_DIGIT+; /* BLANKSPACE_TAB // : (' ' | '\t'){skip();}; : (' ' | '\t') {$channel=HIDDEN;}; */ //fragment BLANK : (' '|'\t')+ {skip();}; //BLANK : (' '|'\t') {skip();}; BLANK : (' '|'\t') {skip();}; fragment HEADER_FILENAME : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'_')*; /* //singleInclude : '#include' ' '+ '"' ID '.h"' ; //singleInclude : '#include' ' '+ '"' ID+ '.h"' ; //singleInclude : '#include' ' '+ '"' HEADER_FILENAME '.h"'; //singleInclude : '#include' ' ' '"' HEADER_FILENAME '.h"'; //singleInclude : '#include "' HEADER_FILENAME '.h"'; //fragment singleInclude : '#include' (' ')+ '"' ID '.h"'; //singleInclude : '#include' (' '|'\t')+ '""' ID '.h"'; //singleInclude : '#include' (' '|'\t')+ '"std_defs.h"'; singleInclude : '#include' (' '|'\t')+ ID '.h'; include : singleInclude WS* -> singleInclude; */ //startParse : include* identification+; //startParse : include+ identification+; //startParse : identification+; startParse : manufacture deviceType deviceRevison ddRevision; manufacture : 'MANUFACTURER'^ BLANK+ (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*; deviceType : 'DEVICE_TYPE'^ BLANK+ (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*; deviceRevison : 'DEVICE_REVISION'^ BLANK+ (DECIMAL_VALUE | HEX_VALUE)(','?)! WS*; ddRevision : 'DD_REVISION'^ BLANK+ (DECIMAL_VALUE | HEX_VALUE)(','?)! WS*; //identification : definiton WS* (','?)! WS* -> definiton; //definiton : (ID)^ ('\t'!|' '!)+ (DECIMAL_VALUE | HEX_VALUE) //definiton : (ID)^ BLANKSPACE_TAB+ (DECIMAL_VALUE | HEX_VALUE) //definiton : ID ('\t'!|' '!)+ (DECIMAL_VALUE | HEX_VALUE);
去调试解析:
MANUFACTURER 0x1E6D11, DEVICE_TYPE 0x00FF, DEVICE_REVISION 5, DD_REVISION 1
结果出错:
【解决过程】
1.参考:
How to resolve this parsing ambiguitiy in Antlr3
看了其解释,只是明白了一点,那就是,
在语法中,的确存在,解析器,希望匹配的东西,但是实际上所匹配的内容中,缺少了后面的部分,所以导致解析器报错,说是EarlyExitException,即过早退出,(希望还有更多后续匹配的内容)
2.所以,就去自己的语法中,看看是否有,类似于上面这样的歧义的东西。
试试去,把skip去掉,即变为:
//BLANK : (' '|'\t') {skip();}; BLANK : (' '|'\t');
看看效果。结果果然可以正常解析对应的值了:
接下来,还是需要,好好搞懂,为何加上那个skip,而出现EarlyExitException。
3.改为加上感叹号,表示不捕获:
//manufacture : 'MANUFACTURER'^ BLANK+ (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*; manufacture : 'MANUFACTURER'^ (BLANK+)! (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;
结果还是和上面一样,还是可以捕获对应的那6个空格。
4.参考:
http://www.antlr3.org/api/Java/index-all.html
中的:
All tokens go to the parser (unless skip() is called in that rule) on a particular "channel". |
以及,进一步的,参考:
得知,加上skip()后,对应的,antlr就不为此内容,创建对应的token了。
所以,倒是可以去试试,把对应的内容,去改为hidden,而不是skip:
//BLANK : (' '|'\t') {skip();}; //BLANK : (' '|'\t'); BLANK : (' '|'\t') {$channel=HIDDEN;};
结果却又是变成EarlyExitException了:
觉得还是不能理解。
5.期间,又出现别的问题,详见:
【基本解决】antlr v3,用包含{$channel=HIDDEN;}语法,结果解析出错:MissingTokenException
【总结】
虽然,对于org.antlr.runtime.EarlyExitException和之后的MissingTokenException,都可以避免了。
但是还是无法实现所要的,可以skip或hidden空格的效果。
更多总结详见上面的:
【基本解决】antlr v3,用包含{$channel=HIDDEN;}语法,结果解析出错:MissingTokenException
转载请注明:在路上 » 【基本解决】antlr v3中包含{skip();}的语法,调试解析时出错:org.antlr.runtime.EarlyExitException