2012-04-04 4 views
2

C#을 사용하여 PLC 언어 인터프리터를 작성하고 있습니다. 인터프리터에는 요소 유형 (정수, 부울, ..) 및 파생 유형 (구조체, 배열, ...)과 같은 자체 형식 계층이 있습니다. ANTLR 문법에서 다차원 배열을 만드는 동안 문제가 있습니다. 내가 파서에 아무런 문제가ANTLR 문법에서 다차원 배열 만들기

decl_derivated 
    : 'TYPE' NEWLINE* ID ':' NEWLINE* type_decl ';' NEWLINE* 'END_TYPE' NEWLINE* -> ^(TYPEDEF<TypeDefinition>[$ID.text, $type_decl.type]) 
    ; 

type_decl returns [Type type] 
    : 'STRUCT' NEWLINE* decl_fields 'END_STRUCT' { $type = new STRUCT($decl_fields.fieldList); } 
    | 'ARRAY' '[' range ']' 'OF' type_var { $type = new ARRAY($type_var.type, $range.init, $range.end); } 
    ; 

range returns [int init, int end] 
    : ini=CTE_INT '..' en=CTE_INT { $init = int.Parse($ini.text); $end = int.Parse($en.text); } 
    ; 

type_var returns [Type type] 
    : 'BOOL' { $type = new BOOL(); } 
    | 'INT' { $type = new INT(); } 
    | 'REAL' { $type = new REAL(); } 
    ; 

/* lexer */ 

ID : (LETTER | '_') (LETTER | DIGIT | '_')* 
    ; 

fragment 
DIGIT : '0'..'9' 
     ; 

fragment 
INTEGER : DIGIT ('_'|DIGIT)* 
    ; 

fragment 
EXPONENT : ('e'|'E') ('+'|'-')? INTEGER ; 

fragment 
CTE_INT 
    : ('+'|'-'|) INTEGER 
    ; 

fragment 
CTE_REAL 
    : ('+'|'-'| /*vacio*/) INTEGER '.' INTEGER EXPONENT? 
    ; 

RANGE : '..' ; 

RANGE_OR_INT 
    : (CTE_INT RANGE) => CTE_INT { $type=CTE_INT; } 
     | (CTE_REAL) => CTE_REAL  { $type=CTE_REAL; } 
     | CTE_INT     { $type=CTE_INT; } 
    ; 

NEWLINE : '\r'? '\n' 
    | '\r' 
    ; 

:

TYPE 
    MY_ARRAY : ARRAY [0..2, 1..2] OF INT; 
END_TYPE 

일차원 배열 선언을 구문 분석에 대한 나의 ANTLR 문법은 다음과 같습니다

은 내 언어가 다차원 배열을 선언하는 방법 (3 × int 배열)입니다 배열 선언의 문법을 변경하는 다차원 배열 :

type_decl returns [Type type] 
     : 'ARRAY' '[' range (',' range)* ']' 'OF' type_var 

이 다차원 배열에 대한 생성자를 작성하는 방법을 모르겠습니다. 누구든지 나를 도울 수 있습니까? 감사합니다.

+0

'decl_array [목록 listaInit, 목록 listaFin] 반환 [유형 유형] \t : 'ARRAY ''[ 'r1 = range {$ listaInit.Add ($ r1.init); $ listaFin.Add ($ r1.end); } \t (','r2 = range {$ list2Init.Add ($ r2.init); $ listaFin.Add ($ r2.end);}) * ']' ' ARRAY ($ type_var.type, $ listaInit, $ listaFin); } \t \t; '이 방법으로 해결하려고했습니다. 배열 생성자 내에서 다차원 배열을 만들지 만 더 좋은 방법이라고 생각합니다. –

+0

질문에 편집 해 주실 수 있습니까? 읽을 때 훨씬 쉬울 것입니다. 감사! (시도했지만 .. 줄 바꿈을 얻는 것은 3시에 할 수있는 것보다 더 많은 일입니다 :) – sarnold

+0

시간 내 주셔서 감사합니다;) –

답변

1

솔루션 마지막으로

, 내가 더 나은 더 우아한 해결책을 달성했습니다. 내 ARRAY 데이터 형식 클래스에 새로운 메서드를 두 개 추가했습니다. 하나는 새 차원을 추가하고 다른 하나는 기본 형식을 설정하기위한 클래스입니다.

public class ARRAY : ANY_DERIVED 
    { 
     public Type de; // ARRAY type 
     public int size; 
     public int initIndex; 
     public int finalIndex; 

    public ARRAY(int initIndex, int finalIndex) 
    { 
     this.initIndex = initIndex; 
     this.finalIndex = finalIndex; 
     size = finalIndex - initIndex + 1; 
    } 

    public void NewDim(int initIndex, int finalIndex) 
    { 
     if (de == null) 
      de = new ARRAY(initIndex, finalIndex); 
     else 
      ((ARRAY)de).NewDim(initIndex, finalIndex); 
    } 

    public void SetBaseType(Type t) 
    { 
     if (de == null) 
      de = t; 
     else 
      ((ARRAY)de).SetBaseType(t); 
    } 
    } 

ANTLR 문법 : 어쨌든

decl_type returns [Type type] 
    : 'ARRAY' '[' r1=range {$type = new ARRAY($r1.init, $r1.end);} (',' r2=range {((ARRAY)$type).NewDim($r2.init, $r2.end);})* ']' 'OF' type_var { ((ARRAY)$type).SetBaseType($type_var.type); }  
    ; 

은, 시간 내 주셔서 감사합니다;)

관련 문제