对AST函数声明的抽象格式的困惑

时间:2018-08-13 13:15:58

标签: c++ compiler-construction abstract-syntax-tree language-theory

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

我想使用3个步骤:

  1. 识别陈述的类型;
  2. 在左值右值和节点中将表达式中的标记与临时AST和本地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:在抽象语法分析和树的领域,我还是一个新手,但是我已经阅读了很多有关此主题的文档和教程。

1 个答案:

答案 0 :(得分:3)

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

对于您的功能参数问题,AST不仅位于左侧的右节点。您可以在一个节点下具有多个(> 2)分支,并将这些分支视为其语法表达式而不是文字字符。在这里,词法分析器可以提供帮助,因为您可以将字符抽象为令牌,然后解析器会将令牌抽象为语法结构。通常,像a : integer之类的东西都应该抽象为语法结构,可能称为类型化声明。

所以func add(a : integer, b : integer) : integer;确实是

func identifier(params) : returnType

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

也就是说,您的AST应该使用“字符”或“令牌”,但内部节点应该抽象该语言的语法结构。特别是对于参数列表,我建议将其作为逗号分隔的类型声明列表,然后params节点将具有子级声明节点列表。

从您还将语句添加到全局树的陈述中,将其视为将语句添加到AST的全局列表中可能会更有用。

无论如何,这是一个很奇怪的答案,希望对您有所帮助。