1

저는 통역사를 작업 중이며 의미 분석 후 트래버스 및 추상 구문 트리를 사용하는 방법에 대한 좋은 설명을 발견하지 못했습니다. 나는 그것을하는 올바른 방법이 무엇인지 궁금합니다. 나는 왼쪽에서 오른쪽으로 처리하는 부모에게 단말기를 병합하고 최대한 많이 반복하는 것을 이해합니다.인터프리터 백엔드, 추상 구문 트리를 어떻게 트래버스합니까?

나는이 추상 구문 트리를 가지고 있습니다.이 추상 구문 트리는 올 바르거나 맞지 않을 수 있습니다.

ast http://theadesilva.com/so_1.jpg

어떻게해야합니까?

*에 34와 3을 병합 한 다음 4와 *를 +에 병합 한 다음 ident를 call과 + call에 병합 하시겠습니까? 그게 맞습니까? 트리를 거꾸로 통과하는 좋은 알고리즘은 무엇입니까?

+0

왜 직접 AST interp를하고 싶습니까? 먼저 평평한 스택 VM 바이트 코드와 같은 무언가로 변환하지 않고 재시도해야합니까? –

답변

1

내가했던 것처럼 AST를 작성하지 않았을 것입니다. print 인자를 인자로 보았습니다. 그래서 나는 나무를 만들 것입니다.

print 
    \ 
     + 
    / \ 
    4  * 
    / \ 
     3  34 

루트를 운영자/기능에 적용하기 전에 트리를 걸어 평가하십시오. 두 자녀 만있을 수 있다는 규정은 없습니다. 여러 명이 필요한 경우 여러 명의 자녀를 가질 수 있습니다.

즉 재미 (A, B, C, D)

fun 
// \ \ 
a b c d 

또는 자녀가없는

즉 currentTime을() 내 AST와 질문이 될 것이다 이처럼

currentTime 

visit            
print   need to evaluate right child 
+    left is 4, need to evaluate right 
*    left is 3, right is 34 
       evaluate 3 * 34 and return right = 102 
       evaluate 4 + 102 and return right = 106 
       evaluate print, so print 106 
+0

상대 론적으로 PRINT number *는 반드시 하나의 함수 여야합니다. 기본 언어로 연결하는 데는 거의 이유가 없습니다 (PRINTCHARACTER 또는 PRINTSTRING을 언어에 써야하지만 PRINT 번호는 숫자 문자열을 생성 한 다음 인쇄 할 프리미티브를 호출해야합니다). 나는 OP가했던 방식대로 나무를 만들었을 것입니다. 산수를 계산 한 후에 그는 "call (print, 106)"을 가지고 있고 print (어딘가)를위한 AST를 찾는 "call"을위한 인터프리터 단계를 실행합니다. 그것을 평가하기 시작합니다. –