【已解决】antlr中匹配OPERATOR出错:mismatched input ‘&’ expecting set null

【问题】

用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中截图:

operator char amp mismatchedsetexception

即,对于:

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的截图:

variable handling if expression 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 ')';

而使得,可以匹配到了。



发表评论

电子邮件地址不会被公开。 必填项已用*标注

无觅相关文章插件,快速提升流量