【问题】
用antlr语法去匹配eddl中的VARIABLE中的HANDLING中的值,是个IF表达式。
其中,相关的antlr的语法为:
//LEFT : '(' | '[' | '{' ; //LEFT : '(' | '[' ; //LEFT : LEFT_PARENTHESIS | LEFT_BRACKET; LEFT_PARENTHESIS : '('; LEFT_BRACKET : '['; LEFT_BRACE : '{'; //RIGHT : ')' | ']' | '}' ; //RIGHT : ')' | ']'; //RIGHT : RIGHT_PARENTHESIS | RIGHT_BRACKET; RIGHT_PARENTHESIS : ')'; RIGHT_BRACKET : ']'; RIGHT_BRACE : '}'; LEFT_ANGLE_BRACKET : '<'; RIGHT_ANGLE_BRACKET : '>'; COMMA : ',' ; POINT : '.'; SEMICOLON : ';'; PLUS : '+'; MINUS : '-'; COMPOSITE_OPERATOR : '<<=' | '>>=' | '==' | '!=' | '<=' | '>=' | '&&' | '||' | '++' | '--' | '<<' | '>>' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '^=' | '|='; OPERATOR : '!' | '#' | '$' | '%' | '&' | '*' | PLUS | MINUS | POINT | '/' | ':' | ';' | LEFT_ANGLE_BRACKET | '=' | RIGHT_ANGLE_BRACKET | '?' | '@' | '\\' | '^' | '`' | '|' | '~' ; //OPERATOR : '!' | '#' | '$' | '%' | '&' | '*' | '+' | '-' | '.' | '/' | ':' | '<' | '=' | '>' | '?' | '@' | '\\' | '^' | '`' | '|' | '~' ; common_validity : 'VALIDITY' (common_validity_value_line | common_validity_expression) ; common_validity_expression : 'IF' common_conditional_check '{' common_validity_value_line '}' 'ELSE' '{' common_validity_value_line '}'; common_conditional_check : common_check; common_check : '(' common_single_check_value (OPERATOR | COMPOSITE_OPERATOR) common_single_check_value ')'; common_single_check_value : common_check | direct_value | string_value; common_validity_value : 'TRUE' | 'FALSE'; common_validity_value_line : common_validity_value SEMICOLON; common_handling : 'HANDLING' (common_handling_value_line | common_handling_expression) ; common_handling_expression : 'IF' common_conditional_check '{' common_handling_value_line '}' 'ELSE' '{' common_handling_value_line '}'; common_handling_value_line : handling_value SEMICOLON;
调试输入内容为:
VARIABLE eu_lower_value { LABEL "EU LO"; CLASS ANALOG_OUTPUT; HANDLING IF (((type_code & 0x80) == 0x80) && ((display_type == 27) || (display_type == 253))) { READ&WRITE; } ELSE { READ; } TYPE FLOAT { DISPLAY_FORMAT ".3f"; EDIT_FORMAT "7.3f"; MIN_VALUE -19999.0; MAX_VALUE 19999.0; } }
出错时,antlrworks中截图:
即,对于:
IF (((type_code & 0x80) == 0x80) |
中的&,就出错了,说是:
D:\DevRoot\IndustrialMobileAutomation\HandheldDataSetter\ANTLR\projects\v1.5\HartEddlParser_local_TFS\output\__Test___input.txt line 6:18 mismatched input ‘&’ expecting set null |
【解决过程】
1.此处奇怪的是:
对于&这个操作符,已经用OPERATOR去匹配了。但是不知道为何无法匹配到。
难道又是某种原因,导致OPERATOR“吃掉”了’&’,导致后续(此处)匹配不到了?
2.后来发现,当前antlr语法中,用到了OPERATOR就只有这一处。
而且是:OPERATOR,中,感觉含义不精确:
除了普通的操作符,结果把分号,冒号等内容都包括进来了。
所以,需要去优化。
3.最终,通过优化一些字符的表示,使得此处的
操作符,二元操作符,都是可以正常匹配了
使得后续匹配,不再出错。
相关语法为:
//common ID Name //must put here, before ID, otherwise can not match !!! IF : 'IF'; ELSE : 'ELSE'; TRUE : 'TRUE'; FALSE : 'FALSE'; //fragment //ID : ('a'..'z' | 'A'..'Z' |'_') (options {greedy=true;} :'a'..'z' | 'A'..'Z'| '0'..'9' |'_')*; ID : ('a'..'z' | 'A'..'Z' |'_') ('a'..'z' | 'A'..'Z'| '0'..'9' |'_')*; //LEFT : '(' | '[' | LEFT_BRACE ; //LEFT : '(' | '[' ; //LEFT : LEFT_PARENTHESIS | LEFT_BRACKET; LEFT_PARENTHESIS : '('; LEFT_BRACKET : '['; LEFT_BRACE : '{'; //RIGHT : ')' | ']' | RIGHT_BRACE ; //RIGHT : ')' | ']'; //RIGHT : RIGHT_PARENTHESIS | RIGHT_BRACKET; RIGHT_PARENTHESIS : ')'; RIGHT_BRACKET : ']'; RIGHT_BRACE : '}'; LEFT_ANGLE_BRACKET : '<'; RIGHT_ANGLE_BRACKET : '>'; COMMA : ',' ; POINT : '.'; SEMICOLON : ';'; PLUS : '+'; MINUS : '-'; //MULTIPLY : STAR; //DIVIDE : SLASH; //MODULUS : PERCENT; STAR : '*'; SLASH : '/'; PERCENT : '%'; BITWISE_AND : '&'; COMPOSITE_OPERATOR : '<<=' | '>>=' | '==' | '!=' | '<=' | '>=' | '&&' | '||' | '++' | '--' | '<<' | '>>' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '^=' | '|='; //OPERATOR : '!' | '#' | '$' | | | | PLUS | MINUS | POINT | '/' | ':' | ';' | LEFT_ANGLE_BRACKET | '=' | RIGHT_ANGLE_BRACKET | '?' | '@' | '\\' | '^' | '`' | '|' | '~' ; //OPERATOR : '!' | '#' | '$' | '%' | '&' | '*' | '+' | '-' | '.' | '/' | ':' | '<' | '=' | '>' | '?' | '@' | '\\' | '^' | '`' | '|' | '~' ; binary_operator //BINARY_OPERATOR // : PLUS | MINUS | MULTIPLY | DIVIDE | MODULUS | BITWISE_AND; : PLUS | MINUS | STAR | SLASH | PERCENT | BITWISE_AND; common_validity : 'VALIDITY' (common_validity_value_line | common_validity_expression) ; common_validity_expression : IF common_conditional_check LEFT_BRACE common_validity_value_line RIGHT_BRACE ELSE LEFT_BRACE common_validity_value_line RIGHT_BRACE; common_conditional_check : common_check; common_check : '(' common_single_check_value (binary_operator | COMPOSITE_OPERATOR) common_single_check_value ')'; common_single_check_value : common_check | direct_value | string_value; common_validity_value : TRUE | FALSE; common_validity_value_line : common_validity_value SEMICOLON; common_handling : 'HANDLING' (common_handling_value_line | common_handling_expression) ; common_handling_expression : IF common_conditional_check LEFT_BRACE common_handling_value_line RIGHT_BRACE ELSE LEFT_BRACE common_handling_value_line RIGHT_BRACE; common_handling_value_line : handling_value SEMICOLON;
4.此处,顺带贴上:
调试的输入内容:
VARIABLE eu_lower_value { HANDLING IF (((type_code & 0x80) == 0x80) && ((display_type == 27) || (display_type == 253))) { READ&WRITE; } ELSE { READ; } TYPE FLOAT { DISPLAY_FORMAT ".3f"; EDIT_FORMAT "7.3f"; MIN_VALUE -19999.0; MAX_VALUE 19999.0; } }
所解析后的,输出的Parse Tree的截图:
效果还是不错的。
【总结】
此处,对于之前用OPERATOR所表示的&字符,匹配不到,出现Mismatch的异常
原因就是,不知道哪里没写准确,导致前面的某个token已经匹配过了&
导致此处的OPERATOR匹配不到了这个&字符
使得后面匹配出错。
经过优化,尤其是,从lexer的token,改为了parser的rule:
binary_operator : PLUS | MINUS | STAR | SLASH | PERCENT | BITWISE_AND; common_check : '(' common_single_check_value (binary_operator | COMPOSITE_OPERATOR) common_single_check_value ')';
而使得,可以匹配到了。
转载请注明:在路上 » 【已解决】antlr中匹配OPERATOR出错:mismatched input ‘&’ expecting set null