package formula;

import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.BaseTree; import formula.function.Add;
import formula.function.Function;
import formula.function.FunctionException;
import formula.function.Max; public class ExpressionEvaluator { // Contains all of the functions in use.
private Map functions = new HashMap(); // Contains all of the variables in use.
private Map variables = new HashMap(); public ExpressionEvaluator(Map variables) {
// TODO Auto-generated constructor stub
this.variables = variables;
this.putFunction(new Max());
this.putFunction(new Add());
} /**
* Adds a function to the list of functions to use when evaluating
* expressions.
*
* @param function
* The function being added.
*
* @exception IllegalArgumentException
* Thrown when the function name is not valid or the function
* name is already in use.
*/
public void putFunction(final Function function) {
// Make sure the function name is valid. // Make sure the function name isn't already in use.
final Function existingFunction = (Function) functions.get(function
.getName()); if (existingFunction == null) {
functions.put(function.getName(), function);
} else {
throw new IllegalArgumentException("A function with the same name "
+ "already exists.");
}
} /**
* Returns a funtion from the list of functions. If the function can not be
* found in the list of functions, then null will be returned.
*
* @param functionName
* The name of the function to retrieve the value for.
*
* @return The value for a function in the list of function.
*/
public Function getFunction(final String functionName) {
return (Function) functions.get(functionName);
} /**
* Removes the function from the list of functions to use when evaluating
* expressions.
*
* @param functionName
* The name of the function to remove.
*/
public void removeFunction(final String functionName) {
if (functions.containsKey(functionName)) {
functions.remove(functionName);
} else {
throw new IllegalArgumentException("The function does not exist.");
}
} /**
* Rturns the map of functions currently set on this object.
*
* @return the map of functions currently set on this object.
*/
public Map getFunctions() {
return functions;
} /**
* Sets the map of functions for this object.
*
* @param functions
* The map of functions for this object.
*/
public void setFunctions(Map functions) {
this.functions = functions;
} public ActiveOperand eval(BaseTree tree) throws FunctionException {
ActiveOperand result = null;
switch (tree.getType()) {
case FormulaLexer.NUM:
Integer temp = Integer.valueOf(tree.getChild(0).toStringTree());
result = new ActiveOperand(temp.getClass(), temp);
break;
case FormulaLexer.CALL:
result = evalFunction(tree);
break;
case FormulaLexer.T__18:
result = addFunction(tree);
break;
case FormulaLexer.VAR:
String varName = tree.getChild(0).toStringTree();
Object varValue = variables.get(varName);
result = new ActiveOperand(varValue.getClass(), varValue);
break;
} return result;
} // call has two oprands ,e.g. call max 2
private ActiveOperand addFunction(BaseTree tree) throws FunctionException {
List<Object> children = tree.getChildren();
if (null == children || children.size() != 2) {
throw new FunctionException("Two numeric arguments are required.");
}
Integer paramNum = children.size();
ActiveOperand[] arguments = new ActiveOperand[paramNum];
for (int i = 0; i < paramNum; i++) {
BaseTree t = (BaseTree) children.get(i);
arguments[i] = eval(t);
}
return evalFunction("add", arguments); // stack.push(frame);
// asn 赋值 assign 一个操作数 栈顶元素出栈,存储于数据存储器中
} // call has two oprands ,e.g. call max 2
private ActiveOperand evalFunction(BaseTree tree) throws FunctionException {
List<Object> children = tree.getChildren();
Integer paramNum = children.size() - 1;
ActiveOperand[] arguments = new ActiveOperand[paramNum];
for (int i = 0; i < paramNum; i++) {
BaseTree t = (BaseTree) children.get(i + 1);
arguments[i] = eval(t);
} return evalFunction(((BaseTree) children.get(0)).toStringTree(),
arguments); // stack.push(frame);
// asn 赋值 assign 一个操作数 栈顶元素出栈,存储于数据存储器中
} // call has two oprands ,e.g. call max 2
private ActiveOperand evalFunction(String functionName,
ActiveOperand[] arguments) throws FunctionException { Function function = this.getFunction(functionName);
return function.execute(arguments); // stack.push(frame);
// asn 赋值 assign 一个操作数 栈顶元素出栈,存储于数据存储器中
} public static void main(String[] args) throws Exception {
String[] testStr = { "max(3,max(1,2))", "2", "a + b + 3", "a - (b + 3)"
// "a + (b * 3",
// "11.1+12b+a*b", }; for (String s : testStr) {
System.out.println("Input expr: " + s);
run(s);
} } public static void run(String expr) throws Exception {
ANTLRStringStream in = new ANTLRStringStream(expr);
// 词法分析器
FormulaLexer lexer = new FormulaLexer(in); CommonTokenStream tokens = new CommonTokenStream(lexer);
// 语法分析器
FormulaParser parser = new FormulaParser(tokens); FormulaParser.prog_return ret = parser.prog(); Map variables = new HashMap();
variables.put("a", Integer.valueOf(2));
variables.put("b", Integer.valueOf(3)); ExpressionEvaluator evaluator = new ExpressionEvaluator(variables); System.out.println(evaluator.eval((((BaseTree) ret.getTree()))));
// System.out.println(((BaseTree)ret.getTree()).toStringTree());
// toStringTree(((BaseTree)ret.getTree()));
}
}

