我已将下面的问题附在答案上。我的问题是我无法理解。您是否可以通过派生第一个表达式来详细说明解析树和ETF语法?
试着解释第一个表达式,a + b / c + d。我认为这并不难,但我一直无法找到合适的资源来理解这一点。你还可以提供解释ETF语法的资源吗?如果你不想给出解释,那么至少你可以指出一些资源来理解这一点会很好。作为一种策略,我认为最好先构建解析树,然后将其转换为AST。
答案 0 :(得分:1)
这是一个粗心的问题。 先验没有理由为什么ETF语法需要与任何特定的AST相对应。对于基于EFT语法的解析器来说,使用传统的优先级规则构建AST是最简单的。这样的左递归语法也很容易在AST中实现左关联运算。
但这些是一个很大的假设,这个问题应该明确说明。要完全指定问题,您需要提供一个产生AST的属性语法,而不仅仅是一个简单的语法。
属性语法将指定如何构建AST节点:
E_a -> E_b + T { E_a.ast = makeNode('+', E_b.ast, T.ast) }
E -> T { E.ast = T.ast }
...
F -> i { F.ast = makeLeaf(i) }
因此,如果我们假设一个典型的属性语法,那么EFT语法的结构意味着操作的优先级。
语法“顶部”的运算符 - 直接从起始符号派生 - 对应于最小优先级。你可以这样想:
E -> E + T | T
扩展为由T
运算符分隔的一个或多个+
个列表的列表。
E -> T + ... + T
这意味着属性语法构造了一个左倾的术语树(T
s)。 “在T
s内”发生的所有事情都优先于其他事物。那些东西“捆绑在一起”而不考虑周围的+
。
相应的AST将如下所示:
+
| \
+ T
| \
+ T
|
.
.
.
+
| \
T T
在单词中,表达式是添加到最后一个术语(右子树)的前面术语(根下的左子树)的总和。连续添加从左到右发生。这称为左关联操作。某些操作 - 例如通常取幂 - 使树以另一种方式倾斜,因此操作从右向左进行评估。 2^3^2
表示“2提高到9次幂”= 512而不是“8平方”= 64。
现在您可以扩展条款。在您的示例中,第一个术语最终扩展为a
。第二个扩展为F / F
,最后扩展为b / c
。 (这假设*
规则也适用于/
。)第三个术语扩展为d
。所以你最终得到了
+
| \
+ T
| \
T T
这就变成了
+__
| \
+ d
| \
a /
|\
b c
操作b/c
的优先级高于+
,因为它更接近树的叶子。
括号覆盖此自然优先级。表达式
(a + b) / c
最初只用一个词来扩展!
E -> T
-> T / F
-> F / F
第二个因素是c
。直观地说,树的形式如下:
/
| \
F c
现在,展开F
的关键属性语法规则是
F -> ( E ) { F.ast = E.ast }
所以我们真的有
/_______
| \
( E ) c
现在( E )
会自动扩展为a + b
的AST
/_______
| \
+ c
| \
a b
请注意+
如何离树叶更近。括号的优先级高于/
!