编译器/解释器设计:内置方法应具有自己的Node还是应使用查找表?

问题描述 投票:0回答:1

我正在设计一个使用递归下降的解释器,现在我已经开始实现内置方法。

[我正在实现的方法的一个示例是print()方法,它输出到控制台,就像python的print()方法和Java的System.out.println()

然而,引起我注意的是,有多种方法可以实现这些内置方法。我敢肯定还有很多,但是我已经确定了两种可行的方法来实现这一目标,我正在尝试确定哪种方法是最佳实践。下面的上下文是我在解释器中使用的不同层,这些层大致基于https://www.geeksforgeeks.org/introduction-of-compiler-design/和我遇到的其他教程。

  1. Lexer
  2. 解析器
  3. 语义分析器
  4. 解释器/代码生成器

1。为每个内置方法创建一个AST节点。

此方法需要对解析器进行编程,以为每个单独的方法生成一个节点。这意味着每种方法都将存在一个唯一节点。例如:

当在词法分析器中找到TPRINT标记时,解析器将寻找生成一个节点。

print : TPRINT TLPAREN expr TRPAREN {$$ = new Print($3);}
      ;

这是打印类的外观。

class Print : public Node {
public:
    virtual VariableValue visit_Semantic(SemanticAnalyzer* analyzer) override;
    virtual VariableValue visit_Interpreter(Interpreter* interpreter) override;
    Node* value;
    Print(Node* cvalue) {
        value = cvalue;
    }
}

[我从那里定义visit_Semanticvisit_interpreter方法,并使用从顶部节点的递归访问它们。

我可以想到使用此方法的一些优点/缺点:

优点

  • [当代码生成器在树上行走并访问Print节点的visit_interpreter方法时,它可以直接将响应编程为它的访问方法,直接执行响应。

缺点

  • 我将不得不编写很多复制粘贴代码。我将必须为每个单独的方法创建一个节点,然后定义它的解析器语法。

2。为方法调用节点创建通用AST节点,然后使用查找表确定正在调用的方法。

这涉及创建一个通用节点MethodCall和语法,以确定是否已调用方法,并带有一些唯一的identifier,例如所引用方法的字符串。然后,当调用MethodCallvisit_Interpretervisit_Semantic方法时,它将在要执行代码的表中查找。

methcall : TIDENTIFIER TLPAREN call_params TRPAREN {$$ = new MethodCall($1->c_str(), $3);}
         ;

MethodCall节点。这里的唯一标识符是std::string methodName

class MethodCall : public Node {
public:
    virtual VariableValue visit_Semantic(SemanticAnalyzer* analyzer) override;
    virtual VariableValue visit_Interpreter(Interpreter* interpreter) override;
    std::string methodName;
    ExprList *params;
    MethodCall(std::string cmethodName, ExprList *cparams) {
        params = cparams;
        methodName = cmethodName;
    }
};

优点:

  • 所有方法调用的一个通用语法/节点。这使其更具可读性

缺点:

  • 在某些时候,唯一标识符std::string methodName必须在查找表中进行比较以确定对此的响应。这不像直接编程来响应Node的访问方法那样有效。

哪种实践是在编译器/解释器中处理方法的最佳方法?是否总有一些更好的不同做法,或者我还缺少其他缺点/缺点?

我对编译器/解释器设计还很陌生,所以请问我是否弄错了某些术语。

methods compiler-construction lookup abstract-syntax-tree interpreter
1个回答
0
投票

您绝对应该使用表查找。它使您的工作变得容易得多。另外,请考虑用户定义的功能!然后,您肯定需要一张桌子。

© www.soinside.com 2019 - 2024. All rights reserved.