我仍在寻求一种非常简单的语言,现在我知道没有任何语言。所以我是用ANTLR3自己写的。
我在这个答案中找到了一个非常好的例子:
克:
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
现在,我的用例唯一缺少的是一种向其中注入简单的double变量的方法,因此我可以通过提供{“ A”:12.0,“
B”:14.0}作为输入映射来评估以下内容:
(A+B)/2
有任何想法吗?
您可以Map<String, Double> memory
在解析器中创建一个,并Identifier
在语法中引入一个:
Identifier
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
;
然后,您的atomExp
解析器规则将如下所示:
atomExp returns [double value]
: n=Number {$value = Double.parseDouble($n.text);}
| i=Identifier {$value = memory.get($i.text);} // <- added!
| '(' exp=additionExp ')' {$value = $exp.value;}
;
这是一个小型(完整)演示:
grammar Exp;
@parser::members {
private java.util.HashMap<String, Double> memory = new java.util.HashMap<String, Double>();
public static Double eval(String expression) throws Exception {
return eval(expression, new java.util.HashMap<String, Double>());
}
public static Double eval(String expression, java.util.Map<String, Double> vars) throws Exception {
ANTLRStringStream in = new ANTLRStringStream(expression);
ExpLexer lexer = new ExpLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ExpParser parser = new ExpParser(tokens);
parser.memory.putAll(vars);
return parser.parse();
}
}
parse 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);}
| i=Identifier {$value = memory.get($i.text);}
| '(' exp=additionExp ')' {$value = $exp.value;}
;
Identifier
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
;
Number
: ('0'..'9')+ ('.' ('0'..'9')+)?
;
WS
: (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;}
;
现在,您无需自己实例化解析器/词法分析器,您只需执行以下操作:
import org.antlr.runtime.*;
import java.util.*;
public class ANTLRDemo {
public static void main(String[] args) throws Exception {
Map<String, Double> vars = new HashMap<String, Double>();
vars.put("two", 2.0);
vars.put("pi", Math.PI);
System.out.println(ExpParser.eval("two * pi", vars));
}
}
会产生:
6.283185307179586
祝好运!
本文向大家介绍ANTLR语言支持,包括了ANTLR语言支持的使用技巧和注意事项,需要的朋友参考一下 示例 ANTLR能够为多种编程语言生成解析器: C#目标 Python目标 JavaScript目标 Java目标 默认情况下,ANTLR将使用Java编程语言从命令行生成解析器: 要更改目标语言,可以从OS终端/命令行运行以下命令: 不必每次都在命令行/终端上使用“ -Dlanguage”参数来为
Electron 支持 Chrome 扩展API的子集, 主要是支持 DevTools 扩展和 Chromium-internal 扩展,但它同时也支持一些其他扩展能。 注意:Electron 不支持商店中的任意 Chrome 扩展,Electron 项目的目标不是与 Chrome 的扩展实现完全兼容。 加载扩展 Electron 只支持加载未打包的扩展 (即不能使用 .crx 文件)。 插件会被
问题内容: 问题的答案 是否可以在JavaScript中创建自定义运算符? 是 没有的,但@Benjamin建议,这将有可能使用添加一个新的运营商 的第三方工具 : 可以使用sweet.js之类的第三方工具来添加自定义运算符,尽管这需要额外的编译步骤。 我将采用相同的示例,就像上一个问题一样: (ℝ,∘),x y = x + 2y 对于任何两个实数 x 和 y : x y 是 x + 2y ,这也
我尝试扩展ISOSTS XSD方案以支持SVG图像标记。我找到了用于SVG的XSD方案,并将其放在附近。现在我尝试扩展: 但是我在尝试加载方案时出错: 怎么啦?
在过去的几周里,我一直在编写一些浏览器扩展,直到今天,我认为Firefox的WebExtension应该在Chrome中自动运行。所以我试着根据Mozilla的示例编写代码。 但是今天我意识到在Chrome扩展的API文档中没有提到承诺。 我在所有扩展的代码中都严格地使用了承诺。 所以现在我的问题是,我的代码能在Chrome中工作吗?或者,如果我在顶部添加一个声明,它会起作用吗? 或者,Chrom
包含 RTL 文件 如需启用 RTL 功能,则要包含 'easyui-rtl.css' 和 'easyui-rtl.js' 文件。 <link rel="stylesheet" type="text/css" href="themes/default/easyui.css"> <link rel="stylesheet" type="text/css" href="easyui-rtl.cs