最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】antlr解析出错:MismatchedSetException(0!=null)

ANTLR crifan 2262浏览 0评论

【问题】

在antlrworks中,antlr v3的语法,用如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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') {$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';
 
DECIMAL_VALUE   :   DIGIT+;
 
HEX_DIGIT : ('a'..'f'|'A'..'F' | DIGIT) ;
 
HEX_VALUE
    :   '0x' HEX_DIGIT+;
 
BLANKS  :   (' '|'\t')+;
//BLANKS    :   (' '|'\t')+ {skip();};
//BLANKS    :   ' '+ {$channel=HIDDEN;};
 
 
 
//fragment
ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;
 
 
//ID_START  :   'a'..'z'|'A'..'Z'|'_';
//WHOLE_ID  :   (ID_START) (ID_START | DIGIT)*;
 
//ID_MIDDLE_END :   ID_START | DIGIT;
//ID_MIDDLE_END :   HEX_DIGIT | '_';
//singleInclude :   '#include' BLANKS '"' ID_START ID_MIDDLE_END* '.h' '"';
//singleInclude :   '#include' BLANKS '"' ID_START (ID_START | DIGIT)* '.h' '"';
//singleInclude :   '#include' BLANKS '"' ID_START (ID_START | DIGIT)+ '.h' '"';
//singleInclude :   '#include' BLANKS '"' ID_START '.h' '"';
//singleInclude :   '#include' BLANKS '"' WHOLE_ID '.h' '"';
singleInclude   :   '#include' BLANKS '"' ID '.h' '"';
 
 
//include       :   singleInclude WS*   -> singleInclude;
include     :   singleInclude WS*;
 
//startParse    :   include* identification+;
//startParse    :   include+ identification+;
//startParse    :   identification+;
//startParse    :   manufacture deviceType deviceRevison ddRevision;
startParse  :   include+ manufacture deviceType deviceRevison ddRevision;
//manufacture   :   'MANUFACTURER'^ BLANKS (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;
//manufacture   :   'MANUFACTURER'^     (BLANK+! (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;
//manufacture   :   'MANUFACTURER'^ BLANKS (DECIMAL_VALUE | HEX_VALUE) ','? WS*;
manufacture :   'MANUFACTURER'^     BLANKS (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;
deviceType  :   'DEVICE_TYPE'^      BLANKS (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;
deviceRevison   :   'DEVICE_REVISION'^  BLANKS (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;
//deviceRevison :   'DEVICE_REVISION'^  BLANKS (DIGIT+ | HEX_VALUE) (','?)! WS*;
ddRevision  :   'DD_REVISION'^      BLANKS (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;

去解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
**********************************************************************
** 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

出错:

parse value error MismatchedSetException(0!=null)

其中错的是,用:

1
deviceRevison   :   'DEVICE_REVISION'^  BLANKS (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;

解析对应的

1
DEVICE_REVISION   5,

中的5,竟然无法匹配。

 

【解决过程】

1.后来试了试,改为:

1
deviceRevison   :   'DEVICE_REVISION'^  BLANKS (DIGIT+ | HEX_VALUE) (','?)! WS*;

是可以工作的。

2.后来是,把对应的fragment加上:

1
2
3
fragment
DIGIT
    :   '0'..'9';

就可以了:

use decimal value to parse values ok

 

【总结】

此处,如果使用单独的定义:

1
2
3
4
5
6
DIGIT
    :   '0'..'9';
 
DECIMAL_VALUE   :   DIGIT+;
 
deviceRevison   :   'DEVICE_REVISION'^  BLANKS (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;

是无法正常匹配:

1
DEVICE_REVISION   5,

中的数字5的。

但是添加了fragment后,变为:

1
2
3
4
5
6
7
fragment
DIGIT
    :   '0'..'9';
 
DECIMAL_VALUE   :   DIGIT+;
 
deviceRevison   :   'DEVICE_REVISION'^  BLANKS (DECIMAL_VALUE | HEX_VALUE) (','?)! WS*;

就可以了。

根本原因在于:

加了fragment后,就类似于DIGIT,就类似于inline了,就会自动被替换为:

1
deviceRevison   :   'DEVICE_REVISION'^  BLANKS (DIGIT+ | HEX_VALUE) (','?)! WS*;

了,就可以解析了。

 

但是目前,不是十分清楚的是:

对于一个简单的token的定义,何时,才需要加上那个fragment,何时不需要。

有待后续有机会弄清楚。

转载请注明:在路上 » 【已解决】antlr解析出错:MismatchedSetException(0!=null)

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.172 seconds, using 22.20MB memory