当前位置: 首页 > 知识库问答 >
问题:

导入后出现ANTLR4语法标记识别错误

王鹏飞
2023-03-14

我正在使用GitHub提供的antlr4语法分析器和词法分析器来解析Python3中的PHP。

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

antlr试验。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)

这给出了输出

/opt/local/bin/python3.4 /Users/d/PycharmProjects/name/antlr-test.py
enterFunctionInvocation echo("hi") 
enterFunctionInvocation another_method("String")
enterFunctionInvocation print("print statement")

Process finished with exit code 0

当我使用以下PHP时。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

共有1个答案

杨阳飇
2023-03-14

导入是ANTLR4有点乱。

首先,tokenVocab无法生成所需的lexer。这只是意味着该语法使用了PHPLexer的标记。如果删除PHPLexer。令牌,它甚至不会编译!

看看PHPParser. g4,我们也在其中使用选项{TokenSingab=PHPLexer;}。然而在python脚本中,我们仍然需要使用PHPLexer中的lexer才能使其工作。好吧,这个PHPParentLexer根本不可用。这就是你得到所有错误的原因。

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

grammar PHPParent;
import PHPLexer;

但是,导入时不支持模式pPlexer本身经常使用模式。所以这也不是一个选择。

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

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

 类似资料:
  • 我需要antlr4来解析一些简单的HTML文件。我已经将语法分为解析器语法和lexer语法,这样我就可以对标记内部的东西( )使用孤岛语法,如“确定的ANTLR4引用”中所述。antlr4反复告诉我“令牌识别错误”。 解析器语法: 示例HTML文件: ANTLR4的输出:

  • 我正在尝试创建一个语法来解析Solr查询(只需要稍微相关,您不需要了解任何关于Solr的信息来回答这个问题--只需要比我了解更多关于ANTLR4.7的信息就可以了)。我将它建立在Solr6中的QueryParser.jj文件的基础上。我找了一个现存的,但似乎没有一个不是旧的和过时的。 我被困住了,因为当我尝试运行解析器时,我得到了“token recognition error”。 我创建的lex

  • 我正在为一个班级做一个应用程序,教授和我一样困惑为什么它不起作用。我有2个js文件和一个html。我将一个数组从一个js导出到另一个,然后在我的html中使用那个js作为src。以下是相关代码: 医疗名单。js: main.js: HTML: 下面是我得到的错误: main.js: 1未捕获的语法错误:意外令牌{ 我尝试在脚本标记中使用type="模块",但是当我尝试使用main.js中声明的函数

  • 我本打算在我的代码下设置狗的高度,但它用上面的错误标记了它。是否有任何修复方法,是否缺少任何{}im? 就像代码差不多完成了一样,我检查了所有代码,它工作了,并尝试添加狗的高度,但它抛出了语法错误 错误出现在第28到31行,代码如下

  • 我对编码有点陌生,不明白为什么会出现这种情况。谁来帮帮我。 导入java.util.scanner; 类calculateMortgageA{public static void main(String[]args){ } 公共静态double calcmortgage(double salaryOne,double salaryTwo } }

  • 我现在得到了... lexer语法的导入似乎正在加载。以下文件提供了该问题。 AQLCommentTest.G4 如何检查是否以及如何实际应用了antlr4导入语句?