Python 中的 Antlr4 语法错误和客户访问者错误

问题描述

首先我为这么长的帖子道歉。我正在尝试制作一个程序,我可以在其中输入一种称为 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 (将#修改为@)