用ANTLR解析字母范围

用ANTLR解析字母范围,antlr,antlr4,Antlr,Antlr4,我有以下解析器规则: defDirective : defType whiteSpace letterSpec (whiteSpace? COMMA whiteSpace? letterSpec)*; defType : DEFBOOL | DEFBYTE | DEFINT | DEFLNG | DEFLNGLNG | DEFLNGPTR | DEFCUR | DEFSNG | DEFDBL | DEFDATE | DEFSTR | DEFOBJ

我有以下解析器规则:

defDirective : defType whiteSpace letterSpec (whiteSpace? COMMA whiteSpace? letterSpec)*;
defType :
        DEFBOOL | DEFBYTE | DEFINT | DEFLNG | DEFLNGLNG | DEFLNGPTR | DEFCUR |
        DEFSNG | DEFDBL | DEFDATE | 
        DEFSTR | DEFOBJ | DEFVAR
;
letterSpec : universalLetterRange | letterRange | singleLetter;

singleLetter : RESTRICTED_LETTER;
universalLetterRange : upperCaseA whiteSpace? MINUS whiteSpace? upperCaseZ;
upperCaseA : {_input.Lt(1).Text.Equals("A")}? RESTRICTED_LETTER;
upperCaseZ : {_input.Lt(1).Text.Equals("Z")}? RESTRICTED_LETTER;
letterRange : firstLetter whiteSpace? MINUS whiteSpace? lastLetter;
firstLetter : RESTRICTED_LETTER;
lastLetter : RESTRICTED_LETTER;

whiteSpace : (WS | LINE_CONTINUATION)+;
根据相关的Lexer规则:

RESTRICTED_LETTER : [a-zA-Z];
MINUS : '-';
COMMA : ',';
WS : [ \t];
LINE_CONTINUATION : [ \t]* UNDERSCORE [ \t]* '\r'? '\n';
以及匹配其大小写拼写的DefType

现在,当我尝试在以下输入上进行测试时,它完全按照预期工作:

DefInt I,J,K
DefBool A-Z
但是,它对任意字母范围不起作用(请参见规则
letterRange
)。当我使用输入
DefByte B-F
时,我收到错误消息“第1行:8个不匹配的输入'B'应为受限字母”

我曾尝试将
受限_标识符
表示为一个范围(
'a'..'Z'.'a'..'Z'
),但这并没有改变有关错误消息的任何内容

defDirective
中的第一个
whiteSpace
更改为
whiteSpace+
时,错误消息会稍微长一点(现在在预期的备选方案中包括WS和LINE_CONTINUATION)

此外,IntelliJ ANTLR插件生成的解析树突然开始将
F
识别为
singleLetter
,而以前它没有这样做

这种行为在TargetLanguagesJava和CSharp之间似乎是一致的

以前的规则要宽松得多,但这会导致不正确的解析树,所以我有点想解决这个问题


在这里我如何正确识别字母范围?

所以@巴特基尔斯的怀疑是对的。给定的Lexer规则并不是流程中涉及的所有规则

完整语法包含一个lexer规则
B_CHAR:B
,用于不相关语法规则的特例。对输入流进行词法分析时,
B_CHAR
优先于
RESTRICTED_LETTER


所提供的语法规则是正确的(并且工作正常),但是需要将
B_CHAR
标记从词法化的标记中删除。

很高兴看到您解决了它。仅供参考,这是ANTLR决定选择何种杠杆规则的方式: