问题描述
几天后,我开始为自己的项目使用ANTLR4,但我很难看到如何对访问者类进行单元测试。我的规则文件非常简单:
grammar Mmk_Expr;
import Mmk_Common_Grammar,Mmk_Keywords;
prog: stat+;
stat : MMK_SOURCES '=' NEWLINE* (CPP NEWLINE)+ # Sources
| MMK_HEADERS '=' NEWLINE* (HPP NEWLINE)+ # Headers
| MMK_DEPEND_ON '=' NEWLINE* (DIR_PATH NEWLINE)+ # Depends
| NEWLINE # blank
;
使用-visitor和-no-listener选项运行ANTLR4之后,ANTLR生成了一个访问者:
# Generated from Mmk_Expr.g4 by ANTLR 4.8
from antlr4 import *
if __name__ is not None and "." in __name__:
from .Mmk_ExprParser import Mmk_ExprParser
else:
from Mmk_ExprParser import Mmk_ExprParser
# This class defines a complete generic visitor for a parse tree produced by Mmk_ExprParser.
class Mmk_ExprVisitor(ParseTreeVisitor):
# Visit a parse tree produced by Mmk_ExprParser#prog.
def visitProg(self,ctx:Mmk_ExprParser.ProgContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by Mmk_ExprParser#Sources.
def visitSources(self,ctx:Mmk_ExprParser.sourcesContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by Mmk_ExprParser#Headers.
def visitHeaders(self,ctx:Mmk_ExprParser.HeadersContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by Mmk_ExprParser#Depends.
def visitDepends(self,ctx:Mmk_ExprParser.DependsContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by Mmk_ExprParser#blank.
def visitBlank(self,ctx:Mmk_ExprParser.BlankContext):
return self.visitChildren(ctx)
del Mmk_ExprParser
我继承了MMK_ExprVisitor并制成了Mmk_EvalVisitor:
from Mmk_ExprVisitor import Mmk_ExprVisitor
from Mmk_ExprParser import Mmk_ExprParser
from typing import Dict,List
class Mmk_EvalVisitor(Mmk_ExprVisitor):
def __init__(self):
self.__expr: Dict[str,List[str]] = {}
self.__name: str
self.__sourceFiles: List[str] = []
self.__headerFiles: List[str] = []
self.__directories: List[str] = []
def toDict(self):
return self.__expr
def visitSources(self,ctx: Mmk_ExprParser.sourcesContext):
#print(ctx.MMK_SOURCES)
self.__name = ctx.MMK_SOURCES().getText()
for file in ctx.CPP():
self.__sourceFiles.append(str(file))
self.__expr[self.__name] = self.__sourceFiles
def visitHeaders(self,ctx: Mmk_ExprParser.HeadersContext):
self.__name = ctx.MMK_HEADERS().getText()
for file in ctx.HPP():
self.__headerFiles.append(str(file))
self.__expr[self.__name] = self.__headerFiles
return 0
def visitDepends(self,ctx: Mmk_ExprParser.DependsContext):
self.__name = ctx.MMK_DEPEND_ON().getText()
for dirname in ctx.DIR_PATH():
self.__directories.append(str(dirname))
self.__expr[self.__name] = self.__directories
return 0
我的单元测试如下:
import unittest
from antlr4 import CommonTokenStream,InputStream
from Mmk_ExprLexer import Mmk_ExprLexer
from Mmk_ExprParser import Mmk_ExprParser
from Mmk_EvalVisitor import Mmk_EvalVisitor
class Test_EvalVisitor(unittest.TestCase):
def setup(self,inputText: str):
input_stream = InputStream(inputText)
lexer = Mmk_ExprLexer(input_stream)
stream = CommonTokenStream(lexer)
parser = Mmk_ExprParser(stream)
return parser
def test_visitSources(self):
visitor = Mmk_EvalVisitor()
expected = {"MMK_SOURCES": ["filename.cpp","ofilename.cpp"]}
parser = self.setup("\nMMK_SOURCES = filename.cpp \\"
"\n ofilename.cpp \\")
srcContext = parser.sourcesContext(parser,parser.prog())
visitor.visitSources(srcContext)
actual = visitor.toDict()
self.assertDictEqual(expected,actual)
def test_visitHeaders(self):
visitor = Mmk_EvalVisitor()
expected = {"MMK_HEADERS": ["filename.h","ofilename.h"]}
parser = self.setup("\nMMK_HEADERS = filename.h \\"
"\n ofilename.h \\")
HeadersContext = Mmk_ExprParser.HeadersContext(parser,parser.stat())
visitor.visitHeaders(HeadersContext)
actual = visitor.toDict()
self.assertDictEqual(expected,actual)
if __name__ == '__main__':
unittest.main()
但是我的测试不会通过:
E
======================================================================
ERROR: test_visitHeaders (test_Mmk_Parser.Test_EvalVisitor)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/fredrik/bin/mymake/frontend/mmk_rules/test_Mmk_Parser.py",line 37,in test_visitHeaders
visitor.visitHeaders(HeadersContext)
File "/home/fredrik/bin/mymake/frontend/mmk_rules/Mmk_EvalVisitor.py",line 25,in visitHeaders
self.__name = ctx.MMK_HEADERS().getText()
AttributeError: 'nonetype' object has no attribute 'getText'
======================================================================
ERROR: test_visitSources (test_Mmk_Parser.Test_EvalVisitor)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/fredrik/bin/mymake/frontend/mmk_rules/test_Mmk_Parser.py",line 24,in test_visitSources
visitor.visitSources(srcContext)
File "/home/fredrik/bin/mymake/frontend/mmk_rules/Mmk_EvalVisitor.py",line 18,in visitSources
self.__name = ctx.MMK_SOURCES().getText()
AttributeError: 'nonetype' object has no attribute 'getText'
----------------------------------------------------------------------
Ran 2 tests in 0.007s
Failed (errors=2)
在单元测试的设置中我缺少什么?我相信我在设置AST时做错了事,但是我不知道如何做。
谢谢。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)