我在空闲时间里尝试解析,想要实现一个非常简单语法的移位-规约解析器。我阅读了许多在线文章,但仍然不清楚如何创建解析树。以下是我想做的一个示例:
语法:
Expr -> Expr TKN_Op Expr
Expr -> TKN_Num
这是一个示例输入:
1 + 1 + 1 + 1
经过标记化后,变成:
TKN_Num TKN_Op TKN_Num TKN_Op TKN_Num TKN_Op TKN_Num
我理解:
- 移进 意味着将第一个输入符号推到堆栈上并从输入中删除它
- 规约 意味着用文法元素替换堆栈上的一个或多个元素
所以,基本上应该发生这样的情况:
Step 1:
Stack:
Input: TKN_Num TKN_Op TKN_Num TKN_Op TKN_Num TKN_Op TKN_Num
What: Stack is empty. Shift.
Step 2:
Stack: TKN_Num
Input: TKN_Op TKN_Num TKN_Op TKN_Num TKN_Op TKN_Num
What: TKN_Num can be reduced to Expr. Reduce.
Step 3:
Stack: Expr
Input: TKN_Op TKN_Num TKN_Op TKN_Num TKN_Op TKN_Num
What: Cannot reduce. Shift.
Step 4:
Stack: Expr TKN_Op
Input: TKN_Num TKN_Op TKN_Num TKN_Op TKN_Num
What: Cannot reduce. Shift.
Step 5:
Stack: Expr TKN_Op TKN_Num
Input: TKN_Op TKN_Num TKN_Op TKN_Num
What: TKN_Num can be reduced to Expr. Reduce.
// What should I check for reduction?
// Should I try to reduce incrementally using
// only the top of the stack first,
// then adding more stack elements if I couldn't
// reduce the top alone?
Step 6:
Stack: Expr TKN_Op Expr
Input: TKN_Op TKN_Num TKN_Op TKN_Num
What: Expr TKN_Op Expr can be reduced to Expr. Reduce.
Step 7:
Stack: Expr
Input: TKN_Op TKN_Num TKN_Op TKN_Num
What: ...
// And so on...
除了“要减少什么?”的疑问,我不知道如何正确地构建解析树。该树可能应该像这样:
1 + o
|
1 + o
|
1 + 1
在减少时,我应该创建一个新节点吗?
何时应该给新创建的节点添加子节点/何时应该创建新的根节点?