Course project of Compile Principle in CS, ZJU.
Reference from CS375: UT
Materials: ftp://ftp.cs.utexas.edu/pub/novak/cs375/
SPL is a Simple Pascal Language. The target is to compile SPL programs into x86 assemble codes.
- I'm not good at Pascal & X86 asm, so the result might be wrong.
- At least there's no running bug within test files.
Lexical Analyzer - lexer
-
lexan.l
-
mainlexer.c
-
Makefile
-
lexan.h *
-
token.h *
-
printtoken.c *
$ make clean
$ make lexer
$ ./lexer < [SPL-file]
yylex() = 304 tokenType: 2 which: 17 program
yylex() = 258 tokenType: 3 value: graph1
yylex() = 270 tokenType: 1 which: 8 ;
yylex() = 313 tokenType: 2 which: 26 var
yylex() = 258 tokenType: 3 value: i
yylex() = 268 tokenType: 1 which: 6 ,
yylex() = 258 tokenType: 3 value: lim
yylex() = 269 tokenType: 1 which: 7 :
yylex() = 319 tokenType: 2 which: 32 SYS_TYPE
yylex() = 270 tokenType: 1 which: 8 ;
yylex() = 289 tokenType: 2 which: 2 begin
yylex() = 258 tokenType: 3 value: lim
yylex() = 282 tokenType: 0 which: 12 :=
yylex() = 260 tokenType: 5 type: 0 7
yylex() = 270 tokenType: 1 which: 8 ;
yylex() = 296 tokenType: 2 which: 9 for
yylex() = 258 tokenType: 3 value: i
yylex() = 282 tokenType: 0 which: 12 :=
yylex() = 260 tokenType: 5 type: 0 0
yylex() = 310 tokenType: 2 which: 23 to
yylex() = 258 tokenType: 3 value: lim
yylex() = 292 tokenType: 2 which: 5 do
yylex() = 318 tokenType: 2 which: 31 SYS_PROC
yylex() = 263 tokenType: 1 which: 1 (
yylex() = 262 tokenType: 6 value: *
yylex() = 264 tokenType: 1 which: 2 )
yylex() = 270 tokenType: 1 which: 8 ;
yylex() = 295 tokenType: 2 which: 8 end
yylex() = 271 tokenType: 0 which: 1 .
Syntax Analysis - parser
Modified/new files
- parse.y
- parse.h
- parsefun.c
- mainparser.c
- pprint.c *
- pprint.h
- symtab.c *
- symtab.h *
- symtab.txt *
$ make clean
$ make parser
$ ./parser < [SPL-file]
yyparse result = 0
token 140443849342752 OP program dtype 0 link 0 operands 140443849339712
(program graph1 (progn (:= lim 7)
(progn (:= i 0)
(label 0)
(if (<= i lim)
(progn (funcall write
'*')
(:= i (+ i 1))
(goto 0))))))
Code Generator - compiler
- codegen.c
- codegen.h
- maincompiler.c
- genasm.c *
- genasm.h *
$ make clean
$ make compiler
$ ./compiler < [SPL-file]
# ---------------------- Beginning of Generated Code --------------------
.file "foo"
.text
.globl graph1
.type graph1, @function
graph1:
.LFB0:
.cfi_startproc
pushq %rbp # save base pointer on stack
.cfi_def_cfa_offset 16
movq %rsp, %rbp # move stack pointer to base pointer
.cfi_offset 6, -16
.cfi_def_cfa_register 6
subq $32, %rsp # make space for this stack frame
movq %rbx, %r9 # save %rbx (callee-saved) in %r9
# ------------------------- begin Your code -----------------------------
jmp .L0 # jump
.L0:
movl $7,%eax # 7 -> %eax
movl %eax,-28(%rbp) # %eax -> lim
movl $0,%eax # 0 -> %eax
movl %eax,-32(%rbp) # %eax -> i
.L1:
movl -32(%rbp),%eax # i -> %eax
movl -28(%rbp),%ecx # lim -> %ecx
cmpl %ecx,%eax # compare %eax - %ecx
jle .L2 # jump if <=
jmp .L3 # jump
.L2:
movl $.LC4,%edi # addr of literal .LC4
call write # write()
movl -32(%rbp),%eax # i -> %eax
movl $1,%ecx # 1 -> %ecx
addl %ecx,%eax # %eax + %ecx -> %eax
movl %eax,-32(%rbp) # %eax -> i
jmp .L1 # jump
.L3:
# ----------------------- begin Epilogue code ---------------------------
movq %r9, %rbx # restore %rbx (callee-saved) from %r9
leave
ret
.cfi_endproc
.LFE0:
.size graph1, .-graph1
# ----------------- end Epilogue; Literal data follows ------------------
.section .rodata
.align 4
.LC4:
.string "*"
.ident "Compiler Principle - Spring 2017"
run 80386 asm file
- It's fine to run Part1-3 on Mac OS. However Part4 must run on Linux, because our assembly grammar is for Linux.
- There are some bugs, if you use SPL-files other than test1.spl/test2.spl/test6.spl, you might get errors.
- The program name must be "test", which you should find in driver.c
- driver.c
$ ./compiler < test2.spl > test2.s
$ cc driver.c test2.s -lm
$ ./a.out
test2.spl compute fibonacci(10).
calling test
55
exit from test