我定义了一种小语言和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)
答案 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}}