Syntax 如何为a*(b+;c)*d创建抽象语法树

Syntax 如何为a*(b+;c)*d创建抽象语法树,syntax,compiler-construction,tree,abstract,abstract-syntax-tree,Syntax,Compiler Construction,Tree,Abstract,Abstract Syntax Tree,我不知道如何表示AST中的括号。我知道如何制作解析树,一位朋友告诉我AST不会包含括号,我无法从任何文本中验证这一点,你的朋友是对的,抽象语法树不会包含括号。括号仅控制树的结构,它们本身不显示在树中 因此a*(b+c)将创建一个树,其中a是*的左子树,右子树是另一个子树,其中b和c是+的子树。鉴于a*b+c和(a*b)+c都将创建一个根为+的树,*与子a和b是+的左子级,c是+的右子级 我无法从任何文本中验证 从抽象语法树上的: 该语法是“抽象”的,不能代表真实语法中出现的每个细节。例如,分组括

我不知道如何表示AST中的括号。我知道如何制作解析树,一位朋友告诉我AST不会包含括号,我无法从任何文本中验证这一点,你的朋友是对的,抽象语法树不会包含括号。括号仅控制树的结构,它们本身不显示在树中

因此
a*(b+c)
将创建一个树,其中
a
*
的左子树,右子树是另一个子树,其中
b
c
+
的子树。鉴于
a*b+c
(a*b)+c
都将创建一个根为
+
的树,
*
与子
a
b
+
的左子级,
c
+
的右子级

我无法从任何文本中验证

从抽象语法树上的:

该语法是“抽象”的,不能代表真实语法中出现的每个细节。例如,分组括号在树结构中是隐式的


AST的标准智慧是它们不包含表达式中的括号。 这实际上只是品味的问题。你可以用任何一种方法

抽象的要点是省略了一些细节

人们可能会决定删除括号以外的其他细节;您仍然会得到一个抽象语法树。例如,如果采用完全具体的语法树,并删除所有具有固定拼写的终端节点(包括“+”、“if”和“(”),则可以得到一个很好的抽象语法树

我构建了一个程序分析和转换工具,可以从原始语法自动进行这种抽象(以及其他一些抽象)。它有一些非常好的好处:

  • 从语法构建解析器时,您可以自动构建AST,而无需手动编写任何代码。在构建和维护大型语法(如C++14和IBM COBOL)时,这一点非常重要。是的,树中会显示一个(…)节点,但“('和')”的具体标记不会显示

  • 自动从AST重新生成源文本更容易。如果不保留括号节点,则在预打印时恢复插入括号节点的位置需要花费一些精力

  • 如果您使用感兴趣的langauge的表面语法编写模式和代码转换(我们就是这么做的),那么无论如何您都要用括号来编写它们。而且matcher不关心是否必须匹配“额外”节点。因此,在使用树时,这基本上不是问题。(偶尔我们会编写删除嵌套括号的规则,但编写起来非常简单)