2011-10-14 1 views
3

나는 타입 검사를 지원하기 위해 ANLTR을 연구 중이다. 나는 어느 시점에 문제가있다. 내가 예를 들어 문법으로 설명하려고합니다, 나는 다음과 같은 있다고 가정 : 규칙 dec_list에서타입 검사, 언어 자바에 대한 ANTLR의 목록을 반환

@members { 
    private java.util.HashMap<String, String> mapping = new java.util.HashMap<String, String>(); 
} 

var_dec 
    : type_specifiers d=dec_list? SEMICOLON 
    { 
     mapping.put($d.ids.get(0).toString(), $type_specifiers.type_name); 
     System.out.println("identext = " + $d.ids.get(0).toString() + " - " + $type_specifiers.type_name); 
    }; 

type_specifiers returns [String type_name] 
    : 'int' { $type_name = "int";} 
    | 'float' {$type_name = "float"; } 
    ; 

dec_list returns [List ids] 
    : (a += ID brackets*) (COMMA (a += ID brackets*))* 
    {$ids = $a;} 
    ; 

brackets : LBRACKET (ICONST | ID) RBRACKET; 

ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*; 
LBRACKET : '['; 
RBRACKET : ']'; 

, 당신은 내가 ID를 가진 목록을 반환하고 있음을 볼 수 있습니다. 그러나 var_dec에서 내가 목록의 첫 번째 요소를 넣으려고하면 (dec_list 규칙의 반환 값을 보려면 get(0) 만 사용하고 나중에 반복 할 수 있습니다.) 입력

int a, b; 

에 대한

[@4,6:6='a',<17>,1:6] 

는 내가 뭘하려고이 경우 a 각각 인덱스 0과 1의 목록에서 b에서, 각 ID의 텍스트를 얻을 수 있습니다.

아무도 아이디어가 있습니까?

답변

4

+= 연산자는 ListToken의의 만이 아니라 텍스트이 Token의 일치를 만듭니다. 규칙의 @init{...} 블록에서 List을 초기화하고 토큰의 내부 텍스트를 직접 추가해야합니다.

또한,이 작업을 수행 할 필요가 없습니다 :

type_specifiers returns [String type_name] 
    : 'int' { $type_name = "int";} 
    | ... 
    ; 

단순히 같이, 당신이 그것을 사용하는 규칙에서 text 속성을 type_specifiers 년대에 액세스하고 returns 문을 제거 :

var_dec 
    : t=type_specifiers ... {System.out.println($t.text);} 
    ; 

type_specifiers 
    : 'int' 
    | ... 
    ; 
이 같은

시도 뭔가 :

grammar T; 

var_dec 
    : type dec_list? ';' 
    { 
     System.out.println("type = " + $type.text); 
     System.out.println("ids = " + $dec_list.ids); 
    } 
    ; 

type 
    : Int 
    | Float 
    ; 

dec_list returns [List ids] 
@init{$ids = new ArrayList();} 
    : a=ID {$ids.add($a.text);} (',' b=ID {$ids.add($b.text);})* 
    ; 

Int : 'int'; 
Float : 'float'; 
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*; 
Space : ' ' {skip();}; 

하여 콘솔에 다음과 같은 인쇄 것이다 :

type = int 
ids = [a, b, foo] 

당신이 다음 클래스 실행하는 경우 :

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
    TLexer lexer = new TLexer(new ANTLRStringStream("int a, b, foo;")); 
    TParser parser = new TParser(new CommonTokenStream(lexer)); 
    parser.var_dec(); 
    } 
} 
+0

바트를 대단히 감사합니다 :). –

+1

존 환영합니다. –