compiler term project
DESCRIPTION
Compiler Term Project. MiniJava Compiler. 이한욱 2005220146 조재호 2000160239 권신일 99390274. Overview. Mips Assembly Code. MiniJava Source Code. Parser. Jlex Specification file (parser/ MiniJavaLexer ). CUP Specification file (parser/MiniJavaParser.cup). JLex. CUP. Generated. - PowerPoint PPT PresentationTRANSCRIPT
Overview
• Parser
AST
• SymbolTableBuilder
Symbol Table
• CanonUtil
Canonical Tree
MiniJava Source Code
Mips Assembly Code
ParserJlex Specification file(parser/MiniJavaLexer)
CUP Specification file(parser/MiniJavaParser.cup)
Scanner (Lexer)(parser/MiniJavaLexer.java)
Symbols(parser/Sym.java)
Parser(parser/MiniJavaParser.java)
JLex CUP
Yylex MiniJavaParserParser.java(Module)
Generated
TokenSym-bol Yylex.next_token()
Token Listint (Type)
a (Identifier)
; (SEMICOLON)
? (error symbol)
b (Identifier)
; (SEMICOLON)
int (Type)
c (Identifier)
; (SEMICOLON)
…int a;? b;int c;…
Source Code GrammarVarDecl := Type Identifier SEMICOLON
| Type error SEMICOLON
int (Type)
a (Identifier)
; (SEMI-COLON)
Stack
? (error sym-bol)
LookAhead
(pop)
(pop)
…
int (Type)
? (error sym-bol)
b (Identifier)
…
(skip)
int (Type)
? (error sym-bol)
; (SEMI-COLON)
…
int (Type)
? (error sym-bol)
; (SEMI-COLON)
int (Type)
…
VarDecl (error rule)
int (Type)
c (Identifier)
…
…int c;…
Local Error Recovery
Node
Node
Node Node Node
Abstract Syntax Tree
Class A
Method
Var Var Method
Symbol Table Tree
Class B :A
Method
Var Var Method
Class C
Method
Var Var Method
Class List
Class A
Class B
Class C
…
• Symbol Table 은 Class 별로 생성• AST 는 Scope 에 따라 특정 Symbol Table 을 참조• Symbol Table 은 Tree 형태로 구성되어 있기 때문에 상위 Scope 의 Symbol Table을 참조할 수 있다 .
AST PhaseSymbol Table Phase
Symbol Table Builder
변수 또는 메소드에 대한 접근 (사용 )• [Statement] var = 1;• [Statement] foo();• 변수 또는 메소드에 대한 접근 시 변수인지 메소드인지 판별한 후 해당 Scope의 심볼
테이블로부터 탐색하여 해당 변수 또는 메소드가 존재하는지 검사한다 .
객체를 통한 변수 /메소드 접근• [Statement] obj.var = 1;• [Statement] obj.foo();• 심볼테이블에서 obj를 찾은 후 Type과 Type Name을 얻는다 . Type이 CLASS이면 Type
Name에 해당하는 클래스의 심볼에서 탐색하여 변수 또는 메소드가 존재하는지 검사한다 .
변수 또는 메소드 선언• [Statement] Type Identifier;• [Statement] Type Identifier(…)• Type이 올바른 타입인지 검사한다 . 기본형이 아닌 경우 클래스 타입이므로 해당 클래스가
존재하는지 검사한다 .• (변수 또는 메소드의 중복 선언 검사는 심볼 테이블 생성 시 이루어진다 .)
Type Rules (1)
연산자 Semantics• [Statement] Exp && Exp (Operand 가 모두 boolean 타입이어야 한다 .)• [Statement] Exp <|+|-|* Exp (Operand 가 모두 int 타입이어야 한다 .)• [Statement] !Exp (Operand 가 모두 boolean 타입이어야 한다 .)• 연산자가 받아들일 수 있는 피연산자 (Exp)의 타입은 연산자에 의해 결정된다 .
따라서 연산자에 따라 피연산자의 타입을 검사해야 한다 . 만약 피연산자가 Identi-fier인 경우 변수 /메소드 여부 판단 후 심볼테이블을 탐색하여 Type을 얻을 수 있다 .
Type mismatch• 변수에 값을 할당할 때 변수의 타입과 할당된 값의 타입이 일치해야 한다 . 즉 , A
타입으로 선언된 변수에 B 타입의 값을 할당할 수 없다 .
Method return type• 메소드는 반드시 메소드의 Signature에 명시된 리턴 타입의 값을 리턴해야 한다 .
즉 , A 타입을 리턴하도록 명시된 메소드는 B 타입의 값을 리턴할 수 없다 .
Type Rules (2)
public Exp visit(Minus n, Types.Type arg) { return new Ex(BINOP
(Tree.BINOP.MINUS, (n.e1.accept(this, arg)).unEx(), (n.e2.accept(this, arg)).unEx()));
}
Implementation
Canon.java
• IR Tree 를 순회하면서 SEQ 와 ESEQ 를 제거
• CALL 수행 시 return value overwrit-ing 문제 해결
Canonical Form
Canonical Form
Original Transformed
static Tree.ESEQ do_exp(Tree.ESEQ e) { Tree.Stm stms = do_stm(e.stm); Tree.ESEQ b = do_exp(e.exp); return new Tree.ESEQ(seq(stms,b.stm), b.exp); }
연속적으로 수행되는 statement
LABEL 로 시작해서 JUMP 또는 CJUMP로 끝남
모든 LABEL, JUMP, CJUMP 은 Basic Block 에서 속해야만한다 .
Basic Block
Tracevoid trace(LinkedList<Tree.Stm> l) {
for(;;) { 현재 block 의 label 을 hash table 에서 삭제
if( 현재 block 의 마지막 label 이 JUMP) {
if(JUMP 가 가리키는 곳이 block 일 경우 ) {JUMP / label 삭제Statement list l 에 statement 추가 Hash table 에서 label 삭제
} else {재귀 호출을 통해 hash table 의 다음 label 로
}} else if ( 현재 block 의 마지막 label 이 CJUMP) {
…} else {
error}
}
( 변경전 Temp 레지스터 t101, t102 사용 )add t101 t101 t102 # t101 = t101 + t102 ( 변경후 새로운 Temp 레지스터 t201, t202 발생 )lw t201 mem(for t101) # t101 에 해당하는 메모리 주소에서 값을 읽어 t201 에
저장lw t202 mem(for t102) # t102 에 해당하는 메모리 주소에서 값을 읽어 t202 에
저장add t201 t201 t202 # t201 = t201 + t202sw mem(for 101) t201 # t101 에 해당하는 메모리 주소에 t201 값을 저장
Liveness Analysis &Register Allocation
lw $t0 mem(for t101) # t101 에 해당하는 메모리 주소에서 값을 읽어 $t0 에 저장lw $t1 mem(for t102) # t102 에 해당하는 메모리 주소에서 값을 읽어 $t1 에 저장add $t0 $t0 $t1 # $t0 = $t0 + $t1sw mem(for 101) $t0 # t101 에 해당하는 메모리 주소에 $t0 값을 저장