首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >导入后ANTLR4语法标记识别错误

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

Stack Overflow用户
提问于 2015-04-14 22:28:43
回答 1查看 1.9K关注 0票数 17

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

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

antlr-test.py

代码语言:javascript
复制
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)

它给出了输出

代码语言:javascript
复制
/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

当我使用下面的PHPParent.g4语法时,我得到了很多错误:

代码语言:javascript
复制
grammar PHPParent;
options { tokenVocab=PHPLexer; }
import PHPParser;

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

代码语言:javascript
复制
/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工具时,我没有得到任何错误。我被难住了--是什么导致了这个问题?

代码语言:javascript
复制
$ 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-30 12:39:58

Import is ANTLR4有点凌乱。

首先,tokenVocab不能生成你需要的词法分析器。它只是意味着这个语法使用了PHPLexer的标记。如果你删除了PHPLexer.tokens,它甚至不能编译!

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

要从组合语法中生成新的词法分析器,您需要像这样导入它:

代码语言:javascript
复制
grammar PHPParent;
import PHPLexer;

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

我们能简单地用PHPLexer取代PHPParentLexer吗?遗憾的是,没有。因为PHPParentParser是用PHPParentLexer生成的,所以它们是紧密耦合的,不能单独使用。如果你使用PHPLexerPHPParentParser也不能工作。至于这个语法,多亏了错误恢复,它实际上是有效的,但会产生一些错误。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29630026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档