扩展简单的 ANTLR 语法以支持输入变量
我仍在我的追求一种非常简单的语言,但我现在知道不存在这种语言。所以我自己用 ANTLR3 写了一个。
我在这个答案中找到了一个非常好的例子:
Exp.g:
grammar Exp;
eval returns [double value]
: exp=additionExp {$value = $exp.value;}
;
additionExp returns [double value]
: m1=multiplyExp {$value = $m1.value;}
( '+' m2=multiplyExp {$value += $m2.value;}
| '-' m2=multiplyExp {$value -= $m2.value;}
)*
;
multiplyExp returns [double value]
: a1=atomExp {$value = $a1.value;}
( '*' a2=atomExp {$value *= $a2.value;}
| '/' a2=atomExp {$value /= $a2.value;}
)*
;
atomExp returns [double value]
: n=Number {$value = Double.parseDouble($n.text);}
| '(' exp=additionExp ')' {$value = $exp.value;}
;
Number
: ('0'..'9')+ ('.' ('0'..'9')+)?
;
WS
: (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;}
;
Java 代码:
public Double evaluate(String string, Map<String, Double> input) throws RecognitionException {
ANTLRStringStream in = new ANTLRStringStream(string);
ExpLexer lexer = new ExpLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
return new ExpParser(tokens).eval();
}
使用这个 ANTLR 语法,我可以计算类似的表达式
(12+14)/2
并得到 13 作为结果。
现在,我的用例唯一缺少的是一种将简单双变量注入其中的方法,以便我可以通过提供 {"A": 12.0, "B":14.0} 作为输入映射来评估以下内容:
(A+B)/2
任何想法?
I'm still on my quest for a really simple language and I know now that there are none. So I'm writing one myself using ANTLR3.
I found a really great example in this answer:
Exp.g:
grammar Exp;
eval returns [double value]
: exp=additionExp {$value = $exp.value;}
;
additionExp returns [double value]
: m1=multiplyExp {$value = $m1.value;}
( '+' m2=multiplyExp {$value += $m2.value;}
| '-' m2=multiplyExp {$value -= $m2.value;}
)*
;
multiplyExp returns [double value]
: a1=atomExp {$value = $a1.value;}
( '*' a2=atomExp {$value *= $a2.value;}
| '/' a2=atomExp {$value /= $a2.value;}
)*
;
atomExp returns [double value]
: n=Number {$value = Double.parseDouble($n.text);}
| '(' exp=additionExp ')' {$value = $exp.value;}
;
Number
: ('0'..'9')+ ('.' ('0'..'9')+)?
;
WS
: (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;}
;
Java Code:
public Double evaluate(String string, Map<String, Double> input) throws RecognitionException {
ANTLRStringStream in = new ANTLRStringStream(string);
ExpLexer lexer = new ExpLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
return new ExpParser(tokens).eval();
}
Using this ANTLR grammer I can evaluate expressions like
(12+14)/2
and get 13 as a result.
Now the only thing missing for my use-case is a way to inject simple double variables into this, so that I can evaluate the following by supplying {"A": 12.0, "B":14.0} as the input map:
(A+B)/2
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以创建一个
Map在你的解析器中添加一个
Identifier
并在你的语法中引入一个Identifier
:然后你的
atomExp
解析器规则将如下所示:这是一个小型(完整)演示:
现在无需自己实例化解析器/词法分析器,您可以简单地执行:
这将产生:
祝你好运!
You could create a
Map<String, Double> memory
in your parser and introduce aIdentifier
in your grammar:Then your
atomExp
parser rule would look like this:Here's a small (complete) demo:
And now theres no need to instantiate the parser/lexer yourself, you can simply do:
which will produce:
Good luck!
啊,花时间来实现这个,所以不妨发布它,即使我被击败了:)
在下面的语法中,我已经实现了您想要做的变量分配的格式。
Bah, took the time to implement this so might as well post it, even though I was beat to the punch :)
In the grammar below I have implemented the format of variable assigning you were looking to do.