ANTLR字符串插值
我正在尝试编写一个ANTLR语法,用于解析字符串插值表达式,例如:ANTLR字符串插值,antlr,antlr4,Antlr,Antlr4,我正在尝试编写一个ANTLR语法,用于解析字符串插值表达式,例如: my.greeting = "hello ${your.name}" 我得到的错误是: line 1:31 token recognition error at: 'e' line 1:34 no viable alternative at input '<EOF>' MyLexer.g4: lexer grammar MyLexer; START_STR: '"' -> more, pushMode(S
my.greeting = "hello ${your.name}"
我得到的错误是:
line 1:31 token recognition error at: 'e'
line 1:34 no viable alternative at input '<EOF>'
MyLexer.g4:
lexer grammar MyLexer;
START_STR: '"' -> more, pushMode(STRING_MODE) ;
VAR: (UPPERCASE|LOWERCASE) ANY_CHAR*;
EQ: '=';
DOT: '.';
WHITE_SPACE: (SPACE | NEW_LINE | TAB)+ -> skip;
fragment DIGIT: '0'..'9';
fragment LOWERCASE: 'a'..'z';
fragment UPPERCASE: 'A'..'Z';
fragment ANY_CHAR: LOWERCASE | UPPERCASE | DIGIT;
fragment NEW_LINE: '\n' | '\r' | '\r\n';
fragment SPACE: ' ';
fragment TAB: '\t';
mode INTERPOLATION_MODE;
STRING_SEGMENT_START: '}' -> more, popMode;
mode STRING_MODE;
STRING_END: '"' -> popMode;
STRING_SEGMENT_END: '${' -> pushMode(INTERPOLATION_MODE);
TEXT : ~["$]+ -> more ;
...
mode INTERPOLATION_MODE;
STRING_SEGMENT_START: '}' -> more, popMode;
I_VAR: (UPPERCASE|LOWERCASE) ANY_CHAR*;
I_DOT: '.';
...
下面这样的表达很好:
my.greeting = "hello"
my.greeting = "hello ${} world"
你知道我可能做错了什么吗?好的,我发现(受启发)我需要在插值模式下再次定义默认lexer规则:
MyLexer.g4:
lexer grammar MyLexer;
START_STR: '"' -> more, pushMode(STRING_MODE) ;
VAR: (UPPERCASE|LOWERCASE) ANY_CHAR*;
EQ: '=';
DOT: '.';
WHITE_SPACE: (SPACE | NEW_LINE | TAB)+ -> skip;
fragment DIGIT: '0'..'9';
fragment LOWERCASE: 'a'..'z';
fragment UPPERCASE: 'A'..'Z';
fragment ANY_CHAR: LOWERCASE | UPPERCASE | DIGIT;
fragment NEW_LINE: '\n' | '\r' | '\r\n';
fragment SPACE: ' ';
fragment TAB: '\t';
mode INTERPOLATION_MODE;
STRING_SEGMENT_START: '}' -> more, popMode;
mode STRING_MODE;
STRING_END: '"' -> popMode;
STRING_SEGMENT_END: '${' -> pushMode(INTERPOLATION_MODE);
TEXT : ~["$]+ -> more ;
...
mode INTERPOLATION_MODE;
STRING_SEGMENT_START: '}' -> more, popMode;
I_VAR: (UPPERCASE|LOWERCASE) ANY_CHAR*;
I_DOT: '.';
...
MyParser.g4:
parser grammar MyParser;
options { tokenVocab=MyLexer; }
program: variable EQ expression EOF;
expression: (string | variable);
variable: (VAR DOT)? VAR;
string: (STRING_SEGMENT_END expression)* STRING_END;
...
variable: ((VAR|I_VAR) (DOT|I_DOT))? (VAR|I_VAR);
...
不过,这似乎有些过分,所以仍然需要一个更好的答案。而不是:
mode INTERPOLATION_MODE;
STRING_SEGMENT_START: '}' -> more, popMode;
I_VAR: (UPPERCASE|LOWERCASE) ANY_CHAR*;
I_DOT: '.';
...
variable: ((VAR|I_VAR) (DOT|I_DOT))? (VAR|I_VAR);
你可以试试:
mode INTERPOLATION_MODE;
STRING_SEGMENT_START: '}' -> more, popMode;
I_VAR: (UPPERCASE|LOWERCASE) ANY_CHAR* -> type(VAR);
I_DOT: '.' -> type(DOT);
...
variable: (VAR DOT)? VAR;
字符串插值也在官方ANTLR语法库中的现有语法和语法中实现。我意识到这不是对您问题的回答,而是对您答案的评论(不适合在评论中)。因此,如果这解决了它,我建议你把它添加到你自己的答案中,并接受它。那我就删除这个答案。谢谢巴特。我认为你的回答很好。比我的解决方案好得多。