由于ID和STRING都可以匹配以“ driver”开头的输入文本,因此,即使ID规则排在最前面,词法分析器也会选择最长的匹配项。
因此,您在这里有几种选择。最直接的方法是通过要求字符串以等号开头来消除ID和STRING之间的歧义(这是替代方法的工作方式)。
file : prop+ EOF ;prop : ID STRING newline ;ID : [a-zA-Z]+ ;STRING : '=' (~[rn])+;newline : 'r'?'n' ;
然后,您可以使用操作从字符串标记的文本中修剪等号。
或者,您可以使用谓词消除规则的歧义。
file : prop+ EOF ;prop : ID '=' STRING newline ;ID : [a-zA-Z]+ ;STRING : { isValue() }? (~[rn])+; newline : 'r'?'n' ;其中,isValue方法在字符流上向后看以验证其是否跟随等号。就像是:
@members {public boolean isValue() { int offset = _tokenStartCharIndex; for (int idx = offset-1; idx >=0; idx--) { String s = _input.getText(Interval.of(idx, idx)); if (Character.isWhitespace(s.charAt(0))) { continue; } else if (s.charAt(0) == '=') { return true; } else { break; } } return false;}}


