博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Antlr实现表达式引擎
阅读量:5091 次
发布时间:2019-06-13

本文共 2362 字,大约阅读时间需要 7 分钟。

上周末尝试使用Antlr生成C#语言的表达式引擎,目前已经可以支持基本运算.主要思路是把表达式解析成操作数和函数(操作符也作为函数看待)两种类型节点,主要部分类图如下:

Node.jpg

GrandExpr.g文件内容如下:

grammar GrandExpr;options {  output=AST;  ASTLabelType=CommonTree; // language=CSharp;}tokens{	INDEX;	MEMBERACCESS;	CALL;}expr	:	logicalOrExpr	;logicalOrExpr 	:	logicalAndExpr (OR logicalAndExpr)* 	;                        logicalAndExpr	:	equalityExpr (AND equalityExpr)*  	;   	                     equalityExpr	:	relationalExpr ((EQUALS|NOTEQUALS)^ relationalExpr)*	;	relationalExpr	:	additiveExpr ((LT|LTEQ|GT|GTEQ)^ additiveExpr)? 	;  additiveExpr	:	multiplyExpr ((PLUS|MINUS)^ multiplyExpr)*  	;multiplyExpr  	:	powExpr ((a=MUL| a=DIV | a=MOD) powExpr)*    	;   powExpr   	:	unaryExpr (POWER unaryExpr)?    	;   unaryExpr	:  	(PLUS | MINUS | NOT) unaryExpr	  	|  	memberExpr 	;       memberExpr   	:	basicExpr (memberAccessExpr)*  (indexerExpr)?   	;basicExpr	:	 parenExpr | literal |  memberFunctionExpr;   	       parenExpr    	:	LPAREN! expr  RPAREN!   	;    	literal   	: 	numbericLiteral  	| 	stringLiteral   	;       numbericLiteral  	:  	INTEGER_LITERAL	   	| 	DECIMAL_LITERAL    	| 	DATETIME_LITERAL   	;   stringLiteral  	: 	STRING_LITERAL     	;   	   	memberAccessExpr	:	'.' memberFunctionExpr -> ^(MEMBERACCESS memberFunctionExpr)	;memberFunctionExpr	:	fieldPropertyExpr | methodExpr	;	fieldPropertyExpr	:	IDENTIFIER	;	   methodExpr		:	IDENTIFIER LPAREN (argument (COMMA argument)*)? RPAREN -> ^(CALL IDENTIFIER argument*)	;	    indexerExpr		:	LBRACKET argument (COMMA argument)* RBRACKET -> ^(INDEX argument+)	;	argument   	: 	expr   	;      AND		:	'and'	;	OR		: 	'or'	;NOT		: 	'not'	;COMMA 		: 	','  	;PLUS		: 	'+'  	;	MINUS		: 	'-'	;	MUL		: 	'*'  	;	DIV		: 	'/'  	;	MOD		: 	'%'	;	POWER		: 	'^'	;	EQUALS	:	'=';	NOTEQUALS 	:	'!=' | '<>';	LT	:	'<';LTEQ	:	'<=';GT	:	'>';GTEQ	:	'>=';LPAREN	:	'('	;	RPAREN	:	')'	;LBRACKET	:	'['	;RBRACKET	:	']'	;	DATETIME_LITERAL	: 	'\'' STRING_LITERAL '\''	;STRING_LITERAL		:	'"' (~'"')* '"'		;IDENTIFIER	:	LETTER (LETTER|Digit)*	;	fragmentLETTER		:	'A'..'Z'|'a'..'z'|'_'	;DECIMAL_LITERAL	:   	(INTEGER_LITERAL)? '.' Digit* Exponent? 	;fragmentExponent 	: 	('e'|'E') INTEGER_LITERAL	;INTEGER_LITERAL 	: 	Digit+ 	;	fragmentDigit		:	'0'..'9'	;/* Ignore white spaces */	WS		:  (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}	;

 

 

欢迎转载,转载请注明:转载自 [ ]

转载于:https://www.cnblogs.com/zhoujg/archive/2007/04/17/717488.html

你可能感兴趣的文章
HDU 5510 Bazinga KMP
查看>>
[13年迁移]Firefox下margin-top问题
查看>>
Zookeeper常用命令 (转)
查看>>
Enterprise Library - Data Access Application Block 6.0.1304
查看>>
重构代码 —— 函数即变量(Replace temp with Query)
查看>>
Bootstrap栅格学习
查看>>
程序员的数学
查看>>
聚合与组合
查看>>
如何理解汉诺塔
查看>>
洛谷 P2089 烤鸡【DFS递归/10重枚举】
查看>>
Linux基本操作
查看>>
osg ifc ifccolumn
查看>>
C++ STL partial_sort
查看>>
centos redis 安装过程,解决办法
查看>>
IOS小技巧整理
查看>>
WebDriverExtensionsByC#
查看>>
我眼中的技术地图
查看>>
lc 145. Binary Tree Postorder Traversal
查看>>
sublime 配置java运行环境
查看>>
在centos上开关tomcat
查看>>