基于antlr的表达式解析器的更多相关文章

  1. java字符串应用之表达式解析器

    一.表达式的组成    1.数字    2.运算符:+ - / * ^ % =    3.圆括号    4.变量二.运算符优先级    由高到低分别为:+-(正负号).^.*/%.+-.=    优先 ...

  2. 基于Jquery的XML解析器,返回定制的HTML

    依据HTML模板返回解析的XML 依赖jQuery 1.4​1. [代码]基于Jquery的xml解析器并返回定制的HTML     /** *  jQuery插件 *  Author: pureco ...

  3. OO第四单元——基于UML的UML解析器总结&OO课程总结

    OO第四单元--基于UML的UML解析器总结&OO课程总结 前言:一学期愉快(痛苦)的OO课程学习结束了,OO几个单元作业都各有特色,实验也各有特色,仔细回味起来,不再是单纯的敲代码(但自己还 ...

  4. OSS.Core基于Dapper封装(表达式解析+Emit)仓储层的构思及实现

    最近趁着不忙,在构思一个搭建一个开源的完整项目,至于原因以及整个项目框架后边文章我再说明.既然要起一个完整的项目,那么数据仓储访问就必不可少,这篇文章我主要介绍这个新项目(OSS.Core)中我对仓储 ...

  5. [LeetCode] Ternary Expression Parser 三元表达式解析器

    Given a string representing arbitrarily nested ternary expressions, calculate the result of the expr ...

  6. C 四则运算表达式解析器

    下载实例:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1074 程序主要包括:基础结构定义.词法分析.语法分 ...

  7. dom4j解析器 基于dom4j的xpath技术 简单工厂设计模式 分层结构设计思想 SAX解析器 DOM编程

    *1 dom4j解析器   1)CRUD的含义:CreateReadUpdateDelete增删查改   2)XML解析器有二类,分别是DOM和SAX(simple Api for xml).     ...

  8. 基于Java的简易表达式解析工具(一)

    最近需要用到相关表达式解析的工具,然后去网上搜索,找到了一个用C#写的表达式解析工具,仔细看了功能后发现,这正是我需要的,如果我能将它改造成基于Java语言的方式,岂不是更好吗,所以花了一段时间,把网 ...

  9. atitit.java解析sql语言解析器解释器的实现

    atitit.java解析sql语言解析器解释器的实现 1. 解析sql的本质:实现一个4gl dsl编程语言的编译器 1 2. 解析sql的主要的流程,词法分析,而后进行语法分析,语义分析,构建sq ...

  10. 在.NET Core中使用Irony实现自己的查询语言语法解析器

    在之前<在ASP.NET Core中使用Apworks快速开发数据服务>一文的评论部分,.NET大神张善友为我提了个建议,可以使用Compile As a Service的Roslyn为语 ...

随机推荐

  1. 前后端沟通 naming conversion 转换需要知道的事

    c# 是 pascal case, js 是 camel case 所以在做 web api 和 odata 的时候经常需要转换. 早年 web api 是依赖 Newtonsoft json (JS ...

  2. SQL Server 冗余维护

    介绍 冗余是维护的魔鬼, 是性能优化的天使 常见的冗余有 1. computed column 2. principal 的识别字段 3. cross computed 4. cascade soft ...

  3. Kubernetes集群安装(十三)

    为了根据最新的集群特性,我们这里安装目前最新的版本 v1.19.3,如果你是在生产环境使用,建议使用上一个版本中最大的修正版本,比如 v1.15.5,由于 v1.16 版本之后和之前的版本有很大变化, ...

  4. kali系统安装和CVE-2017-12615测试

    1 安装kali系统 1.1 下载VMware压缩包 kali-linux-2022.1 默认的用户和密码是kali 1.2 初始化系统 sudo apt update -y #kali sudo a ...

  5. 北京智和信通PON.EPON.GPON运维解决方案,全面管理OLT.ONU等设备

    高质量.高可靠.高安全性的网络已成为助力企事业单位高速发展的基石.PON网络采用先进的无源光纤通信技术与自动化融合,构建新兴一体化网络体系,可以有效构造安全可靠的生产办公网络.因此,交通.制造.能源. ...

  6. ARM SMMU中 SteamTable的作用

    在 ARM SMMU(System Memory Management Unit)中,Stream Table 是一个非常关键的数据结构,它用于管理和映射设备的内存访问请求.它的作用主要体现在以下几个 ...

  7. 【ARMv8】异常级别的定义EL0、EL1、EL2、EL3

    Exception levels ARMv8-A系列定义了一系列的异常等级,从EL0到EL3,下面具体说明其含义: ELn中,随着n的增加,软件的执行权限也相应的增加: EL0被称为无特权执行: EL ...

  8. break,continue,return的只要区别

    a)break 结束当前循环体 b)continue 结束本次的循环,执行下次的循环 c)return 结束函数体,并返回值 d)break 和 continue 写在循环里(for,while)re ...

  9. innerText 和 inner HTML 的区别

    获取内容时: innerText会自动删除空格和换行:innerHTML会保留空格和换行: <body> <div>获 取内 容</div> <script& ...

  10. C# 根据主键ID查询数据库的数据 反射和泛型实现

    // 引入命名空间 using Zhu.ADO.NET.DBProxy; using Zhu.ADO.NET.Models.models; Console.WriteLine("====== ...