基于antlr的表达式解析器
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的表达式解析器的更多相关文章
- java字符串应用之表达式解析器
一.表达式的组成 1.数字 2.运算符:+ - / * ^ % = 3.圆括号 4.变量二.运算符优先级 由高到低分别为:+-(正负号).^.*/%.+-.= 优先 ...
- 基于Jquery的XML解析器,返回定制的HTML
依据HTML模板返回解析的XML 依赖jQuery 1.41. [代码]基于Jquery的xml解析器并返回定制的HTML /** * jQuery插件 * Author: pureco ...
- OO第四单元——基于UML的UML解析器总结&OO课程总结
OO第四单元--基于UML的UML解析器总结&OO课程总结 前言:一学期愉快(痛苦)的OO课程学习结束了,OO几个单元作业都各有特色,实验也各有特色,仔细回味起来,不再是单纯的敲代码(但自己还 ...
- OSS.Core基于Dapper封装(表达式解析+Emit)仓储层的构思及实现
最近趁着不忙,在构思一个搭建一个开源的完整项目,至于原因以及整个项目框架后边文章我再说明.既然要起一个完整的项目,那么数据仓储访问就必不可少,这篇文章我主要介绍这个新项目(OSS.Core)中我对仓储 ...
- [LeetCode] Ternary Expression Parser 三元表达式解析器
Given a string representing arbitrarily nested ternary expressions, calculate the result of the expr ...
- C 四则运算表达式解析器
下载实例:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1074 程序主要包括:基础结构定义.词法分析.语法分 ...
- dom4j解析器 基于dom4j的xpath技术 简单工厂设计模式 分层结构设计思想 SAX解析器 DOM编程
*1 dom4j解析器 1)CRUD的含义:CreateReadUpdateDelete增删查改 2)XML解析器有二类,分别是DOM和SAX(simple Api for xml). ...
- 基于Java的简易表达式解析工具(一)
最近需要用到相关表达式解析的工具,然后去网上搜索,找到了一个用C#写的表达式解析工具,仔细看了功能后发现,这正是我需要的,如果我能将它改造成基于Java语言的方式,岂不是更好吗,所以花了一段时间,把网 ...
- atitit.java解析sql语言解析器解释器的实现
atitit.java解析sql语言解析器解释器的实现 1. 解析sql的本质:实现一个4gl dsl编程语言的编译器 1 2. 解析sql的主要的流程,词法分析,而后进行语法分析,语义分析,构建sq ...
- 在.NET Core中使用Irony实现自己的查询语言语法解析器
在之前<在ASP.NET Core中使用Apworks快速开发数据服务>一文的评论部分,.NET大神张善友为我提了个建议,可以使用Compile As a Service的Roslyn为语 ...
随机推荐
- c++异步回调函数引用传递空指针异常
c++异步回调函数引用传递空指针异常 问题描述 最近使用 c++ / qt 开发的一个桌面应用,运行到一处异步执行python脚本任务的方法处报错: 进程已结束,退出代码-1073741819 (0x ...
- vue导出word文档
具体需求 在我的疫情可视化项目中有一个功能需要导出word文档,在页面点击按钮后处理数据生成word文件,然后自动下载文档. 实现步骤 多番查询后发现前端导出word,使用docxtemplater较 ...
- Windows 11 上搭建 Linux 桌面系统
为什么做这个事呢?首先dev 环境方面肯定Linux是主流,然后因为后面要跑CV应用,肯定还是要看看效果啥的,最好有个桌面系统. 1. 首先在windows 里安装 WSL, 要用 wsl2 版本 2 ...
- RedisCluster集群架构原理与通信原理
redis 参考目录: 生产级Redis 高并发分布式锁实战1:高并发分布式锁如何实现 https://www.cnblogs.com/yizhiamumu/p/16556153.html 生产级Re ...
- Falcon Mamba: 首个高效的无注意力机制 7B 模型
Falcon Mamba 是由阿布扎比的 Technology Innovation Institute (TII) 开发并基于 TII Falcon Mamba 7B License 1.0 的开放 ...
- 这些年没来得及学习的一些 HTML5 标签
认识并学习下还没来得及学习的一些 HTML5 标签 <ruby> 标签 HTML <ruby> 元素被用来展示东亚文字注音或字符注释. 比如: <ruby>兄弟&l ...
- 选择:Qt Creator、Qt Designer、Qt Design Studio,三种开发工具,您选择哪一种?
前言 本文介绍了三种QT开发工具的特点,以及各自的优点和缺点. QT三种工具对比 QT提供的工具 Qt Creator: 扮演的是QT Widgets和QT QML的IDE的角色. 优点: 可以编写C ...
- RedisTemplate设置的key,redis客户端取不到
原因:RedisTemplate 在set key时,key被序列化 解决办法1: import org.springframework.context.annotation.Bean; import ...
- Word、Excel办公书的资源下载
我是清华社编辑,下载资源没有版权问题,可供读者个人学习用,但不允许商用. 微信扫描,清华社网盘,可转自己邮箱下载.安全,无风险. <Word/Excel/PPT 2019商务办公从入门到精通&g ...
- 某制造企业基于 KubeSphere 的云原生实践
背景介绍 随着业务升级改造与软件产品专案的增多,常规的物理机和虚拟机方式逐渐暴露出一些问题: 大量服务部署在虚拟机上,资源预估和硬件浪费较大: 大量服务部署在虚拟机上,部署时间和难度较大,自动化程度较 ...