2016-06-20 3 views
1

ANTLR 문자열 :내가 같은 문자열 보간 식 구문 분석 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

바트에게 감사드립니다. 나는 네가 대단한 대답이라고 생각한다. 내 솔루션보다 훨씬 좋네요. –

1

좋아, 나는 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 overkill, 그래도 여전히 더 나은 답변을 가진 사람을 위해 밖으로 개최.

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 문법 기존에 구현했습니다.