抽象树对解析器树

时间:2012-11-18 16:44:02

标签: c++ parsing boost abstract-syntax-tree boost-spirit

我需要你的意见,以便选择生成解析器树(ST)或生成抽象语法树(AST)之间的最佳选择。背景是:

我想解析像C这样的语言(只是C的一个子集,带有一些更改,使其更加面向伪代码),但不是为了在其他输出语言/文件中翻译它,而是为了动画执行它的句子它的执行过程(我使用Qt绘制)。此C子集的一个功能是它启用嵌套范围。我对ST和AST之间选举的疑问来自于符号表。一般的想法是(使用Boost.spirit):

  1. 通过自定义Boost.spirit解析器解析源代码文件。
  2. 语义动作产生一个语法树,只是源代码语法树的副本(或者也是Boost.spirit内部语法树的副本,但是有我自己的类和结构)。因此,没有AST。
  3. 手中有这个ST,程序会自上而下地读取这个语法树,如下所示:
    1. 执行第一句话。
    2. 使用新的(句子结果)值上传符号表。
    3. 将符号表的实际状态保存在程序状态堆栈中。
    4. 至3.1直到ST完全处理。
    5. 为算法读取和绘制程序状态堆栈设置动画。
  4. 两个推理:

    1. 如果我使用AST,我在解析后丢失了有关变量声明,其类型等的信息。因此,我必须通过解析器的语义操作来处理符号表,使解析器的编写和理解变得复杂。此外,我必须一直使用带有所有变量的符号表,而不管实际范围(如果我在范围i中,只需要范围i,i-1,....,1;不整个算法的所有范围)。这花费了记忆。
    2. 在程序状态堆栈中,我只需要实际和先前范围的变量,以免通过动画使算法的可理解性变得复杂。如果我使用ST,我必须删除所有不需要的符号,然后将其保存在堆栈中。花费时间。
    3. 具有控制范围的静态符号表比动态符号表更难设计和使用。静态符号表必须具有每个范围的标识符(例如),并将树的每个节点与每个标识符相关联。动态符号表更容易工作,因为如果我在范围i中,只需要两个“向量”(可能是一个双队列和一个堆栈):

      • 包含符号及其相关信息的容器(双队列?):容器中的最后一个变量是最近的声明变量。
      • 整数的容器(堆栈),显示每个范围的开头(双队列的索引)。

      例如,对于范围i:

      • 容器1:[x y z x a b z f a z]
      • 容器2:[0 3 6 8]

      如果我离开范围i,只需要擦除最后一个整数以及从位置8到结尾的符号。树保持不变。

    4. 由于我必须在执行时执行每个句子,因此ST便于执行。

    5. 两个问题:

      1. 哪个更好呢?
      2. 存在任何形式以提取Spirit的内部树或自定义它以便不复制它?

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找的是一个抽象语义图(ASG),它代表程序的语义(而不是语法)。你能做的是:

  1. 将源解析为AST,然后
  2. 将AST转换为ASG,最后
  3. 走ASG执行实际代码。
  4. 另外,我会说你可以确实构建一个没有抽象的AST;例如,我目前正在构建自己的脚本语言解释器,AST将包含变量名称(这对调试解析器/解释器以及解析的程序本身也很有用)。