QLExpress脚本语言技术讲解(2) -----QL的基本执行过程

 @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 本地缓存乘一段指令,第二次重复执行的时候直接执行指令,极大的提高了性能。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值