具有Java互操作性的ANTLR DSL
我一直在学习教程。简言之,开发了一种具有最小算术运算集的小型语言。“println”和“print”是直接映射的函数,它们调用具有Java互操作性的ANTLR DSL,java,interop,antlr,dsl,antlr3,Java,Interop,Antlr,Dsl,Antlr3,我一直在学习教程。简言之,开发了一种具有最小算术运算集的小型语言。“println”和“print”是直接映射的函数,它们调用System.out.print() 因此,我试图通过更改该系列文章中开发的语言的一些属性来实现我自己的DSL。我想从DSL中访问java.lang.Math,但如果不手动映射每个函数,我想不出一个好方法 该语言不支持任何导入。我可以引入一个新的语法规则来匹配数学。(肯定有更复杂的方法,但也许您可以使用doMath(“函数(a,b)”)并使用反射在生成的代码中调用函数(a
System.out.print()
因此,我试图通过更改该系列文章中开发的语言的一些属性来实现我自己的DSL。我想从DSL中访问java.lang.Math
,但如果不手动映射每个函数,我想不出一个好方法
该语言不支持任何导入。我可以引入一个新的语法规则来匹配
数学。(
肯定有更复杂的方法,但也许您可以使用doMath(“函数(a,b)”)并使用反射在生成的代码中调用函数(a,b)。您甚至可以用这种方式对函数(a,b)进行类型检查——如果java.lang.Math.function(a,b)不存在(反射说不存在),您将记录类型检查错误
这样,只有一条规则就足够了(doMath)
无论如何,祝你好运;) 肯定有更复杂的方法,但也许您可以使用doMath(“函数(a,b)”)并使用反射在生成的代码中调用函数(a,b)。您甚至可以用这种方式对函数(a,b)进行类型检查——如果java.lang.Math.function(a,b)不存在(反射说不存在),您将记录类型检查错误 这样,只有一条规则就足够了(doMath)
无论如何,祝你好运;) 您可以通过将
Math
设置为保留字并进行以下更改来完成此操作:
语法增补
树语法加法
新的数学节点类
将打印以下内容:
3.0
-42.0
您可以通过将
Math
设置为保留字并进行以下更改来完成此操作:
语法增补
树语法加法
新的数学节点类
将打印以下内容:
3.0
-42.0
谢谢!答案和你的整个博客系列一样令人惊讶。谢谢@halfdan,不客气。请注意,您可能需要在
evaluate()
中执行一些健全性检查:检查参数的数量,可能还有提供的参数的类型。非常感谢!答案和你的整个博客系列一样令人惊讶。谢谢@halfdan,不客气。请注意,您可能需要在evaluate()
中执行一些健全性检查:检查参数的数量,可能还有所提供参数的类型。
package tl.tree;
import tl.TLValue;
import java.util.ArrayList;
import java.util.List;
public class MathCallNode implements TLNode {
private String methodName;
private List<TLNode> params;
public MathCallNode(String nm, List<TLNode> ps) {
methodName = nm;
params = ps;
}
@Override
public TLValue evaluate() {
if(methodName.equals("sqrt"))
return new TLValue(Math.sqrt(params.get(0).evaluate().asDouble()));
else if(methodName.equals("min"))
return new TLValue(Math.min(params.get(0).evaluate().asDouble(), params.get(1).evaluate().asDouble()));
// TODO implement more Math-methods
else
throw new RuntimeException("unknown method: Math." + methodName + "(...)");
}
}
println(Math.sqrt(9));
println(Math.min(9, -42));
3.0
-42.0