java - 具有 Java 互操作性的 ANTLR DSL

标签 java interop antlr dsl antlr3

我一直在学习 http://bkiers.blogspot.de/2011/03/creating-your-own-programming-language.html 上的教程。 。简而言之,开发了一种具有最少算术运算集的小型语言。 “println”和“print”是直接映射的函数,调用 System.out.print()

从此,我尝试通过更改该系列文章中开发的语言的一些属性来实现我自己的 DSL。我想做java.lang.Math可以从我的 DSL 中访问,但想不出无需手动映射每个函数的好方法。

该语言不支持任何导入。我可以引入一个新的语法规则来匹配 Math.<function>(<parameters>) .

最佳答案

您可以通过将 Math 设置为保留字并进行以下更改来做到这一点:

语法补充

functionCall
  :  Identifier '(' exprList? ')'         -> ^(FUNC_CALL Identifier exprList?)
  |  Println '(' expression? ')'          -> ^(FUNC_CALL Println expression?)
  |  Print '(' expression ')'             -> ^(FUNC_CALL Print expression)
  |  Assert '(' expression ')'            -> ^(FUNC_CALL Assert expression)
  |  Size '(' expression ')'              -> ^(FUNC_CALL Size expression)
  |  Math '.' Identifier '(' exprList ')' -> ^(FUNC_CALL Math Identifier exprList) // added
  ;

// ...

Math : 'Math'; // added

树语法添加

functionCall returns [TLNode node]
  :  ^(FUNC_CALL Identifier exprList?)     {node = new FunctionCallNode($Identifier.text, $exprList.e, functions);}
  |  ^(FUNC_CALL Println expression?)      {node = new PrintlnNode($expression.node);}
  |  ^(FUNC_CALL Print expression)         {node = new PrintNode($expression.node);}
  |  ^(FUNC_CALL Assert expression)        {node = new AssertNode($expression.node);}
  |  ^(FUNC_CALL Size expression)          {node = new SizeNode($expression.node);}
  |  ^(FUNC_CALL Math Identifier exprList) {node = new MathCallNode($Identifier.text, $exprList.e);} // added
  ;

新的数学节点类

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 + "(...)");
    }
}

现在您不需要在自己的类中实现所有单独的方法,但当然仍然需要检查在 MathCallNodeevaluate() 方法中调用了哪个方法。

如果您现在评估:

println(Math.sqrt(9));
println(Math.min(9, -42));

将打印以下内容:

3.0
-42.0

关于java - 具有 Java 互操作性的 ANTLR DSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10280327/

相关文章:

c++ - 在 Fortran 和 C++ 之间传递复杂的数据结构

antlr - 我如何对这个输入进行词法分析?

java - 短路运算符给我不同的结果

java - 如何使用printf以某种格式打印出来

Java - Action 监听器只响应一个 if 语句?

java - 在 Java Spring 中将 JSON 绑定(bind)到 Arraylist?

c# - 动态与类型化产生奇怪的结果

c# - 如何将指向 char[256] 数组的指针从 C++ 编码到 C#

angular - 没有'new'就不能调用类构造函数

c++ - 在 C++ 应用程序中集成 ANTLR 4