n fact tc n main c gcc int

  • Slides: 49
Download presentation

コンパイル例 n fact. tc n main. c (このファイルはgccでコンパイル) int fact(int n) { if (n

コンパイル例 n fact. tc n main. c (このファイルはgccでコンパイル) int fact(int n) { if (n == 1) return 1; else return n * fact(n-1); } #include <stdio. h> main() { printf("%dn", fact(10)); } n gccと同一の stack layout / calling convention

Tiny Cコンパイラの出力 (テキストファイル) fact. asm: fact L 2 L 1 GLOBAL fact push ebp

Tiny Cコンパイラの出力 (テキストファイル) fact. asm: fact L 2 L 1 GLOBAL fact push ebp mov ebp, esp cmp dword [8+ebp], 1 jne L 2 mov eax, 1 jmp L 1 mov eax, [8+ebp] sub eax, 1 push eax call fact add esp, 4 imul eax, [8+ebp] pop ebp ret

lexが出力するCファイルの内容 #include "calc. tab. h" … int yylex() { … yylval = atoi(yytext); return

lexが出力するCファイルの内容 #include "calc. tab. h" … int yylex() { … yylval = atoi(yytext); return INTEGER; … } /* Cコードセクションのコード */ …

yaccファイルの例 %token INTEGER %% program: /* empty */ | program expr 'n' ; expr:

yaccファイルの例 %token INTEGER %% program: /* empty */ | program expr 'n' ; expr: INTEGER | expr '+' INTEGER | expr '-' INTEGER ; %% int yyerror(char *s) { … } main() { yyparse(); } 定義 セクション { printf("%dn", $2); } { $$ = $1 + $3; } { $$ = $1 - $3; } ルール セクション Cコード セクション

yaccファイルの例 %token INTEGER %% program: /* empty */ | program expr 'n' ; expr:

yaccファイルの例 %token INTEGER %% program: /* empty */ | program expr 'n' ; expr: INTEGER | expr '+' INTEGER | expr '-' INTEGER ; %% int yyerror(char *s) { … } main() { yyparse(); } { printf("%dn", $2); } { $$ = $1 + $3; } { $$ = $1 - $3; } ルール セクション

lexファイル %{ #include "calc. tab. h" %} %% {digit}+ { yylval = atoi(yytext); return

lexファイル %{ #include "calc. tab. h" %} %% {digit}+ { yylval = atoi(yytext); return INTEGER; "-"|"+"|n } return *yytext; yaccファイル %token INTEGER %% program: /* empty */ | program expr 'n' ; expr: INTEGER | expr '+' INTEGER | expr '-' INTEGER ; { printf("%dn", $2); } { $$ = $1 + $3; } { $$ = $1 - $3; }

Makefileの例 タブ文字 n YACC=bison YFLAGS= -d LEX=flex LFLAGS= OBJS = bar. tab. o lex.

Makefileの例 タブ文字 n YACC=bison YFLAGS= -d LEX=flex LFLAGS= OBJS = bar. tab. o lex. yy. o all: a. out bar. tab. c: bar. y $(YACC) $(YFLAGS) bar. y lex. yy. c: foo. l bar. tab. h $(LEX) $(LFLAGS) foo. l a. out: $(OBJS) $(CC) –o $@ $(OBJS) OBJS のリストの並び順によっては以下も必要 bar. tab. h: bar. y $(YACC) $(YFLAGS) bar. y

共用体 struct st 1 { … }; struct st 2 { … }; union

共用体 struct st 1 { … }; struct st 2 { … }; union un { struct st 1 s 1; struct st 2 s 2; }; n union un *u = (union un *) malloc(sizeof(union un)); u->st 1. ? ? ? = …; n sizeof(union un):s 1 または s 2 を格納するのに十分 n なサイズ u は st 2 として再利用可

yaccファイルでの%union指定 n %union { int i; char *str; tree n; } トークンIdentifierの値は • 型treeの宣言を持つヘッダファイルを用意してyaccファイルの先

yaccファイルでの%union指定 n %union { int i; char *str; tree n; } トークンIdentifierの値は • 型treeの宣言を持つヘッダファイルを用意してyaccファイルの先 文字列(char *)型 頭でインクルード n n n %token <str> Identifier %token <i> Constant %token IF ELSE WHILE… yylval. i = atoi(yytext); yylval. str = strdup(yytext); %type <n> program … 非終端記号programの値は tree型

opt の扱い 2 a: bopt c d  ↓ a: c d |bcd ; a:

opt の扱い 2 a: bopt c d  ↓ a: c d |bcd ; a: bopt c d x: a |y  ↓ a_aux: c d ; x: a_aux | b a_aux |y ;

5. Misc

5. Misc