为什么这个语法无法解析这个输入?

时间:2016-01-17 10:15:03

标签: parsing antlr4

我定义了一种小语言和Antlr4的语法。这个想法是用那种语言,有一个关键词"功能"可用于定义函数或定义参数时的类型说明符。我希望能够做到这样的事情:

function aFunctionHere(int a, function callback) ....

然而,似乎Antlr并不喜欢我使用" function"在两个不同的地方。据我所知,语法甚至不含糊。

在下面的语法中,如果我删除LINE 1,生成的解析器会解析样本输入而不会出现问题。此外,如果我更改LINE 2或LINE 3中的标记字符串,以使它们不相等,则解析器可以正常工作。

我用语法得到的错误是:

  

第1行:0输入不匹配'功能'期待< INVALID>

"期待什么< INVALID>"意思?

(精简)语法:

grammar test;

begin : function ;

function: FUNCTION IDENTIFIER '(' parameterlist? ')' ;

parameterlist: parameter (',' parameter)+ ;

parameter: BaseParamType IDENTIFIER ;

// Lexer stuff

BaseParamType:
      INT_TYPE
    | FUNCTION_TYPE // <---- LINE 1
    ;

FUNCTION : 'function'; // <---- LINE 2

INT_TYPE : 'int';
FUNCTION_TYPE : 'function'; // <---- LINE 3

IDENTIFIER : [a-zA-Z_$]+[a-zA-Z_$0-9]*;

WS : [ \t\r\n]+ -> skip ;

输入我使用:

  

function abc(int c,int d,int a)

测试生成的解析器的程序:

from antlr4 import *
from testLexer import testLexer as Lexer
from testParser import testParser as Parser
from antlr4.tree.Trees import Trees

def main(argv):
    input = FileStream(argv[1] if len(argv)>1 else "test.in")
    lexer =  Lexer(input)
    tokens = CommonTokenStream(lexer)
    parser = Parser(tokens)

    tree = parser.begin()

    print Trees.toStringTree(tree, None, parser)


if __name__ == '__main__':
    import sys
    main(sys.argv)

1 个答案:

答案 0 :(得分:1)

只需为令牌function使用一个名称。

令牌只是一个令牌。单独查看function,无法确定它是FUNCTION还是FUNCTION_TYPE。由于FUNCTION在文件中排在第一位,因此lexer使用的是FUNCTION_TYPE。这使得无法匹配function,因此成为无效的令牌类型。

解析器将找出令牌BaseParamType的语法角色。因此,对于相同的令牌,使用两个不同的词法描述符是没有意义的,即使它是可能的。

在OP中的语法中,function也是一种词法类型,它将吸收令牌FUNCTION的所有用法,从而阻止function在{baseParamType的制作中被识别1}}。将其名称更改为grammar test; begin : function ; function: FUNCTION IDENTIFIER '(' parameterlist? ')' ; parameterlist: parameter (',' parameter)+ ; parameter: baseParamType IDENTIFIER ; // Lexer stuff baseParamType: INT_TYPE | FUNCTION // ; FUNCTION : 'function'; INT_TYPE : 'int'; IDENTIFIER : [a-zA-Z_$]+[a-zA-Z_$0-9]*; WS : [ \t\r\n]+ -> skip ; ,将其有效地更改为解析器非终端,将允许解析器工作,但我认为它可能会以不合需要的方式更改解析树。

我理解解析器&#34;应该知道&#34;考虑到Antlr的预测解析策略的性质,哪些词汇标记在上下文中是可能的。我远离Antlr专家,所以我不会假装解释为什么它似乎不起作用,但是大多数解析器生成器 - 以及我常用的所有 - 词汇分析作为解析的先前传递有效地执行,因此在解析器建立上下文之前完成文本输入到令牌流的转换。 (大多数词法生成器,包括Antlr,都有用户可以构建词汇上下文的机制,但是恕我直言这些机制会降低语法可读性,只有在必要时才能使用。)

这是我测试的语法文件:

{{1}}