【问题】
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