我有我的 char.g4 文件:
grammar char;
start: pair (',' pair)*;
pair: key ':' value;
key: L_ID;
value: L_ID;
STRING
: '"' (ESC | SAFECODEPOINT)* '"'
;
fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;
fragment UNICODE
: 'u' HEX HEX HEX HEX
;
fragment HEX
: [0-9a-fA-F]
;
fragment SAFECODEPOINT
: ~ ["\\\u0000-\u001F]
;
L_ID: L_ID_PART ;
fragment L_DIGIT : [0-9] ;
// Double quoted string escape sequence
//fragment L_STR_ESC_D : '""' | '\\"' ;
fragment L_ID_PART :
[a-zA-Z] ([a-zA-Z] | L_DIGIT | '_' | '.')* // Identifier part
| '$' '{' .*? '}'
| ('_' | '@' | '#' | '$') ([a-zA-Z] | L_DIGIT | '_' | '@' | ':' | '#' | '$')+ // (at least one char must follow special char)
| '"' .*? '"' // Quoted identifiers
| '`' .*? '`' // Quoted identifiers
| '\'' .*? '\'' // Quoted identifiers
;
WS: [ \t\n\r]+ -> skip ;
当我尝试使用antlr4解析字符串名称:“x”时,我观察到值部分与STRING而不是L_ID匹配。我相信“x”符合 L_ID 表达式,那么为什么它会与 STRING 匹配呢?
我明白了。
line 1:6 mismatched input '"x"' expecting L_ID
我很确定您只发布了真实语法的(一小部分),因为输入
x:z
正在被很好地解析。
你的问题是在你的解析器语法中的某个地方,你已经完成了
'x'
,就像这样:
parser_rule : 'x' ':' L_ID;
这
'x'
导致 ANTLR 创建如下的词法分析器规则:
T__0 : 'x';
T__1 : ':';
L_ID: L_ID_PART;
并且因为
T__0
是在 L_ID
之前定义的,所以 'x'
将始终成为 T__0
标记,而不是 L_ID
。这就是 ANTLR 的词法分析器的工作原理:尝试为每个词法分析器规则匹配尽可能多的字符,如果出现平局,请选择首先定义的词法分析器规则。词法分析器不“监听”解析器。
你能做的是:
parser_rule : X ':' id;
id : X | L_ID;
X : 'x';
L_ID: L_ID_PART;