2016-06-20 15 views
1

ANTLR文字列の補間

my.greeting = "hello ${your.name}" 

は私が得るエラーは以下のとおりです。

line 1:31 token recognition error at: 'e' 
line 1:34 no viable alternative at input '<EOF>' 

Output from ANTLR IntelliJ Plugin

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; 

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 ; 

式:

my.greeting = "hello" 
my.greeting = "hello ${} world" 

任意のアイデア私が間違っているかもしれないもの?

答えて

1

mode INTERPOLATION_MODE; 

STRING_SEGMENT_START: '}' -> more, popMode; 
I_VAR: (UPPERCASE|LOWERCASE) ANY_CHAR* -> type(VAR); 
I_DOT: '.' -> type(DOT); 

... 

variable: (VAR DOT)? VAR; 
+0

私はこれがあなたの質問に対する答えではありませんが、あなたの答えにはコメント(コメントに収まらない)が多くあることを認識しています。だから、これで解決すれば、あなた自身の答えにこれを加え、それを受け入れることをお勧めします。私はこの答えを削除します。 –

+0

ありがとうBart。私はあなたのことが素晴らしい答えだと思います。私の解決策よりもずっと良い。 –

1

[OK]を、私は、デフォルトのレクサーはINTERPOLATION_MODEに再びルールを定義する必要があること(thisに触発さ)を働いてきた:

MyLexer.g4:

... 
mode INTERPOLATION_MODE; 

STRING_SEGMENT_START: '}' -> more, popMode; 
I_VAR: (UPPERCASE|LOWERCASE) ANY_CHAR*; 
I_DOT: '.'; 

... 

をMyParser.g4:

... 
variable: ((VAR|I_VAR) (DOT|I_DOT))? (VAR|I_VAR); 
... 

Output from IntelliJ ANTLR Plugin

この参照msの過剰な、しかし、まだ誰かのためにより良い答えを持っている。

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); 

あなたは試みることができる:代わりの

1

文字列の補間も公式ANTLR文法リポジトリ内C#PHP文法を既存の実装。