2013-06-05 2 views
0

나는 오래된 언어에 대한 문법을 ​​개발 중이다.ANTLR4 - 구분할 수없는 토큰이있는 언어

언어는 상당히 복잡하지만 특정 문제에 집중하고 싶습니다. 그래서 나는 가벼운 버전을 만들었습니다. 라이트 버전에서는 대입 문과 수학 연산 또는 문자열 연결과 같은 간단한 표현식을 지정할 수 있습니다. 이처럼

:

@assign[@var1 (1+3)*2] 
@assign[@var2 "foo" $ "bar"]  

참고 : 할당 문 내부은, 변수는 @의 문자로 시작되지 않을 수 있습니다. 이 언어에서

@assign[@var2 "foo" $ "bar"] 

@assign[var2 "foo" $ "bar"] 

@assign 
[@var2 "foo" 
$ "bar"] 

@assign 
[var2 "foo" 
$ "bar"] 

당신이 또한 변수의 값을 출력 할 수 있습니다 다음과 같은 과제가 동일하므로 문은 또한, 여러 줄에 쓸 수 있습니다. 문제는 특정 명령이 (예 : @print [...])이 아니고이면 변수를 쓰는 것으로 충분합니다. 이처럼 :

@var1 @var2 

그래서, 코드

@assign[@var1 (1+3)*2] 
@assign[@var2 "foo" $ "bar"] 
@var1 @var2 

의 출력은 다음과 같습니다 여기

8 foobar 

내가 뮤 문법 파일에서 시작하여 지금까지 작성한 문법입니다 :

grammar Grammar; 

//////////////// 
// PARSER // 
//////////////// 

file 
: block EOF 
; 

block 
: stat* 
; 

stat 
: assignment 
| print 
; 

assignment 
: ASSIGN LBRACKET variable expr RBRACKET 
; 

print 
: AT ID 
; 

expr 
: expr CONCAT expr #concatExpr 
| expr MUL expr #mulExpr 
| expr DIV expr #divExpr 
| expr ADD expr #addExpr 
| expr SUB expr #subExpr 
| atom    #atomExpr 
; 

variable 
: AT ID 
| ID 
; 

atom 
: LPARENS expr RPARENS #parExpr 
| INT     #intAtom 
| STRING    #stringAtom 
| variable    #variableAtom 
; 

/////////////// 
// LEXER // 
/////////////// 

ASSIGN : AT 'assign' ; 

AT : '@' ; 

ID : [a-zA-Z_] [a-zA-Z_0-9]* ; 

INT 
: [0-9]+ 
; 

LBRACKET : '[' ; 
RBRACKET : ']' ; 
LPARENS : '(' ; 
RPARENS : ')' ; 

CONCAT : '$' ; 
ADD : '+' ; 
SUB : '-' ; 
MUL : '*' ; 
DIV : '/' ; 

WS : [ \t\r\n] -> skip ; 

COMMENT : '[*' .*? '*]' -> skip ; 

STRING : '"' (~["\r\n] | '""')* '"' ; 

변수 I 맞춤형 방문자를 개발했습니다. visitPrint 메서드를 방문하면 ATID의 두 가지 토큰이 있다는 것을 알고 있습니다.

이제 문제가됩니다.

다음 예제 코드

@assign[@var1 "one"] 
@assign[var2 "two"] 
@assign[var3 var1 $ var2] 
Value of var3 is: @var3 

이 출력을 생성하도록 어떻게 내 문법을 수정할 수 있습니다?

Value of var3 is: onetwo 

무료 텍스트를 인쇄 할 수있는 문법을 만드는 것이 목표입니다.

인쇄 규칙을 다시 작성해야한다고 생각합니다. 하지만 ... 어떻게? (각 단어 하나도 토큰) 하나의 토큰을해야한다 :이 경우

print 
: AT ID 
| ?????? //Help! 
; 

는, 목표는 "VAR3의 가치가있다"고이기도합니다.

이것은 틀린 방법입니다.

print 
: AT ID 
| .+? 
; 

미리 감사드립니다.

답변

0

이것은 Parr의 "The Definitive ANTLR 4 Reference"12.3 절의 텍스트에서 XML 태그를 분리하는 예제와 비슷합니다.그는 렉서 (lexer)의 모드를 사용하여 내부 XML 태그와 외부 (즉, 일반 텍스트)의 토큰 출력을 전환합니다.

"@assign"및 "]"이 태그 (모드 1)로 사용되는 것 같습니다. 그렇지 않으면 변수를 인식 한 후 입력을 출력에 인쇄 할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 저는 이미 렉시 컬 모드의 방식을 따르려고했지만 (어쨌든 언어의 다른 측면에 대해이 기능을 사용합니다) 어쨌든 나는 목표에 도달하지 못했습니다. 그래서 나는 그것을 확인하기 위해 @@ [...]를 사용하여 print 서술문의 구문을 변경하기로 결정했다. – user2455930