先来编写一下语法, 并标记备选分支
语法文件
004/LabeledExpr.g4
grammar LabeledExpr;
import CommonLexerRules;
prog
: stat +
;
stat
: expr NEWLINE
| ID '=' expr NEWLINE
| NEWLINE
;
expr
: expr op=('*'|'/') expr
| expr op=('+'|'-') expr
| INT
| ID
| '(' expr ')'
;
MUL: '*' ;
DIV: '/' ;
ADD: '+' ;
SUB: '-' ;
词法文件
004/CommonLexerRules.g4
lexer grammar CommonLexerRules;
ID: [a-zA-Z]+ ;
INT: [0-9]+ ;
NEWLINE: '\r'? '\n' ;
WS: [ \t]+ -> skip ;
生成词法分析器、语法分析器以及访问器
antlr4vpy3 LabeledExpr.g4
编写自定义的访问器代码
004/EvalVisitor.py
from LabeledExprVisitor import LabeledExprVisitor
from LabeledExprParser import LabeledExprParser
class EvalVisitor(LabeledExprVisitor):
memory = {}
def visitAssign(self, ctx: LabeledExprParser.AssignContext):
id = ctx.ID().getText()
value = self.visit(ctx.expr())
self.memory[id] = value
return value
def visitPrintExpr(self, ctx:LabeledExprParser.PrintExprContext):
value = self.visit(ctx.expr())
print(value)
return 0
def visitInt(self, ctx:LabeledExprParser.IntContext):
return int(ctx.INT().getText())
def visitId(self, ctx:LabeledExprParser.IdContext):
id = ctx.ID().getText()
if id in self.memory:
return self.memory[id]
return 0
def visitMulDiv(self, ctx:LabeledExprParser.MulDivContext):
left = self.visit(ctx.expr(0))
right = self.visit(ctx.expr(1))
if ctx.op.type == LabeledExprParser.MUL:
return left * right
return left / right
def visitAddSub(self, ctx:LabeledExprParser.AddSubContext):
left = self.visit(ctx.expr(0))
right = self.visit(ctx.expr(1))
if ctx.op.type == LabeledExprParser.ADD:
return left + right
return left - right
def visitParens(self, ctx:LabeledExprParser.ParensContext):
return self.visit(ctx.expr())
编写应用的代码
004/calc.py
import sys
from antlr4 import *
from LabeledExprLexer import LabeledExprLexer
from LabeledExprParser import LabeledExprParser
from EvalVisitor import EvalVisitor
input_ = FileStream(sys.argv[1])
lexer = LabeledExprLexer(input_)
tokens = CommonTokenStream(lexer)
parser = LabeledExprParser(tokens)
tree = parser.prog()
eval = EvalVisitor()
eval.visit(tree)
测试文件
004/t.expr
193
a = 5
b = 6
a+b*2
(1+2)*3
测试
(venv) D:\PythonProjects\learnAntlr\004>python calc.py t.expr
193
17
9
|