匹配最具体的规则

时间:2018-04-15 02:28:30

标签: antlr4

在我的语法中,我希望同时拥有"变量标识符"和"功能标识符"。基本上,我希望对函数标识符中允许的字符限制较少。但是,我遇到的问题是所有变量标识符都是有效的函数标识符。

作为一个例子,假设我想在函数标识符中允许使用大写字母,但在变量标识符中不允许。我目前的(可能是天真的)可能看起来像:

prog : 'func' FunctionId
     | 'var' VariableId
     ;

FunctionId : [a-zA-Z]+ ;
VariableId : [a-z]+ ;

根据上述规则,var hello无法解析。如果我理解正确,这是因为FunctionId首先被定义,所以"你好"被视为FunctionId

我可以让antlr选择更具体的有效规则吗?

2 个答案:

答案 0 :(得分:1)

可以找到解释为什么你的语法不能按预期工作的原因here

您可以使用语义谓词解决此问题:

AUTH_EXTRA_ARGUMENTS = {'hd': 'example.com'}

在词法分析器级别上只有id。在解析器级别,您可以将id限制为小写字符。 grammar Test; prog : 'func' functionId | 'var' variableId ; functionId : Id; variableId : {isVariableId(getCurrentToken().getText())}? Id ; Id : [a-zA-Z]+; 看起来像是:

isVariableId(String)

答案 1 :(得分:1)

  

我可以让antlr选择更具体的有效规则吗?

否(如前所述)。词法分析器仅匹配尽可能多的匹配,并且在2个或更多规则匹配相同的情况下,首先定义的那个"胜出"。没有办法解决这个问题。

我会这样做:

prog : 'func' functionId
     | 'var' variableId
     ;

functionId : LowerCaseId | UpperCaseId ;
variableId : LowerCaseId ;

LowerCaseId : [a-z]+ ;
UpperCaseId : [A-Z] [a-zA-Z]* ;