我试图了解访问者上下文在python 版本的 ANTLR4中的工作原理
我正在使用 Python3 语法,我试图访问"arith_expr">
有了这个输入示例x = 10 + 50 - 50 我在访问者中有这个上下文
len(ctx.term()) = 3
是atom [10,50,50]
的价值
len(ctx.ADD()) = 1
len(ctx.MINUS()) = 1
操作员的顺序是什么?
arith_expr
: term (('+'|'-') term)*
;
class Arith_exprContext(ParserRuleContext):
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
super().__init__(parent, invokingState)
self.parser = parser
def term(self, i:int=None):
if i is None:
return self.getTypedRuleContexts(MBIParser.TermContext)
else:
return self.getTypedRuleContext(MBIParser.TermContext,i)
def ADD(self, i:int=None):
if i is None:
return self.getTokens(MBIParser.ADD)
else:
return self.getToken(MBIParser.ADD, i)
def MINUS(self, i:int=None):
if i is None:
return self.getTokens(MBIParser.MINUS)
else:
return self.getToken(MBIParser.MINUS, i)
def getRuleIndex(self):
return MBIParser.RULE_arith_expr
def enterRule(self, listener:ParseTreeListener):
if hasattr( listener, "enterArith_expr" ):
listener.enterArith_expr(self)
def exitRule(self, listener:ParseTreeListener):
if hasattr( listener, "exitArith_expr" ):
listener.exitArith_expr(self)
def accept(self, visitor:ParseTreeVisitor):
if hasattr( visitor, "visitArith_expr" ):
return visitor.visitArith_expr(self)
else:
return visitor.visitChildren(self)
这是覆盖访客定义
def visitArith_expr(self, ctx:MBIParser.Arith_exprContext):
print(len(ctx.term())) #3
self.visit(ctx.term(0)) #10
self.visit(ctx.term(1)) #50
self.visit(ctx.term(2)) #50
print(len(ctx.ADD())) #1
print(len(ctx.MINUS())) #1
return self.visitChildren(ctx)
谢谢你的解释
您可以在列表中收集所有运算符,如下所示:
arith_expr
: term (operators+=('+'|'-') term)*
;
operators
是一个列表,包含所有运算符。然后,您可以在访问者中执行以下操作:
def visitArith_expr(self, ctx):
result = self.visit(ctx.term(0))
for i in range(len(ctx.operators)):
if ctx.operators[i].type == MBILexer.ADD:
result += self.visit(ctx.term(i + 1))
else:
result -= self.visit(ctx.term(i + 1))
return result
def visitTerm(self, ctx):
return int(ctx.getText())
或者更好的是,做这样的事情:
expr
: expr ('+' | '-') expr #add_expr
| term #term_expr
;
在这种情况下,访问者会变得容易得多:
# expr ('+' | '-') expr #add_expr
def visitAdd_expr(self, ctx):
if ctx.ADD() is not None:
return self.visit(ctx.expr(0)) + self.visit(ctx.expr(1))
return self.visit(ctx.expr(0)) - self.visit(ctx.expr(1))
# term #term_expr
def visitTerm_expr(self, ctx):
return self.visit(ctx.term())
def visitTerm(self, ctx):
return int(ctx.getText())