【问题】
折腾:
【已解决】antlr调试解析出错:UnwantedTokenException(found=xxx)
的过程中,如果按照之前的逻辑:会自动匹配空格然后hidden掉
那么,之前自己手动添加的空格,都可以去掉了,比如针对
manufacture : 'MANUFACTURER'^ BLANKS_TABS (direct_value | define_value) (','?)! WS*;可以改为:
//manufacture : 'MANUFACTURER'^ BLANKS_TABS (direct_value | define_value) (','?)! WS*;
manufacture : 'MANUFACTURER'^ (direct_value | define_value) (','?)!;看看效果,
结果就会出现:
NoViableAltException(0@[null])
【解决过程】
1.怀疑是,WS只能自动识别并忽略掉单个的空格,所以,对于多个的空格,需要手动自己去匹配并忽略掉。
所以,去把WS改为自动识别多个,并忽略:
//WS : ( ' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
WS : ( ' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};试试,结果,后来的,原先可用的:
BLANKS_TABS : (' '|'\t')+;显示,和之前的WS冲突了,重复定义了,
所以,去掉BLANKS_TABS,以及多处出现的BLANKS_TABS。
2.然后,再去调试,发现,的确是可以了。
【总结】
1.此处的错误:
NoViableAltException
是由于,对于之前用WS,匹配并忽略掉了单个的空格,而后续的再去用BLANKS_TABS去匹配空格,实际上已经没了空格了,所以,无法继续匹配,才报错的。
解决办法就是,使用如下要解释的内容,使用WS,匹配并自动忽略掉所有的空格,会更加高效。
2.对于使用:
WS : ( ' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};可以达到的效果:
后续的,所有的token的定义中,凡是出现的,一个或多个的空格,Tab,回车,换行等内容,
都可以自动地,匹配到,并且由于加了hidden,就会自动忽略掉。
所以,后续的token中,就无需再写对应的WS,去匹配对应的空格了。
如此,就简化了整个语法,即无需每次单独去写对应的WS了。
目前,去掉了WS的,已经简化的语法如下:
grammar DDParserDemo;
options {
output = AST;
ASTLabelType = CommonTree; // type of $stat.tree ref etc...
}
/*
//NEWLINE : '\r'? '\n' ;
//NEWLINE : '\r' '\n' ;
fragment
NEWLINE : '\r'? '\n' ;
*/
/*
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();};
//fragment WS : ( ' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
//WS : ( ' ' | '\t' | '\r' | '\n');
//WS : ( ' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
WS : ( ' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
/*
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*;
DECIMAL_VALUE : DIGIT+;
//DECIMAL_VALUE : '1'..'9' DIGIT*;
//HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
//HEX_DIGIT : (DIGIT|'a'..'f'|'A'..'F') ;
HEX_DIGIT : ('a'..'f'|'A'..'F' | DIGIT) ;
HEX_VALUE
: '0x' HEX_DIGIT+;
/*
fragment
HEADER_FILENAME
: ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'_')*;
*/
//BLANK : (' '|'\t')+ {$channel=HIDDEN;};
//BLANK : (' '|'\t')+ {skip();};
//BLANKS_TABS : (' '|'\t')+;
//fragment
//BLANKS_TABS : (' '|'\t')+;
//fragment
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
HEADER_FILENAME : ID '.h';
//singleInclude : '#include' BLANKS_TABS '"' ID '.h' '"';
//singleInclude : '#include' BLANKS_TABS '"' HEADER_FILENAME '"';
//singleInclude : '#include' WS '"' HEADER_FILENAME '"';
singleInclude : '#include' '"' HEADER_FILENAME '"';
//include : singleInclude WS*;
include : singleInclude;
define_value : ID;
direct_value : (DECIMAL_VALUE | HEX_VALUE);
//manufacture : 'MANUFACTURER'^ BLANKS_TABS (direct_value | define_value) (','?)! WS*;
manufacture : 'MANUFACTURER'^ (direct_value | define_value) (','?)!;
//deviceType : 'DEVICE_TYPE'^ (DECIMAL_VALUE | HEX_VALUE) (','?)!;
deviceType : 'DEVICE_TYPE'^ (direct_value | define_value) (','?)!;
//deviceRevison : 'DEVICE_REVISION'^ (DECIMAL_VALUE | HEX_VALUE) (','?)!;
deviceRevison : 'DEVICE_REVISION'^ (direct_value | define_value) (','?)!;
//ddRevision : 'DD_REVISION'^ (DECIMAL_VALUE | HEX_VALUE) (','?)!;
ddRevision : 'DD_REVISION'^ (direct_value | define_value) (','?)!;
label_value : '['? ID ']';
//label : WS* ('REDEFINE' WS+)? 'LABEL' WS+ label_value WS* ';' WS*;
label : ('REDEFINE')? 'LABEL' label_value ';';
help_value : '['? ID ']';
//help : WS* ('REDEFINE' WS+)? 'HELP' WS+ help_value WS* ';' WS*;
help : ('REDEFINE')? 'HELP' help_value ';';
//variable: 'REDEFINE' WS+ ID WS* '{' WS* label help class? type? constant?_unit? handling? '}';
//variable: 'REDEFINE' WS+ ID WS* '{' WS* label help '}';
variable: 'REDEFINE' ID '{' label help '}';
//everything : 'EVERYTHING' WS* ';';
everything : 'EVERYTHING' ';';
//redefinitions : 'REDEFINITIONS' WS* '{' WS* (variable | record)+ '}';
//redefinitions : 'REDEFINITIONS' WS* '{' WS* (variable)+ '}';
redefinitions : 'REDEFINITIONS' '{' (variable)+ '}';
//single_import : 'IMPORT' BLANKS_TABS manufacture deviceType deviceRevison ddRevision WS* '{' WS* everything WS* redefinitions WS* '}' ;
//single_import : 'IMPORT' manufacture deviceType deviceRevison ddRevision WS* '{' WS* everything WS* redefinitions WS* '}' ;
single_import : 'IMPORT' manufacture deviceType deviceRevison ddRevision '{' everything redefinitions '}' ;
//single_import : 'IMPORT' (' ' | '\t')+ manufacture deviceType deviceRevison ddRevision WS* '{' WS* everything WS* redefinitions WS* '}' ;
//single_import : 'IMPORT' WS+ manufacture deviceType deviceRevison ddRevision WS* '{' WS* everything WS* redefinitions WS* '}' ;
startParse : include+ manufacture deviceType deviceRevison ddRevision single_import+;是可以正常匹配如下测试内的:
/* ===========================================================================
FILE_NAME fbk_hm.ddl
FUNCTIONAL_MODULE_DESCRIPTION
This file contains the device description of the FBK HART Master
application.
=========================================================================== */
/*
**********************************************************************
** Includes
**********************************************************************
*/
#include "std_defs.h"
#include "com_tbls.h"
#include "rev_defs.h"
#include "fbk_hm.h"
#include "fdiag_FBK2_Start.h"
#include "blk_err.h"
/*
**********************************************************************
********** DEVICE SECTION ********************************************
**********************************************************************
*/
MANUFACTURER 0x1E6D11,
DEVICE_TYPE 0x00FF,
DEVICE_REVISION 5,
DD_REVISION 1
/*
***********************************************************************
Import the Standard Descriptions for all Standard Parameters
***********************************************************************
*/
IMPORT MANUFACTURER __FF,
DEVICE_TYPE __STD_PARM,
DEVICE_REVISION SFT_STD_PARM_dev_rev,
DD_REVISION SFT_STD_PARM_dd_rev
{
EVERYTHING ;
REDEFINITIONS
{效果为:
效果真心不错。