330 likes | 609 Views
구문 트리. 파스트리. 다음의 toyPL 프로그램 조각에 대하여 파스트리 ( 유도트리 ) 를 그리시오 . begin if ( <Cond> ) then <Var> = <Expr> ; <Var> = <Expr> ; <Var> = <Expr> end 유도는 <stmt> 로부터 시작한다 . ( 즉 , 유도트리의 루트가 <stmt> 임 .). 파스트리에 대한 고찰. 고찰 1: 자식 노드의 개수 문제점 : 모든 노드를 같은 자료구조로 유지 못함 고찰 2: 정보가 포함되어 있는 노드
E N D
파스트리 • 다음의 toyPL 프로그램 조각에 대하여 파스트리(유도트리)를 그리시오. begin if ( <Cond> ) then<Var> = <Expr> ;<Var> = <Expr> ; <Var> = <Expr>end • 유도는 <stmt>로부터 시작한다. (즉, 유도트리의 루트가 <stmt>임.)
파스트리에 대한 고찰 • 고찰1: 자식 노드의 개수 • 문제점: 모든 노드를 같은 자료구조로 유지 못함 • 고찰2: 정보가 포함되어 있는 노드 • 해결: 불필요한 노드를 제거 • 고찰3: 그냥 아래로 연결되는 노드 • 해결: 해당 노드를 제거하고 아래위를 직접 연결
자식 노드의 개수 • 모든 트리는 링크 2개로서 표현 가능 원 트리 변환된 트리
kind value bro son 트리 노드의 구조 p ... ...
+ num * num num 1 2 3 트리 표현 예제
트리 순회 • 기본 아이디어 • 형제 노드는 while loop로 • 자식 노드는 recursive call로 • 알고리즘 algorithm traverse(p) { while (p != NULL) { process(p); traverse(p->son); p = p->bro; } }
구문 트리 (abstract syntax tree) 파스트리를 간략히 표현한 형태 전체 트리의 크기가 작다 파스트리와 똑같은 정보를 유지 예: 1 + 2 * 3 구문 트리
노드의 종류 • PLUS, MINUS, TIMES, DIVIDE, NEG • AND, OR, NOT • EQ, NE, GT, GE, LT, LE • NAME, NUMBER • FCALL, PCALL, ASSIGN, IF, WHILE, FOR, COMP, RETURN • MAIN, VARDECL, DECL, INT, LONG, PROC, FUNC
EXPR EXPR NEG PLUS류 bro bro [EXPR] [EXPR] [EXPR] EXPR (1) * PLUS류: PLUS, MINUS, TIMES, DIVIDE
EXPR EXPR FCALL NUMBER value bro bro NULL [NAME] [EXPR]* EXPR (2)
EXPR / NAME NAME symtab index bro NULL EXPR (3) - NAME
COND COND NOT AND류 bro bro [COND] [COND] [COND] COND (1) * AND류: AND, OR
COND EQ류 bro [EXPR] [EXPR] COND (2) * EQ류: EQ, NE, GT, GE, LT, LE
STMT / COMP STMT STMT COMP ASSIGN RETURN bro bro bro [NAME] [EXPR] [STMT]+ [EXPR] STMT (1)
STMT STMT IF PCALL bro bro [NAME] [EXPR]* [COND] [STMT] [STMT]? STMT (2)
STMT STMT WHILE FOR bro bro [NAME] [COND] [STMT] [EXPR] [EXPR] [STMT] STMT (3)
PGM MAIN symbol table [SUBPGM]* [VARDECL] [COMP] PROGRAM
VARDECL DECL VARDECL DECL bro bro [DECL]* [NAME]+ [TYPE] VARDECL
TYPE TYPE LONG INT bro bro NULL NULL TYPE
SUBPGM SUBPGM symbol table FUNC PROC [COMP] bro bro [NAME] [VARDECL] [VARDECL] [COMP] [NAME] [TYPE] [VARDECL] [VARDECL] SUBPGM symbol table
AST 구성 예 • 프로그램 조각 begin sum = sum + 1; if (sum > max) then max = sum end • AST • 각자 구성해 봅시다.
심볼테이블 • 심볼테이블 • 이름과 속성을 가진 테이블 • 부프로그램 당 하나의 심볼테이블 • 심볼테이블 조작 • 생성: 부프로그램을 만났을 때 • 항목 추가: 이름을 만났을 때 • 항목 갱신: 주소계산 등의 필요시에
심볼테이블의 구조 • 심볼테이블의 구조 struct symbolTable { char name[MAXNAMELEN]; typeKind type; int line; int addr; }; • 타입의 종류 UNKNOWN, INT, LONG, PNAME, FNAME, MNAME, ETC
심볼테이블 조작 • 생성 symtab *mkSymbolTable() • 항목 검색 및 추가 symtabEntry(symtab *st, char *name, typeKind type, int line) • st에서 name을 찾아서 인덱스를 반환 • 찾지 못하면 항목 추가 후 인덱스를 반환 • 프로그램 위치 cdcs:~suhyun/compiler/toyPL/toypl.[hc]
고려 사항 • 심볼테이블 작성시 고려사항 • 심볼테이블의 생성 시점 • 하나의 부프로그램당 하나의 심볼테이블 • 구문분석시 부프로그램을 인식하였을 때 • mkSymbolTable()를 호출 • 항목 추가의 시점 • symtabEntry()의 첫 파라메터는 심볼테이블임 • 즉, 심볼테이블 생성후 항목 추가 가능 • 어휘분석시는 심볼테이블을 만들지 않음 • 구문분석시 단어가 인식되었을 때 추가
단어전달 • 단어전달 • 어휘분석의 결과로 토큰을 파서에 전달 • 숫자의 경우는 인식된 값을 함께 전달 • 단어의 경우는 스트링을 전달 • 방법 • yacc에서: %union으로 스트링 타입을 명시 %union { ... char *sval; } • lex에서: 해당 스트링을 전달 {word} {yylval.sval = yytext; return(TW);}
구문분석기의 제작 단계 1. 문법검사기를 제작 • 기능: 프로그램의 오류만 검사 2. 소스 줄 번호 출력 • 기능: 오류가 있을 경우 소스의 줄 번호 출력 3. 트리 생성 • 2에 트리생성 부분을 추가 4. 심볼테이블 구성 • 3에 심볼테이블 구성 부분을 추가
구문분석기의 응용 • 만들어진 구문트리를 이용 • Pretty Printer 제작 • 변수 검사 • 선언되지 않은 변수 • 사용되지 않는 변수 • 프로시져/함수 검사 • 프로시져/함수가 아닌 것을 호출 • 호출되지 않는 프로시져/함수 • 호출시 파라메터의 수와 타입 점검 • 함수의 반환 스펙과 반환 값의 타입 검사 • 식의 타입 검사