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

【已解决】antlr代码执行出错:xxx.ddl line 16:13 no viable alternative at input ‘1’,Recognition exception NoViableAltException(0@[null])

ANTLR crifan 3406浏览 0评论

【问题】

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
grammar HartEddlParser;
 
options {
    output = AST;
    ASTLabelType = CommonTree; // type of $stat.tree ref etc...
}
 
COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;
 
WS  :   ( ' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
 
//fragment
ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
 
 
 
//ID_NON_FRAGMENT   :   ID;
 
fragment
DIGIT
    :   '0'..'9';
 
 
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
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;
 
//fragment
STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;
 
 
 
fragment
IMPORTED_VALUE  :   '[' ID ']'; /* normal ID with [] */
 
//fragment
DEFINE_IMPORTED_VALUE
        :   ID | IMPORTED_VALUE;
 
 
fragment   
DATA_ITEM_SPECIAL_MASKS
    : ID '<' HEX_VALUE '>' ','?;
fragment
DATA_ITEM_SPECIAL_QUALIFIER
    : ID '(' 'INFOR'|'INDEX'|'INFOR,INDEX' ')' ','?;
DATA_ITEM_SPECIAL
    :   DATA_ITEM_SPECIAL_MASKS | DATA_ITEM_SPECIAL_QUALIFIER;
 
 
 
UNSIGNED_CHAR_NUMBER
    :UNSIGNED_CHAR_CONDITION_ONE|UNSIGNED_CHAR_CONDITION_TWO|UNSIGNED_CHAR_CONDITION_THREE|UNSIGNED_CHAR_CONDITION_FOUR;
fragment  
UNSIGNED_CHAR_CONDITION_ONE
    :'0';
fragment   
UNSIGNED_CHAR_CONDITION_TWO
    :'1' (DIGIT | (DIGIT DIGIT))?;     
fragment
UNSIGNED_CHAR_CONDITION_THREE
    :'2' (('0'..'4' DIGIT?) | ('5' '0'..'5'?) | ('6'..'9'))?;              
fragment
UNSIGNED_CHAR_CONDITION_FOUR
    :'3'..'9' DIGIT?;
 
 
//fragment
//HEX_VALUE
//  :   '0x' HEX_DIGIT+;
HEX_VALUE
    :   TMP_HEX_VALUE;
fragment
TMP_HEX_VALUE
    :       '0x' HEX_DIGIT+;
 
//fragment
//DECIMAL_VALUE :   DIGIT+;
DECIMAL_VALUE   :   TMP_DECIMAL_VALUE;
fragment
TMP_DECIMAL_VALUE   :   DIGIT+;
 
fragment
HEX_DIGIT : ('a'..'f'|'A'..'F' | DIGIT) ;
 
string_value    :   (DEFINE_IMPORTED_VALUE | STRING);
 
startParse  :   (singleInclude | id_info | variable)+;
 
singleInclude   :   '#include' STRING;
 
//id_info       :   (manufacture | deviceType | deviceRevison | ddRevision)+;
id_info     :   (manufacture | deviceType | deviceRevison | ddRevision);
manufacture :   'MANUFACTURER'      (direct_value | DEFINE_IMPORTED_VALUE) (','?)!;
deviceType  :   'DEVICE_TYPE'       (direct_value | DEFINE_IMPORTED_VALUE)  (','?)!;
deviceRevison   :   'DEVICE_REVISION'   (direct_value | DEFINE_IMPORTED_VALUE)  (','?)!;
ddRevision  :   'DD_REVISION'       (direct_value | DEFINE_IMPORTED_VALUE)  (','?)!;
 
//fragment
//DIRECT_VALUE  :   (HEX_VALUE | DECIMAL_VALUE);
//direct_value  :   (HEX_VALUE | DECIMAL_VALUE);
direct_value    :   (DECIMAL_VALUE | HEX_VALUE);
 
/*
7.27 VARIABLE
Table 138 – VARIABLE attributes
*/
 
//label_value   :   define_value | IMPORTED_VALUE;
//label     :   'REDEFINE'? 'LABEL' DEFINE_IMPORTED_VALUE ';';
label       :   'REDEFINE'? 'LABEL' string_value ';';
 
//help_value    :   define_value | IMPORTED_VALUE;
help        :   'REDEFINE'? 'HELP' DEFINE_IMPORTED_VALUE ';';
 
single_class_value
        :   ('ALARM'| 'ANALOG_INPUT'| 'ANALOG_OUTPUT'| 'COMPUTATION'| 'CONTAINED'| 'CORRECTION'| 'DEVICE'| 'DIAGNOSTIC'| 'DIGITAL_INPUT'| 'DIGITAL_OUTPUT'| 'DISCRETE_INPUT'| 'DISCRETE_OUTPUT'| 'DYNAMIC'| 'FREQUENCY_INPUT'| 'FREQUENCY_OUTPUT'| 'HART'| 'INPUT'| 'LOCAL'| 'LOCAL_DISPLAY'| 'OPERATE'| 'OUTPUT'| 'SERVICE'| 'TUNE');
class_value :   single_class_value ('&' single_class_value)*;
class_line  :   'CLASS' class_value ';' ;
 
 
expression_or_direct_value
    :   direct_value; //todo: add expression support
 
expression_or_string
    :   STRING;//todo:add string expression support
values_display_format
    :   'DISPLAY_FORMAT' expression_or_string ';';
values_default_value
    :   'DEFAULT_VALUE' expression_or_direct_value ';';
values_attribute
    :   values_default_value | values_display_format;//todo: add more EDIT_FORMAT, ...
float_type_value
    :   'TYPE' 'FLOAT' '{' values_attribute+ '}';
integer_type_value
    :   'TYPE' 'INTEGER' '{' values_attribute+ '}';
type        :   integer_type_value | float_type_value; //todo: add more
 
 
constant_unit   :   'CONSTANT_UNIT' string_value ';' ;
 
/*
7.27.2.5 HANDLING
*/
single_handling_value
        :   ('READ' | 'READ_WRITE' | 'WRITE');
handling_value  :   single_handling_value ('&' single_handling_value)*;
handling    :   'HANDLING' handling_value ';' ;
 
 
variable_field  :   class_line | label | type | help | constant_unit | handling;
variable    :   'REDEFINE'? 'VARIABLE' ID '{' variable_field+ '}';
 
 
/*
*HART_COMMAND
*to do :the length of CMD_NAME and the redefine of the CMD_NAME
*/
hart_command
    :   (hart_cmd_simple)|(hart_cmd_header '{' hart_cmd_number ';' hart_cmd_operation ';' hart_cmd_transaction* hart_cmd_response*);
 
hart_cmd_simple
    :   string_cmd cmd_name ';';
hart_cmd_header
    :string_cmd cmd_name;  
string_cmd
    :   'COMMAND';
cmd_name
    :   ID;
     
hart_cmd_number
    :   cmd_number cmd_number_param;   
cmd_number
    :   'NUMBER';  
 
cmd_number_param
    :   UNSIGNED_CHAR_NUMBER;
 
                 
hart_cmd_operation
    :   cmd_operation cmd_operation_param; 
cmd_operation
    :   'OPERATION'^;
cmd_operation_param
    :   'READ'|'WRITE'|'COMMAND';
     
hart_cmd_transaction
    :cmd_transaction cmd_transaction_integer? '{' cmd_transaction_param '}';   
cmd_transaction
    :   'TRANSACTION'^;
cmd_transaction_integer
    :   UNSIGNED_CHAR_NUMBER;
cmd_transaction_param
    : cmd_transaction_request '{' (cmd_transaction_request_data_item ','?)*  '}' cmd_transaction_reply '{' (cmd_transaction_reply_data_item ','?)+  '}' (cmd_transaction_response '{' cmd_response_code* '}')? ;   
cmd_transaction_request
    :   'REQUEST';
//The DATA_ITEM_SPECIAL should be specified  clearly and test in future
cmd_transaction_request_data_item
    : ID | UNSIGNED_CHAR_NUMBER | DATA_ITEM_SPECIAL;
cmd_transaction_reply
    :'REPLY';  
cmd_transaction_reply_data_item
    :ID | DATA_ITEM_SPECIAL;
cmd_transaction_response
    :'RESPONSE';
cmd_response_code
    : (cmd_name ','?) | (cmd_response_code_item ';');  
 
hart_cmd_response
    :   cmd_response '{' (cmd_response_code_item ';')+  '}';           
cmd_response
    :   'RESPONSE_CODES'^; 
//cmd_response_param
//  : cmd_response_code_item ; 
     
cmd_response_code_item
    : cmd_response_code_item_value ',' cmd_response_code_item_type ',' cmd_response_code_item_description ','? cmd_response_code_item_help?;
     
cmd_response_code_item_value
    :UNSIGNED_CHAR_NUMBER;//DECIMAL_VALUE; 
cmd_response_code_item_type
    :'SUCCESS'|'DATA_ENTRY_WARNING'|'MTIC_WARNING'|'DATA_ENTRY_ERROR'|'MODE_ERROR'|'PROCESS_ERROR'|'MISC_ERROR';
cmd_response_code_item_description
    :string_for_description_help;
cmd_response_code_item_help
    :string_for_description_help;  
string_for_description_help
    :   ('"' ID '"') |'[' ID ']';

用antlrworks 1.5rc2调试,去匹配内容:

1
2
3
4
5
6
7
8
/* *
 *      .........
 * */
 
/*----------------------- D E C L A R A T I O N S ----------------------*/
 
//MANUFACTURER PMV, DEVICE_TYPE _D3, DEVICE_REVISION 1, DD_REVISION 2
MANUFACTURER 1, DEVICE_TYPE 1, DEVICE_REVISION 1, DD_REVISION 2

结果出错:

output输出为:

D:\DevRoot\IndustrialMobileAutomation\HandheldDataSetter\ANTLR\projects\v1.5\HartEddlParser\pos_identification_varialbe_command.ddl line 16:13 no viable alternative at input ‘1’

 

Events中是:

49 Recognition exception NoViableAltException(0@[null])

对应错误截图为:

no viable alternative at input NoViableAltException

【解决过程】

1.此处,感觉还是不懂,为何对于简单的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fragment
DIGIT
    :   '0'..'9';
 
HEX_VALUE
    :   TMP_HEX_VALUE;
fragment
TMP_HEX_VALUE
    :       '0x' HEX_DIGIT+;
 
//fragment
//DECIMAL_VALUE :   DIGIT+;
DECIMAL_VALUE   :   TMP_DECIMAL_VALUE;
fragment
TMP_DECIMAL_VALUE   :   DIGIT+;
 
fragment
HEX_DIGIT : ('a'..'f'|'A'..'F' | DIGIT) ;
 
manufacture :   'MANUFACTURER'      (direct_value | DEFINE_IMPORTED_VALUE) (','?)!;
 
direct_value    :   (DECIMAL_VALUE | HEX_VALUE);

去匹配

1
MANUFACTURER 1

竟然MANUFACTURER后面的1,会被丢掉,而无法匹配,出现NoViableAltException的错误。

2.猜测,或许是因为,由于把,HEX_DIGIT,放在了,其调用者,TMP_HEX_VALUE,的后面,

所以导致带fragment的HEX_DIGIT,无法获得对应的数字了。

所以去改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fragment
HEX_DIGIT : ('a'..'f'|'A'..'F' | DIGIT) ;
 
//fragment
//HEX_VALUE
//  :   '0x' HEX_DIGIT+;
HEX_VALUE
    :   TMP_HEX_VALUE;
fragment
TMP_HEX_VALUE
    :       '0x' HEX_DIGIT+;
 
//fragment
//DECIMAL_VALUE :   DIGIT+;
DECIMAL_VALUE   :   TMP_DECIMAL_VALUE;
fragment
TMP_DECIMAL_VALUE   :   DIGIT+;

试试效果。

结果问题依旧。

3.再改为:

1
2
3
4
5
fragment
TMP_DECIMAL_VALUE   :   DIGIT+;
//fragment
//DECIMAL_VALUE :   DIGIT+;
DECIMAL_VALUE   :   TMP_DECIMAL_VALUE;

结果是,问题依旧。

 

【总结】

后来终于搞懂了,实际上是:

对于十进制的立即数,目前有两个部分;

一个是,用于表示0-255的部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
UNSIGNED_CHAR_NUMBER
    :UNSIGNED_CHAR_CONDITION_ONE|UNSIGNED_CHAR_CONDITION_TWO|UNSIGNED_CHAR_CONDITION_THREE|UNSIGNED_CHAR_CONDITION_FOUR;
fragment  
UNSIGNED_CHAR_CONDITION_ONE
    :'0';
fragment   
UNSIGNED_CHAR_CONDITION_TWO
    :'1' (DIGIT | (DIGIT DIGIT))?;     
fragment
UNSIGNED_CHAR_CONDITION_THREE
    :'2' (('0'..'4' DIGIT?) | ('5' '0'..'5'?) | ('6'..'9'))?;              
fragment
UNSIGNED_CHAR_CONDITION_FOUR
    :'3'..'9' DIGIT?;

另一个是,表示,所有的,普通的十进制的立即数的部分,即:

1
direct_value    :   (DECIMAL_VALUE | HEX_VALUE);

中的DECIMAL_VALUE部分:

1
2
3
4
5
fragment
TMP_DECIMAL_VALUE   :   DIGIT+;
//fragment
//DECIMAL_VALUE :   DIGIT+;
DECIMAL_VALUE   :   TMP_DECIMAL_VALUE;

导致的结果是,

对于输入的数字:

1

其结果,被放在DECIMAL_VALUE前面的UNSIGNED_CHAR_NUMBER 部分匹配到了。

导致后来的:

1
2
manufacture :   'MANUFACTURER'      (direct_value | DEFINE_IMPORTED_VALUE) (','?)!;
direct_value    :   (DECIMAL_VALUE | HEX_VALUE);

中的DECIMAL_VALUE再去匹配对应的数字1,就没了,所以就出现了:

no viable alternative at input ‘1’

的错误。

 

解决办法是:

方案1:

要么把UNSIGNED_CHAR_NUMBER部分删除掉,这样,对于任何输入的十进制的立即数,都去用DECIMAL_VALUE匹配,就不会有歧义和误判了。

方案2:

要么是把现有的DECIMAL_VALUE,拆分成:

0-255的UNSIGNED_CHAR_NUMBER

加上余下的,255到无穷大的部分

即:

  • 删除掉原有的
  • 保留UNSIGNED_CHAR_NUMBER,但是最好改名为:DECIMAL_0_255
  • 再写一个DECIMAL_255_MAX
  • 把原有的DECIMAL_VALUE的表示方法去掉,换成(DECIMAL_0_255 | DECIMAL_255_MAX)

如此,就可以解决了:

去匹配任何的十进制的立即数,使用:DECIMAL_VALUE

去匹配0-255的十进制的立即数,使用:DECIMAL_0_255

就不会产生冲突了。

转载请注明:在路上 » 【已解决】antlr代码执行出错:xxx.ddl line 16:13 no viable alternative at input ‘1’,Recognition exception NoViableAltException(0@[null])

发表我的评论
取消评论

表情

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

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