imp后的ANTLR4语法标记识别错误

2024-06-09 06:36:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用来自GitHub的antlr4的parser grammarlexer grammar来解析Python3中的PHP。在

当我直接使用这些语法时,我的PoC代码起作用:

安特尔-测试.py在

from antlr4 import *
# from PHPParentLexer import PHPParentLexer
# from PHPParentParser import PHPParentParser
# from PHPParentParser import PHPParentListener

from PHPLexer import PHPLexer as PHPParentLexer
from PHPParser import PHPParser as PHPParentParser
from PHPParser import PHPParserListener as PHPParentListener


class PhpGrammarListener(PHPParentListener):
    def enterFunctionInvocation(self, ctx):
        print("enterFunctionInvocation " + ctx.getText())


if __name__ == "__main__":
    scanner_input = FileStream('test.php')
    lexer = PHPParentLexer(scanner_input)
    stream = CommonTokenStream(lexer)
    parser = PHPParentParser(stream)
    tree = parser.htmlDocument()
    walker = ParseTreeWalker()
    printer = PhpGrammarListener()
    walker.walk(printer, tree)

它给出了输出

^{pr2}$

当我使用以下PHPParent.g4语法时,会出现很多错误:

grammar PHPParent;
options { tokenVocab=PHPLexer; }
import PHPParser;

在交换了pythons导入的注释之后,我得到了这个错误

/opt/local/bin/python3.4 /Users/d/PycharmProjects/name/antlr-test.py
line 1:1 token recognition error at: '?'
line 1:2 token recognition error at: 'p'
line 1:3 token recognition error at: 'h'
line 1:4 token recognition error at: 'p'
line 1:5 token recognition error at: '\n'
...
line 2:8 no viable alternative at input '<('
line 2:14 mismatched input ';' expecting {<EOF>, '<', '{', '}', ')', '?>', 'list', 'global', 'continue', 'return', 'class', 'do', 'switch', 'function', 'break', 'if', 'for', 'foreach', 'while', 'new', 'clone', '&', '!', '-', '~', '@', '$', <INVALID>, 'Interface', 'abstract', 'static', Array, RequireOperator, DecimalNumber, HexNumber, OctalNumber, Float, Boolean, SingleQuotedString, DoubleQuotedString_Start, Identifier, IncrementOperator}
line 3:28 mismatched input ';' expecting {<EOF>, '<', '{', '}', ')', '?>', 'list', 'global', 'continue', 'return', 'class', 'do', 'switch', 'function', 'break', 'if', 'for', 'foreach', 'while', 'new', 'clone', '&', '!', '-', '~', '@', '$', <INVALID>, 'Interface', 'abstract', 'static', Array, RequireOperator, DecimalNumber, HexNumber, OctalNumber, Float, Boolean, SingleQuotedString, DoubleQuotedString_Start, Identifier, IncrementOperator}
line 4:28 mismatched input ';' expecting {<EOF>, '<', '{', '}', ')', '?>', 'list', 'global', 'continue', 'return', 'class', 'do', 'switch', 'function', 'break', 'if', 'for', 'foreach', 'while', 'new', 'clone', '&', '!', '-', '~', '@', '$', <INVALID>, 'Interface', 'abstract', 'static', Array, RequireOperator, DecimalNumber, HexNumber, OctalNumber, Float, Boolean, SingleQuotedString, DoubleQuotedString_Start, Identifier, IncrementOperator}

然而,当我在语法上运行antlr4工具时,没有出现错误。我被难住了-是什么引起了这个问题?在

$ a4p PHPLexer.g4
warning(146): PHPLexer.g4:363:0: non-fragment lexer rule DoubleQuotedStringBody can match the empty string
$ a4p PHPParser.g4
warning(154): PHPParser.g4:523:0: rule doubleQuotedString contains an optional block with at least one alternative that can match an empty string
$ a4p PHPParent.g4
warning(154): PHPParent.g4:523:0: rule doubleQuotedString contains an optional block with at least one alternative that can match an empty string

Tags: fromimporttokeninputlineerroratclass
1条回答
网友
1楼 · 发布于 2024-06-09 06:36:14

进口有点混乱。在

首先,tokenVocab无法生成所需的lexer。它只表示此语法使用PHPLexer的标记。{cd3>即使你不编译也不会删除!在

看看PHPParser.g4,这里我们也使用了options { tokenVocab=PHPLexer; }。但是在python脚本中,我们仍然需要使用来自PHPLexer的lexer来使其工作。嗯,这个PHPParentLexer根本不可用。这就是为什么你得到所有的错误。在

要从组合语法生成新的lexer,需要如下导入:

grammar PHPParent;
import PHPLexer;

但是,导入时不支持modePHPLexer本身使用mode很多。所以这也不是一个选择。在

我们可以简单地用PHPParentLexer替换PHPLexer?遗憾的是,没有。因为PHPParentParser是由PHPParentLexer生成的,它们是紧密耦合的,不能单独使用。如果使用PHPLexerPHPParentParser也不起作用。至于这个语法,由于错误恢复,它实际上是有效的,但是会产生一些错误。在

似乎没有更好的办法,只能重写一些语法。在ANTLR4的这个import部分中肯定存在一些设计问题。在

相关问题 更多 >