@org.junit.Test
public void testDemo() throws Exception{
String express = "10 * 10 + 1 + 2 * 3 + 5 * 2";
ExpressRunner runner = new ExpressRunner();
Object r = runner.execute(express,null, null, false,false);
Assert.assertTrue("表达式计算", r.toString().equalsIgnoreCase("117"));
System.out.println("表达式计算:" + express + " = " + r);
}
安装好maven 执行eclipse命令,导入eclipse 之后,运行 com.ql.util.express.test.ExpressTest 单元测试
可以运行处结果:
表达式计算:10 * 10 + 1 + 2 * 3 + 5 * 2 = 117
/**
* 执行一段文本
* @param expressString 程序文本
* @param context 执行上下文
* @param errorList 输出的错误信息List
* @param isCache 是否使用Cache中的指令集
* @param isTrace 是否输出详细的执行指令信息
* @return
* @throws Exception
*/
public Object execute(String expressString, IExpressContext<String,Object> context,
List<String> errorList, boolean isCache, boolean isTrace) throws Exception ;
我们为了要看到运行的过程,修改把ExpressRunner的构造函数,以及execute的参数中: isTrace =true,重新执行下这个单元测试。
@org.junit.Test
public void testDemo() throws Exception{
String express = "10 * 10 + 1 + 2 * 3 + 5 * 2";
ExpressRunner runner = new ExpressRunner(false,true); // 显示执行编译过程
Object r = runner.execute(express,null, null, false,true); // 显示指令执行过程
Assert.assertTrue("表达式计算", r.toString().equalsIgnoreCase("117"));
System.out.println("表达式计算:" + express + " = " + r);
}
日志信息:
[2012-02-20 22:07:07,844] [main] (ExpressParse.java:486) DEBUG com.ql.util.express.parse.ExpressParse -
执行的表达式:10 * 10 + 1 + 2 * 3 + 5 * 2
[2012-02-20 22:07:07,844] [main] (ExpressParse.java:487) DEBUG com.ql.util.express.parse.ExpressParse -
单词分解结果:{10},{*},{10},{+},{1},{+},{2},{*},{3},{+},{5},{*},{2}
[2012-02-20 22:07:07,844] [main] (ExpressParse.java:491) DEBUG com.ql.util.express.parse.ExpressParse -
预处理后结果:{10},{*},{10},{+},{1},{+},{2},{*},{3},{+},{5},{*},{2}
[2012-02-20 22:07:07,860] [main] (ExpressParse.java:502) DEBUG com.ql.util.express.parse.ExpressParse -
单词分析结果:
10:CONST_INTEGER,*:*,10:CONST_INTEGER,+:+,1:CONST_INTEGER,+:+,
2:CONST_INTEGER,*:*,3:CONST_INTEGER,+:+,5:CONST_INTEGER,*:*,
2:CONST_INTEGER
[2012-02-20 22:07:07,860] [main] (ExpressParse.java:506) DEBUG com.ql.util.express.parse.ExpressParse -
Block拆分后的结果:
1: main:FUNCTION_DEFINE FUNCTION_DEFINE
2: 10:CONST_INTEGER CONST
2: *:* *
2: 10:CONST_INTEGER CONST
2: +:+ +
2: 1:CONST_INTEGER CONST
2: +:+ +
2: 2:CONST_INTEGER CONST
2: *:* *
2: 3:CONST_INTEGER CONST
2: +:+ +
2: 5:CONST_INTEGER CONST
2: *:* *
2: 2:CONST_INTEGER CONST
[2012-02-20 22:07:07,860] [main] (ExpressParse.java:511) DEBUG com.ql.util.express.parse.ExpressParse -
语句拆分后的结果:
1: main:FUNCTION_DEFINE FUNCTION_DEFINE
2: ;:; STAT_SEMICOLON_EOF
3: 10:CONST_INTEGER CONST
3: *:* *
3: 10:CONST_INTEGER CONST
3: +:+ +
3: 1:CONST_INTEGER CONST
3: +:+ +
3: 2:CONST_INTEGER CONST
3: *:* *
3: 3:CONST_INTEGER CONST
3: +:+ +
3: 5:CONST_INTEGER CONST
3: *:* *
3: 2:CONST_INTEGER CONST
[2012-02-20 22:07:07,860] [main] (ExpressParse.java:520) DEBUG com.ql.util.express.parse.ExpressParse -
最后的语法树:
1: main:FUNCTION_DEFINE FUNCTION_DEFINE
2: ;:; STAT_SEMICOLON_EOF
3: +:+ EXPRESS_LEVEL5
4: +:+ EXPRESS_LEVEL5
5: +:+ EXPRESS_LEVEL5
6: *:* EXPRESS_LEVEL4
7: 10:CONST_INTEGER CONST
7: 10:CONST_INTEGER CONST
6: 1:CONST_INTEGER CONST
5: *:* EXPRESS_LEVEL4
6: 2:CONST_INTEGER CONST
6: 3:CONST_INTEGER CONST
4: *:* EXPRESS_LEVEL4
5: 5:CONST_INTEGER CONST
5: 2:CONST_INTEGER CONST
[2012-02-20 22:07:07,860] [main] (ExpressRunner.java:491) DEBUG com.ql.util.express.ExpressRunner -
1:LoadData 10
2:LoadData 10
3:OP : * OPNUMBER[2]
4:LoadData 1
5:OP : + OPNUMBER[2]
6:LoadData 2
7:LoadData 3
8:OP : * OPNUMBER[2]
9:OP : + OPNUMBER[2]
10:LoadData 5
11:LoadData 2
12:OP : * OPNUMBER[2]
13:OP : + OPNUMBER[2]
[2012-02-20 22:15:36,090] [main] (InstructionConstData.java:25) DEBUG com.ql.util.express.instruction.detail.Instruction - LoadData 10
[2012-02-20 22:15:36,090] [main] (InstructionConstData.java:25) DEBUG com.ql.util.express.instruction.detail.Instruction - LoadData 10
[2012-02-20 22:15:36,090] [main] (InstructionOperator.java:40) DEBUG com.ql.util.express.instruction.detail.Instruction - *(10,10)
[2012-02-20 22:15:36,105] [main] (InstructionConstData.java:25) DEBUG com.ql.util.express.instruction.detail.Instruction - LoadData 1
[2012-02-20 22:15:36,105] [main] (InstructionOperator.java:40) DEBUG com.ql.util.express.instruction.detail.Instruction - +(100,1)
[2012-02-20 22:15:36,105] [main] (InstructionConstData.java:25) DEBUG com.ql.util.express.instruction.detail.Instruction - LoadData 2
[2012-02-20 22:15:36,105] [main] (InstructionConstData.java:25) DEBUG com.ql.util.express.instruction.detail.Instruction - LoadData 3
[2012-02-20 22:15:36,105] [main] (InstructionOperator.java:40) DEBUG com.ql.util.express.instruction.detail.Instruction - *(2,3)
[2012-02-20 22:15:36,105] [main] (InstructionOperator.java:40) DEBUG com.ql.util.express.instruction.detail.Instruction - +(101,6)
[2012-02-20 22:15:36,105] [main] (InstructionConstData.java:25) DEBUG com.ql.util.express.instruction.detail.Instruction - LoadData 5
[2012-02-20 22:15:36,105] [main] (InstructionConstData.java:25) DEBUG com.ql.util.express.instruction.detail.Instruction - LoadData 2
[2012-02-20 22:15:36,105] [main] (InstructionOperator.java:40) DEBUG com.ql.util.express.instruction.detail.Instruction - *(5,2)
[2012-02-20 22:15:36,105] [main] (InstructionOperator.java:40) DEBUG com.ql.util.express.instruction.detail.Instruction - +(107,10)
表达式计算:10 * 10 + 1 + 2 * 3 + 5 * 2 = 117
由这个简单的例子,我们看到了整个QL的执行过程:
单词分解-->单词类型分析-->语法分析-->生成运行期指令集合-->执行生成的指令集合。
其中前4个过程涉及语法的匹配运算等非常耗时,所以我们看到了 execute方法的 isCache 是否使用Cache中的指令集参数,它可以缓存前四个过程
。
即把 expressString 本地缓存乘一段指令,第二次重复执行的时候直接执行指令,极大的提高了性能。
分享到:
相关推荐
【脚本技术script56--2006】是一本专注于脚本技术的电子书籍,以CHM(Microsoft ...虽然时间已过去多年,但许多脚本语言的基本原理和技术依然适用,对于初学者和有经验的开发者来说,这仍是一份有价值的参考资料。
简单明了的shell脚本语言讲义,让你轻松了解shell语言。
QLExpress是一种强大、轻量级且动态的编程语言,它为开发者提供了高效的代码编写和执行环境。QLExpress的设计目标是简化编程过程,提高开发效率,同时保持灵活性和可扩展性。这种语言通常适用于快速开发、脚本编写...
使用/ dev / usb / lp0设备句柄) 声称支持以下打印机(✓表示经过作者或贡献者验证的打印机): QL-500(✓),QL-550(✓),QL-560(✓),QL-570(✓),QL-580N,QL-650TD,QL-700(✓),QL-710W(✓), QL-...
"游戏脚本-猩红收割者-弗拉基米尔2.zip"这个压缩包很可能包含了某个游戏——可能是电子游戏或者角色扮演游戏——中的角色“猩红收割者”(Vladimir)的相关脚本代码。弗拉基米尔这个名字通常与吸血鬼或暗黑角色相...
由阿里的电商业务规则、表达式(布尔组合)、特殊数学公式计算(高精度)、语法分析、脚本二次定制等强需求而设计的一门动态脚本引擎解析工具。 在阿里集团有很强的影响力,同时为了自身不断优化、发扬开源贡献精神...
**批处理**(Batch Scripting),是一种计算机编程语言,它允许用户创建一系列预定义命令的脚本文件,以实现自动化任务的执行。在Windows操作系统中,这种脚本通常被称为**批处理脚本**,其文件扩展名为`.bat`或`....
Python-Expresol库是一个专为Python开发者设计的工具,它允许用户在Python环境中执行自定义的脚本语言。这个库的独特之处在于它的灵活性和可扩展性,使得开发者可以构建自己的编程语法,然后在Python程序中无缝地...
Linux运维-运维系统服务04-Shell脚本d4-Shell循环-10并发执行判断主机是否ping
奔梦向前:学编程其实很简单,html、css、JavaScript、html5、css3、vue、Canvas实现网页特效页面、新手入门学习、了解网页动画的制作、代码实现网页动态画面-脚本循环代码-2020-04-28-2。
跨站脚本攻击(Cross-Site Scripting,简称XSS)是一种常见的网络安全漏洞,它允许攻击者通过在网页上插入恶意脚本,从而在用户的浏览器上执行代码。这些脚本可以窃取用户的数据,包括登录凭证、个人信息,甚至操纵...
在学习过程中,可以参考“Shell脚本学习指南.pdf”这样的资料,它通常会详细讲解上述各个知识点,并提供实例帮助理解。通过实践和查阅相关文档,你可以逐步提升Shell脚本编写能力,更好地利用Linux系统的强大功能。
【loadRunner入门教学详细讲解】 LoadRunner是一款由Micro Focus公司开发的企业级性能测试工具,它广泛应用于软件性能测试,能够模拟大量并发用户,检测系统在高负载下的性能表现。本教学文档将帮助初学者深入了解...
TCL(Tool Command Language)是一种脚本语言,被广泛应用于自动化测试、快速原型设计和脚本编程等领域。由于其简单易学且功能强大,TCL成为了测试仪表领域中最常用的脚本语言之一。然而,对于中文学习者来说,高...
2. **API接口**:为开发者提供了一套API,用于在程序中创建、执行、管理和控制脚本。 3. **类型转换与数据交互**:组件负责将应用的数据结构与脚本语言的数据类型进行转换,确保数据在两者之间安全、高效地传递。 4....
包含62个文件,主要采用Python语言编写,并辅以Shell脚本,以实现灵活的自动化部署流程。 文件组成: - Python脚本(.py):共24个,构成部署流程的核心部分。 - 配置文件(.xml):17个,用于定义Ambari服务的配置...
在使用这款脚本时,用户只需要运行提供的exe可执行文件,按照提示操作,就可以完成转换过程。需要注意的是,由于涉及到DRM解密,可能触及到版权法,因此在使用前应确保你有权处理这些音乐文件,并遵循当地的法律法规...
GW基本语言(GW-BASIC)是一种老牌脚本语言,自1983年问世以来,它便广泛应用于个人计算机领域。GW-BASIC Users 指南是微软公司(Microsoft Corporation)为GW-BASIC用户编写的详细指南,旨在帮助用户快速掌握GW-...