基于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为语 ...
随机推荐
- pyinstaller 打包 win32ctypes.pywin32.pywintypes.error: (225, '', '无法成功完成操作,因为文件包含病毒或潜在的垃圾软件。')
背景: 使用python 写了一个程序,使用pyinstaller打包, 不使用-w --noconsole的命令打包隐藏命令行窗口时,是正常的, 但是使用-w或者--noconsole就会报错win ...
- 解决使用filter: blur时图片四周泛白的问题
发现问题 在使用filter: blur(15px)模糊背景图时,发现图片周围会泛白. 解决问题 查了好多办法: 1.使用StackBlur.js处理图片模糊. 2.改变background-size ...
- NDP 协议
Ref: http://ipv6.infosws.cn/20201009/40639.html IPv6系列基础篇(下)--邻居发现协议NDP IPv6之基础协议(3)讲NDP 里面NS, NA 报文 ...
- 使用 nuxi info 查看 Nuxt 项目详细信息
title: 使用 nuxi info 查看 Nuxt 项目详细信息 date: 2024/9/5 updated: 2024/9/5 author: cmdragon excerpt: 摘要:文章介 ...
- HashMap深入讲解
HashMap是Java中最常用的集合类框架,也是Java语言中非常典型的数据结构, 而HashSet和HashMap者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说HashSet ...
- JS处理html的编码(encode)与解码(decode)
一.用浏览器内部转换器实现转换 代码: var HtmlUtil = { // 1.用浏览器内部转换器实现html编码 htmlEncode: function(html) { // 创建一个元素容器 ...
- docker安装运行kafka单机版
这里我们安装一下kafka的单机版,由于kafka是基于zk进行管理的,如果我们没有安装过zk的话,需要进行安装好zk再安装kafka,当然如果已经安装过了, 那就没必要安装了.我们可以执行docke ...
- MyBatis——案例——修改(修改全部字段,修改动态字段)
修改-修改全部字段 1.编写接口方法:Mapper接口 参数:所有数据 结果:void(通过异常捕获判断成功修改与否) int (表示sql语句影响的行数) /** ...
- [TK] Blocks 单调栈
题目描述 给出 \(N\) 个正整数 \(a[1..N]\) ,再给出一个正整数 \(k\) ,现在可以进行如下操作:每次选择一个大于 \(k\) 的正整数 \(a[i]\) ,将 \(a[i]\) ...
- eBPF 概述:第 1 部分:介绍
1. 前言 有兴趣了解更多关于 eBPF 技术的底层细节?那么请继续移步,我们将深入研究 eBPF 的底层细节,从其虚拟机机制和工具,到在远程资源受限的嵌入式设备上运行跟踪. 注意:本系列博客文章将集 ...