【问题】
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]) |
对应错误截图为:
【解决过程】
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])