问题描述
首先我为这么长的帖子道歉。我正在尝试制作一个程序,我可以在其中输入一种称为 IMP 的简单编程语言并输出等效的 Python 代码。我为此建立了一个语法和一个自定义访问者。
到目前为止我尝试过的:
-当我在访问者中打印某些返回语句时,我可以“看到正确的结果”,但最终会出错,说 TypeError: must be str not None type.
-解析器也抛出错误:line 2:7 mismatched input
。
-在 ANTLR4 生成的词法分析器文件中,有一个导入语句: from typing.io import TextIO 和 pyCharm 说 TextIO 是未解析的引用。
我还阅读了几篇堆栈溢出的帖子,但似乎找不到答案。我的直觉是我需要在 ImpToPython 脚本中做一些调整。
以下是错误的更详细信息:
line 2:7 mismatched input '<EOF>' expecting {'skip','if','while',VAR}
Traceback (most recent call last):
File "C:/Users/enter/PycharmProjects/grammars/imp_to_python.py",line 36,in <module>
main(sys.argv)
File "C:/Users/enter/PycharmProjects/grammars/imp_to_python.py",line 28,in main
transVisitor = visitor.visit(tree)
File "C:\Users\enter\PycharmProjects\grammars\venv\lib\site-packages\antlr4\tree\Tree.py",line 34,in visit
return tree.accept(self)
File "C:\Users\enter\PycharmProjects\grammars\gen\impParser.py",line 759,in accept
return visitor.visitSequence(self)
File "C:\Users\enter\PycharmProjects\grammars\gen\impVisitor.py",line 111,in visitSequence
return self.visit(ctx.first) + self.visit(ctx.second)
TypeError: must be str,not nonetype
这是我写的语法:
grammar imp;
aexp : INT #Atom
| VAR #Variable
| '(' inner=aexp ')' #Brackets
| left=aexp '*' right=aexp #Mult
| left=aexp '-' right=aexp #Sub
| left=aexp '+' right=aexp #Add
;
bexp : 'true' #True
| 'false' #False
| left=aexp '=' right=aexp #Equal
| left=aexp '<' right=aexp #Smaller
| left=aexp '>' right=aexp #Greater
| left=aexp '<>' right=aexp #Inequality
| 'not' inner=bexp #Not
| '(' left=bexp 'and' right=bexp ')' #And
| '(' left=bexp 'or' right=bexp ')' #Or
;
cmd : 'skip' #Skip
| variable=VAR ':=' expression=aexp #Assignment
| first=cmd ';' second=cmd #Sequence
| 'if' condition=bexp 'then' truecase=cmd 'else' falsecase=cmd 'fi' #If
| 'while' condition=bexp 'do' body=cmd 'od' #While
;
VAR : [a-zA-Z][a-zA-Z0-9_]* ;
INT : [0-9]+ ;
WS : [ \r\n\t] -> skip ;
这是自定义访问者:
# Generated from C:/Users/enter/PycharmProjects/grammars\imp.g4 by ANTLR 4.9.1
from antlr4 import *
if __name__ is not None and "." in __name__:
from .impParser import impParser
else:
from .impParser import impParser
# This class defines a visitor for a parse tree produced by impParser.
class impVisitor(ParseTreeVisitor):
#a place to store our variable names for assignments
global variableNames;
variableNames = set()
'''
starting with the arithemtic expressions aexp
'''
# Visit a parse tree produced by impParser#Atom.
def visitAtom(self,ctx:impParser.AtomContext):
return ctx.getText()
# Visit a parse tree produced by impParser#Variable.
def visitvariable(self,ctx:impParser.VariableContext):
return 'p_' + ctx.getText()
# Visit a parse tree produced by impParser#Brackets.
def visitBrackets(self,ctx:impParser.BracketsContext):
return '(' + self.visit(ctx.inner) + ')'
# Visit a parse tree produced by impParser#Mult.
def visitMult(self,ctx:impParser.MultContext):
return self.visit(ctx.left) + '*' + self.visit(ctx.right)
# Visit a parse tree produced by impParser#Sub.
def visitSub(self,ctx:impParser.SubContext):
return self.visit(ctx.left) + '-' + self.visit(ctx.right)
# Visit a parse tree produced by impParser#Add.
def visitAdd(self,ctx:impParser.AddContext):
return self.visit(ctx.left) + '+' + self.visit(ctx.right)
'''
Now we can define the visitors for the boolean expressions
'''
# Visit a parse tree produced by impParser#True.
def visitTrue(self,ctx:impParser.TrueContext):
return 'True'
# Visit a parse tree produced by impParser#False.
def visitFalse(self,ctx:impParser.FalseContext):
return 'False'
# Visit a parse tree produced by impParser#Equal.
def visitEqual(self,ctx:impParser.EqualContext):
return '(' + self.visit(ctx.left) + '==' + self.visit(ctx.right) + ')'
# Visit a parse tree produced by impParser#Smaller.
def visitSmaller(self,ctx:impParser.SmallerContext):
return '(' + self.visit(ctx.left) + '<' + self.visit(ctx.right) + ')'
# Visit a parse tree produced by impParser#Greater.
def visitGreater(self,ctx:impParser.GreaterContext):
return '(' + self.visit(ctx.left) + '>' + self.visit(ctx.right) + ')'
# Visit a parse tree produced by impParser#Inequality.
def visitInequality(self,ctx:impParser.InequalityContext):
return '(' + self.visit(ctx.left) + ' != ' + self.visit(ctx.right) + ')'
# Visit a parse tree produced by impParser#Not.
def visitNot(self,ctx:impParser.NotContext):
return '(' + 'not ' + self.visit(ctx.inner) + ')'
# Visit a parse tree produced by impParser#And.
def visitAnd(self,ctx:impParser.AndContext):
return '(' + self.visit(ctx.left) + ' and ' + self.visit(ctx.right) + ')'
# Visit a parse tree produced by impParser#Or.
def visitOr(self,ctx:impParser.OrContext):
return '(' + self.visit(ctx.left) + ' or ' + self.visit(ctx.right) + ')'
'''
finally the commands
'''
# Visit a parse tree produced by impParser#Skip.
def visitSkip(self,ctx:impParser.SkipContext):
return '\n'
# Visit a parse tree produced by impParser#Assignment.
def visitAssignment(self,ctx:impParser.AssignmentContext):
variableNames.add(ctx.variable.text)
return 'p_' + ctx.variable.text + '=' + self.visit(ctx.expression) + '\n'
# Visit a parse tree produced by impParser#Sequence.
def visitSequence(self,ctx:impParser.SequenceContext):
return self.visit(ctx.first) + self.visit(ctx.second)
# Visit a parse tree produced by impParser#If.
def visitIf(self,ctx:impParser.IfContext):
return 'if (' + self.visit(ctx.condition) + '): \n ' + self.visit(ctx.truecase) + 'else: \n ' + self.visit(ctx.falsecase) + '\n'
# Visit a parse tree produced by impParser#While.
def visitWhile(self,ctx:impParser.WhileContext):
return 'while (' + self.visit(ctx.condition) + '): \n ' + self.visit(ctx.body)
del impParser
这是 ImpToPython 程序:
import sys
from antlr4 import *
from gen.impLexer import impLexer
from gen.impParser import impParser
from gen.impVisitor import impVisitor
def main(argv):
#take the input of the file
Input = FileStream(argv[1])
lexer = impLexer(Input)
stream = CommonTokenStream(lexer)
parser = impParser(stream)
tree = parser.cmd()
visitor = impVisitor()
transVisitor = visitor.visit(tree)
print(transVisitor)
if __name__ == '__main__':
main(sys.argv)
输入文件:
X := 1;
Y := 2;
预期输出:
p_X=1
p_Y=2
这感觉就像是信息的大脑转储。如果我需要澄清任何事情或者我是否可以提供更多信息,请告诉我。让我提前说声非常感谢您花时间阅读本文,更不用说花时间回答我了:)
注意安全
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)