对函数 AST 声明的抽象格式的混淆

Confusion over the abstract formatting of an AST declaration of functions

我正在使用 C++ 实现编程语言,即将进入 AST 生成阶段。

我想使用三步程序:

  1. 识别语句类型;
  2. 将左值、右值和节点中的标记与表达式分开,作为临时和本地 AST;
  3. 设计并添加到全局 AST。

下面是变量声明的示例:

var MyVar : integer = 8 + 2;

临时形式(右值/节点/左值):

left:
    -left:
         "MyVar"
    -node:
         ":"
    -right:
         "integer"
node:
     "="
right:
    -left:
         "8"
    -node:
         "+"
    -right:
         "2"

表示为经典 AST:

           "="
          /   \
         /     \
        /       \
      ":"       "+"
     /   \     /   \
    /     \  "8"   "2"
   /       \
"MyVar" "integer"

然后,将临时树添加到全局树中,指定声明的类型:

    [EXP]
      |
   VarDecl
      |
   { ... }

这适用于除函数声明和函数调用之外的所有内容:

func add(a : integer, b : integer) : integer;

add(8, 2);

确实,对于这种类型的表达式,没有节点来区分左值和右值。我也不知道如何表示函数参数。我想到了这样的事情:

left:
    "add"
    params:
        [
         -left:
              "a"
         -node:
              ":"
         -right:
               "integer"
        ]
        [
         -left:
              "b"
         -node:
              ":"
         -right:
               "integer"
        ]
node:
    ":"
right:
    "integer"

通话同上:

left:
    "add"
params:
    [
      "8"
    ]
    [
     "2"
    ]

但是我觉得这样做就没有逻辑了。

所以,我想知道是否有一种接近我的方法来改进它,或者是否必须完全修改我的方法。

PS: 我在抽象语法分析和树领域还很新,但是我已经阅读了很多关于这个主题的文档和教程。

首先,我建议研究 bison/flex 的 C++ 或其他解析器生成器,因为您可以更轻松地将语句分组到树结构中。

对于你的函数参数问题,AST 不只是右节点左。您可以在一个节点下有多个(> 2)个分支,并将这些分支视为它们的语法表达式而不是文字字符。这是词法分析器提供帮助的地方,因为您可以将字符抽象为标记,然后解析器会将标记抽象为语法结构。一般来说,像 a : integer 这样的东西应该被抽象成一个语法结构,可能称为类型化声明。

所以func add(a : integer, b : integer) : integer;真的是

func identifier(params) : returnType

并且AST中的节点可以跟踪特定信息。

即你的 AST 应该使用 'characters' 或 'tokens' 但内部节点应该是语言语法结构的抽象。特别是对于参数列表,我建议将其作为逗号分隔的类型声明列表,然后 params 节点将有一个子节点声明节点列表。

另外,根据你关于将语句添加到全局树的声明,将其视为将语句添加到 AST 的全局列表可能更有用。

总之有点奇怪的答案,希望对您有所帮助。