2010-04-20 5 views
2

ANTLR을 사용하여 for 루프에 대한 간단한 matlab과 같은 구문 분석을 수행하려고합니다. 내가 루프를 분석하고 각 문에 일부 작업을하기 위해, 8 배 y(i) = a(i) + i 문을 구문 분석 할ANTLR을 사용하여 루프 구문 분석

for i=1:8 
    y(i) = a(i) + i; 
end 

: 같은

루프입니다. ANTLR은 statements 규칙을 구문 분석 할 때

forloop 
@init 
    { 
     string c = ""; 
     int mark = input.Mark(); 
    } 
@after 
    { 
     if (constants[c] < $i2.value) { 
      SetConst(c, constants[c] + 1); 
      input.Rewind(mark); 
     } 
    } 
: 'for' IDENT '=' i1=constant ':' i2=constant NEWLINE 
    { 
     c = $IDENT.text; 
     if (!IsConst(c)) { 
      AddConst(c, $i1.value); 
     } 
    } 
    statements? 
    'end' 
; 

는 사실, 그것은 어떤 조치를 트리거 :

내 규칙 (조치가 C#으로 설명되어 있습니다) 다음과 같습니다. 여기서는 ANTLR에 i is a constant which value is 1을 먼저 말한 다음 구문 분석을 반복하면서 내 i을 계속 증가시키고 싶습니다.

필자는 input.Mark() 및 input.Rewind()를 사용하지만 예상대로 작동하지 않으며 ANTLR에서 일부 오류가 발생하여 "NEWLINE"토큰이 없습니다. 'for'키워드.

루프가 끝날 때까지 일부 동작을 트리거하려면 어떻게하면 루프 파싱을 처리 할 수 ​​있습니까?

답변

2

해결책을 찾았습니다. 사실 input.Rewind()은 내가 처음 예상 한대로 goto처럼 행동하지 않습니다. input.Mark()으로 정의되는 이전 상태로 입력 버퍼를 복원하면됩니다.

그래서 for 루프의 끝 부분에 도달하면 조건이 여전히 참인 경우 전체 for 루프를 입력 버퍼에 다시 삽입했습니다.

BUT! 또 다른 규칙으로, for-loop에 NEWLINE을 반드시 따라야한다고 ANTLR에게 말했습니다. 그리고 내 경우, 재 주입을 통해 제 1 패스에 대한 루프가 immediatly 뒤를이었다 두 번째 패스에 대한 루프,이 구성의 결과 : 물론

for i=1:8 
    y(i) = a(i) + i; 
endfor i=1:8 
    y(i) = a(i) + i; 
endfor i=1:8 
    y(i) = a(i) + i; 
endfor i=1:8 
    y(i) = a(i) + i; 
endfor i=1:8 
    y(i) = a(i) + i; 
endfor i=1:8 
    y(i) = a(i) + i; 
endfor i=1:8 
    y(i) = a(i) + i; 
endfor i=1:8 
    y(i) = a(i) + i; 
end 

NEWLINE이 따랐다 없으므로 ANTLR은 처음 7 번째 루프에서 오류를보고했습니다.

해결책은 단순히 for 루프에 NEWLINE이 오지 않아도된다는 것을 ANTLR에 알려주는 것이 었습니다.

forloop 
    @init {int mark = input.Mark();} 
    : 'for' IDENT '=' i1=constant ':' i2=constant NEWLINE 
     { 
      string c = $IDENT.text; 
      if (!IsConst(c)) { 
       AddConst(c, $i1.value); 
      } 
     } 
     statements? 'end' 
     { 
      if (constants[c] < $i2.value) { 
       SetConst(c, constants[c] + 1); 
       input.Rewind(mark); 
      } 
     } 
    ; 
+0

그러나이 되감기 :

마지막에 대한 루프 규칙과 같은

(이 그냥 코드 정리입니다) ... 그것은 마치 마법처럼 작동하지만 나는이 결과에 의해 그 정도에 만족하지 않다 방법은 각각의 rewind 후 $ 1.value에 C 루프 카운터를 다시 초기화하지 않을까요? –