Antlr系列(配合Python3)文章:https://www.jianshu.com/nb/32570686
Visitor实现四则运算的计算 文法规则文件Expr.g4
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 grammar Expr; prog: expr NEWLINE # printExpr; expr: left=expr op=('*'|'/') right=expr # mulDiv // 用来确定优先级,在上面的优先级高 | left=expr op=('+'|'-') right=expr # addSub | INT # int | '(' expr ')' # brackets ; NEWLINE : [\r\n]+ ; INT : [0-9]+ ; MUL : '*' ; // 用来便于当作常量引用 DIV : '/' ; ADD : '+' ; SUB : '-' ;
在执行antlr4的时候需要指明-no-listener
和-visitor
,因此执行antlr4 -no-listener -visitor -Dlanguage=Python3 Expr.g4
创建文件Expr.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import sysfrom antlr4 import *from ExprLexer import ExprLexerfrom ExprParser import ExprParserfrom ExprVisitor import ExprVisitor class ExprCalculateVisitor (ExprVisitor ): def visitPrintExpr (self, ctx ): val = self.visit(ctx.expr()) print (val) return val def visitBrackets (self, ctx ): return self.visit(ctx.expr()) def visitAddSub (self, ctx ): if ctx.op.type == ExprParser.ADD: return self.visit(ctx.left) + self.visit(ctx.right) else : return self.visit(ctx.left) - self.visit(ctx.right) def visitMulDiv (self, ctx ): if ctx.op.type == ExprParser.MUL: return self.visit(ctx.left) * self.visit(ctx.right) else : return self.visit(ctx.left) / self.visit(ctx.right) def visitInt (self, ctx ): return int (ctx.getText()) def main (): lexer = ExprLexer(StdinStream()) stream = CommonTokenStream(lexer) parser = ExprParser(stream) tree = parser.prog() calculator = ExprCalculateVisitor() calculator.visitPrintExpr(tree) if __name__ == '__main__' : main()
这里的visitXXX的XXX部分都是上面#后的内容;如果不写#后的东西,就会是visitProg之类的
之后仍然是运行并且输入后回车输入EOF(Ctrl-D/Ctrl-Z)即可看到结果输出