C++ 要创建编译器,是否必须生成AST?

C++ 要创建编译器,是否必须生成AST?,c++,parsing,assembly,abstract-syntax-tree,C++,Parsing,Assembly,Abstract Syntax Tree,我想知道生成AST是否是实现语言的必要条件,例如通过编译器。我问过几次,每次都强烈建议在代码解析/词法分析期间生成AST。 例如,这: int i = 2 + 3; 必须给出以下信息: = / \ i + / \ 2 3 但这种简单的条件难道还不够吗 if (statement == variable_declaration){ if (NotDeclaredInCurrentBlock(NameOfVariable)){

我想知道生成AST是否是实现语言的必要条件,例如通过编译器。我问过几次,每次都强烈建议在代码解析/词法分析期间生成AST。 例如,这:

int i = 2 + 3;
必须给出以下信息:

  = 
 / \    
i   +   
   / \  
  2   3 
但这种简单的条件难道还不够吗

if (statement == variable_declaration){
    if (NotDeclaredInCurrentBlock(NameOfVariable)){
        // ...
    }
    else
        Throw "Error: The '" << NameOfVariable << "' variable is already declared";
}
if(语句==变量_声明){
if(未声明当前块(变量名称)){
// ...
}
其他的

抛出“错误:”您可以使用定制的调车场算法,这将产生如下中间结果:

<i> create_int <i> 2 3 + :=
code:
  push 0 ;id of <i>
  push 2
  push 3
  pop eax
  pop edx
  add eax, edx ; +
  push eax
  pop eax
  pop edx
  mov dword [ data + 4 * edx ], eax ; :=
  jmp finally
data:
  vars rd 1 ;number of variables, maximum variable-size is dword
create_int 2 3+:=
其中
是某种类型的标识符。您可以通过符号列表来实现这一点,您可以在其中查找现有符号的id,或者添加新符号,将当前计数器值作为id并递增此计数器

您可以将其转换为x86代码,如下所示:

<i> create_int <i> 2 3 + :=
code:
  push 0 ;id of <i>
  push 2
  push 3
  pop eax
  pop edx
  add eax, edx ; +
  push eax
  pop eax
  pop edx
  mov dword [ data + 4 * edx ], eax ; :=
  jmp finally
data:
  vars rd 1 ;number of variables, maximum variable-size is dword
代码:
推送0;id为
推2
推3
波普eax
波普edx
添加eax、edx+
推送eax
波普eax
波普edx
mov dword[数据+4*edx],eax;:=
最后是jmp
数据:
变量rd 1;变量数,最大变量大小为dword

正如您可能看到的,这将产生糟糕的代码,需要进一步优化。尽管如此,这段代码并没有使用ASt,而是使用基于堆栈的中间代码。

否。生成ASt对于创建编译器来说不是强制性的。请问下一个问题。好吧,我毫不怀疑您至少可以用30多年前的脏意大利面做一些事情代码。如果这是一个合理和有意识的方法,那就另当别论了。对于一个足够简单的语法和足够复杂的字节码,你可以在解析时直接生成字节码,但对输入代码进行几乎任何转换/分析都会变得复杂。强制要求?你是怎么想到这个主意的?通常在milli如何在计算机上解决特定任务的各种方法(如果至少有一种)但是只有一些是合理的,比如只有几十个或几百个想法。对于任何复杂的任务,比如编译器,从来没有一个银弹,最好的每一个方面。每个想法都有自己的优势。如果强烈建议AST,那么它可能适合很多场景,所以您需要一些特殊的要求或想法来避免,一个I’我以后不会后悔,但如果你只是问这是否是强制性的,那就回到算法研究上来吧…@immibis:再说一次,如果你的语法足够简单和明确(这是你无论如何都应该追求的目标)您可以直接动态生成字节码和伴随的结构;我们的产品中有一个完整的脚本语言。请参见
var
->下一个标记是变量声明,相应地修改与当前解析的范围相关联的堆栈框架。这不是不可能的,实际上很简单呃如果你的问题够简单的话。