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

如何解决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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?