网站建设考试试题地推的方法和技巧
背景
之前在做游戏的过程中,我们经常需要解析一些公式,比如(对方攻击值-对方防御值)*2这种表达式,我们习惯于用代码写死公式,但是这种方式不够灵活,我们想要的是一种灵活的解析方式,
只需要策划输入一个任意的一个表达式,我们就可以自动计算出来对应的数值,我们不需要理解策划的公式,那么问题就转化成了如何解析表达式公式呢?答案是使用antlr.
技术实现
antlr是一个解析器,包括两个部分:词法解析器和语法解析器,如下图所示:
antlr最大的优点是可以按照树的深度优先遍历访问所有的节点,比如下面的表达式:
(1) + 10 * 20 - 40/2 - (attack + defence)
如果我们使用简单的如下.g4文件来解析的话,
grammar Calc;prog: stat+;stat: expr # printExpr| ID '=' expr # assign;expr: expr (MUL|DIV) expr # MulDiv| expr (ADD|SUB) expr # AddSub| INT # int| ID # id| '(' expr ')' # parens;MUL : '*' ;DIV : '/' ;ADD : '+' ;SUB : '-' ;ID : [a-zA-Z]+ ;INT : [0-9]+ ;WS : [ \t\r\n]+ -> skip ; // toss out whitespace
antlr可以解析成如下的解析树:
我们可以看出来如果我们编写一个Listener访问这棵树的话,我们可以得到完整的表达式,包括各个优先级都是正确的,当获取到这个按正确优先级排好序的指令后,我们可以通过简单的堆栈操作获取结果:
push(1)
push(10)
push(20)
pop(*)
pop(+)
push(40)
push(2)
pop(/)
pop(-)
push(attack)
push(defence)
pop(-)
pop(-)
注意这是一个深度优先遍历树的顺序,通过这个指令顺序,可以获取正确的表达式的值
总结
antlr提供了一种解析表达式的方便的方式,让我们可以解析任何用户或者策划提供的公式,它会按照深度优先树遍历的顺序返回数据和指令的顺序,方便我们计算最终的结果