【问题】
用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