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. 以MySQL为例,来看看maven-shade-plugin如何解决多版本驱动共存的问题?

    开心一刻 清明节那天,看到一小孩在路边烧纸时不时地偷偷往火堆里扔几张考试卷子边烧边念叨:爷爷呀,你岁数大了,在那边多做做题吧,对脑子好,要是有不懂的地方,就把我老师带走,让他教您! 前提说明 假设 M ...

  2. HTML & CSS – Practice Projects

    前言 学完了 w3school 就要练练手了. 这篇是记入我学习的过程, 和知识点. update: 2022-02-27 用文章来表达太难了, 用视频比较合理. 所以我就没有继续写了. 这里记入几篇 ...

  3. CSS – 屏幕, 打印, 分辨率, 物理像素, 逻辑像素, Retina, DPI, PPI 是什么?

    前言 之前就有写过关于 Retina 和 Responsive Image 响应式图片 (responsive image) Retina 显示屏 但写的很烂, 这篇从新整理一下. 参考: 掌握web ...

  4. java_day3_Scanner,顺序结构,选择结构(if,switch),循环结构(for,while),

    一.Scanner 键盘录入:程序运行过程中,用户可以根据自己的需求输入参与运算的值 实现键盘录入的步骤 1.导包 2.创建键盘录入对象 3.调用方法实现键盘录入 1)输入整数 2)输入字符串 pub ...

  5. 深入理解虚拟 物理地址转换,页表--基于ARMV8

    1. 页表转换寄存器描述符 1.1,页表/页目录结构 基于前言中的内核配置,内核采用39位虚拟地址,因此可寻址范围为2^39 = 512G,采用(linux 默认为五级页表,另外还有PUD,P4D,由 ...

  6. Data Summit 2022 大会资料分享(共23个)

    Data Summit (数据峰会)是国际上关于数据管理.分析方面最新战略和技术研讨的顶尖峰会,通过行业领先的企业.专家的分享,共同探讨大数据和数据科学领域的发展现状与最新技术研究. 2022年5月1 ...

  7. C# 的运算符和作用域

    // C# 运算符 // 表达式 表达式有操作数(operand)和运算符(operator)构成: // 常见的运算符 + - * / 和 new // x ?? y 如果x为null, 则计算机过 ...

  8. druid连接池报错:sql injection violation, multi-statement not allow

    druid连接池报错:sql injection violation, multi-statement not allow 需要配置druid的 multi-statement-allow属性为tru ...

  9. jmeter测试rpc接口-使用dubbo框架调用

    1.下载用于测试dubbo的spring boot项目 参考文章: http://t.zoukankan.com/111testing-p-11297038.html https://zhuanlan ...

  10. 最新Sql语句来啦

    创建数据库 CREATE DATABASE 数据库名称; 删除数据库 DROP DATABASE 数据库名称; 创建新表 create table 表名(列 类型 ,列 类型 ,..); 根据已有的表 ...