核心
循环代替左递归。
代码
以前:
'''
语法解析:加法表达式
'''
def additive(self, tokens):
child1 = self.multiplicative(tokens)
node = child1
token = tokens.peek()
if (child1 != None and token != None):
if (token.token_type == TokenType.Plus or token.token_type == TokenType.Minus):
token = tokens.read()
child2 = self.additive(tokens)
if (child2 != None):
node = SimpleASTNode(ASTNodeType.Additive, token.token_text)
node.addChild(child1)
node.addChild(child2)
else:
raise "invalid additive expression, expecting the right part."
return node
现在
'''
语法解析:加法表达式
'''
def additive(self, tokens):
child1 = self.multiplicative(tokens) # 应用add规则
node = child1
if (child1 != None):
while True: # 循环应用add'
token = tokens.peek()
if (token != None and (token.token_type == TokenType.Plus or token.token_type == TokenType.Minus)):
token = tokens.read() # 读出加号
child2 = self.multiplicative(tokens) # 计算下级节点
node = SimpleASTNode(ASTNodeType.Additive, token.token_text)
node.addChild(child1) # 注意,新节点在顶层,保证正确的结合性
node.addChild(child2)
child1 = node
else:
break
return node
结果
以前:
计算: 2+3+4,结合性出现错误。
@ASTNodeType.Programm Calculator
@ ASTNodeType.Additive +
@ ASTNodeType.IntLiteral 2
@ ASTNodeType.Additive +
@ ASTNodeType.IntLiteral 3
@ ASTNodeType.IntLiteral 4
| Calculating: ASTNodeType.Programm
| Calculating: ASTNodeType.Additive
| Calculating: ASTNodeType.IntLiteral
| Result: 2
| Calculating: ASTNodeType.Additive
| Calculating: ASTNodeType.IntLiteral
| Result: 3
| Calculating: ASTNodeType.IntLiteral
| Result: 4
| Result: 7
| Result: 9
| Result: 9
现在
计算: 2+3+4
@ASTNodeType.Programm Calculator
@ ASTNodeType.Additive +
@ ASTNodeType.Additive +
@ ASTNodeType.IntLiteral 2
@ ASTNodeType.IntLiteral 3
@ ASTNodeType.IntLiteral 4
| Calculating: ASTNodeType.Programm
| Calculating: ASTNodeType.Additive
| Calculating: ASTNodeType.Additive
| Calculating: ASTNodeType.IntLiteral
| Result: 2
| Calculating: ASTNodeType.IntLiteral
| Result: 3
| Result: 5
| Calculating: ASTNodeType.IntLiteral
| Result: 4
| Result: 9
| Result: 9
课程:https://time.geekbang.org/column/article/120388
代码:https://github.com/buyouran1/PlayWithCompiler