//以下のプログラムは、山下義行「コンパイラ入門」 //(サイエンス社)の中のプログラムの抜粋である。 // 原則として、図x.yに記載したCプログラムには、 //figx_y.cの名称を付けた。表x.yに記載したプロ //グラムには、tabx_y.cを付けた。 // 原則として、各Cプログラムは cc -c コマンド //コンパイルしてエラーが出ないように、#include //などを追加してある。 // ここに載せるファイルの名称は以下の通り。 // fig01_06.c // fig01_10.java // fig02_04.SL0 // fig02_05.SL1 // fig04_01.l // fig04_01v2.l // fig06.h // fig06_02.c // fig06_05.c // fig06_07.c // fig06_09.c // fig06_14.c // fig08_02.y // fig09_02.SL0 // fig09_04.h // fig09_06.SL1 // fig09_09.h // fig09_09.c // fig09_10.l // fig09_11.c // fig09_13.c // fig09_14.l // fig09_15.y // fig09_17.y // fig09_20.h // fig09_20.c // fig10_01.h // fig10_01.c // tab10_01.c // fig10_03.h // fig10_03.c // tab10_03.c // tab11.h // tab11_01.c // tab11_02.c // fig11_01.c // tab11_04.c // tab11_05.c // 問題があれば著者まで連絡してほしい。 // H20.6.30 山下義行 //******************************************** //***** 以下は、fig01_06.c **** //******************************************** //******************************************** //ここから #include int main(void){ int i; float sum = 0; for(i = 1; i <= 10; i++) sum += i; printf("%f_n",sum); } //ここまで //******************************************** //***** 以下は、fig01_10.java **** //******************************************** //******************************************** //ここから class Test { public static void main(String[] args){ float sum = 0; for(int i = 1; i <= 10; i++) sum += i; System.out.println(sum); } } //ここまで //******************************************** //***** 以下は、fig02_04.SL0 **** //******************************************** //******************************************** //ここから int x = 0, abc = 1, z1 = 66; int z2 = 77; !z2, abc; ! x; /* z1 is not used in this program */ //ここまで //******************************************** //***** 以下は、fig02_05.SL1 **** //******************************************** //******************************************** //ここから int x, abc = 2.1; float z1 = 1.7; ? x; int z2; z2 = 2*abc*(x-2.6)+z1; /* this is an assignment statement */ ! z2, abc+3.0; ! 1+2.0*3; //ここまで //******************************************** //***** 以下は、fig04_01.l **** //******************************************** //******************************************** //ここから %{ enum {INT = 1, FLOAT, ID, NUM, REAL, COMMA, EQ, EX, QU, SEMI, ADD, SUB, MUL, DIV, LPAR, RPAR, ERROR }; %} %% int { return INT; } float { return FLOAT; } [a-z][a-z0-9]* { return ID; } 0|[1-9][0-9]* { return NUM; } ([0-9]+"."[0-9]*)|([0-9]*"."[0-9]+) { return REAL; } "," { return COMMA; } "=" { return EQ; } "!" { return EX; } "?" { return QU; } ";" { return SEMI; } "+" { return ADD; } "-" { return SUB; } "*" { return MUL; } "/" { return DIV; } "(" { return LPAR; } ")" { return RPAR; } "_n"|" "|"_t" { } "/*"[a-z0-9 ]*"*/" { } . { return ERROR; } %% int yywrap(void){ return 1; } int main(void){ int t; while((t = yylex()) != 0) { printf("number = %d, string = '%s'_n",t,yytext); } } //ここまで //******************************************** //***** 以下は、fig04_01v2.l **** //5章以降で構文解析器に組み込む場合にはこちら //を用いること。fig04_01.l からトークンの宣言と //main関数を削除してある。 //******************************************** //******************************************** //ここから %% int { return INT; } float { return FLOAT; } [a-z][a-z0-9]* { return ID; } 0|[1-9][0-9]* { return NUM; } ([0-9]+"."[0-9]*)|([0-9]*"."[0-9]+) { return REAL; } "," { return COMMA; } "=" { return EQ; } "!" { return EX; } "?" { return QU; } ";" { return SEMI; } "+" { return ADD; } "-" { return SUB; } "*" { return MUL; } "/" { return DIV; } "(" { return LPAR; } ")" { return RPAR; } "_n"|" "|"_t" { } "/*"[a-z0-9 ]*"*/" { } . { return ERROR; } %% int yywrap(void){ return 1; } //ここまで //******************************************** //***** 以下は、fig06.h **** //このヘッダ・ファイルは構文解析器のコンパイル //に最低限必要である。 //******************************************** //******************************************** //ここから enum {INT = 1, FLOAT, ID, NUM, REAL, ADD, SUB, MUL, DIV, LPAR, RPAR, EQ, EX, QU, COMMA, SEMI, ERROR}; #define EoF 0 int gettoken(void); //ここまで //******************************************** //***** 以下は、fig06_02.c **** //******************************************** //******************************************** //ここから #include #include #include "fig06.h" void Z(void); void Stmt(void); void Exp(void); void error(void){ printf("syntax error_n"); exit(1); } int tok; int gettoken(void); void advance(void){ tok = gettoken(); } void eat(int t){ if(tok == t) advance(); else error(); } void eOf(void){ if(tok != EoF) error(); } int main(void){ advance(); Z(); } void Z(void) { Stmt(); eOf(); } void Stmt(void) { eat(EX); Exp(); } void Exp(void) { eat(NUM); } //ここまで //******************************************** //***** 以下は、fig06_05.c **** //******************************************** //******************************************** //ここから #include #include #include "fig06.h" void Z(void); void Stmt(void); void Tail(void); void Exp(void); void error(void){ printf("syntax error_n"); exit(1); } int tok; int gettoken(void); void advance(void){ tok = gettoken(); } void eat(int t){ if(tok == t) advance(); else error(); } void eOf(void){ if(tok != EoF) error(); } int main(void){ advance(); Z(); } void Z(void) { Stmt(); eOf(); } void Stmt(void) { switch(tok){ case LPAR: eat(LPAR); Stmt(); Tail(); break; case EX: eat(EX); Exp(); break; default: error(); } } void Tail(void) { switch(tok){ case RPAR: eat(RPAR); break; case SEMI: eat(SEMI); Stmt(); Tail(); break; default: error(); } } void Exp(void) { eat(NUM); } //ここまで //******************************************** //***** 以下は、fig06_07.c **** //******************************************** //******************************************** //ここから #include #include #include "fig06.h" void Z(void); void A(void); void B(void); void C(void); void error(void){ printf("syntax error_n"); exit(1); } int tok; int gettoken(void); void advance(void){ tok = gettoken(); } void eat(int t){ if(tok == t) advance(); else error(); } void eOf(void){ if(tok != EoF) error(); } int main(void){ advance(); Z(); } void Z(void) { A(); eOf(); } void A(void) { switch(tok){ case EX: B(); C(); break; case SEMI: eat(SEMI); break; default: error(); } } void B(void) { eat(EX); } void C(void) { switch(tok){ case EX: B(); break; case NUM: eat(NUM); break; default: error(); } } //ここまで //******************************************** //***** 以下は、fig06_09.c **** //******************************************** //******************************************** //ここから #include #include #include "fig06.h" void Z(void); void A(void); void B(void); void C(void); void error(void){ printf("syntax error_n"); exit(1); } int tok; int gettoken(void); void advance(void){ tok = gettoken(); } void eat(int t){ if(tok == t) advance(); else error(); } void eOf(void){ if(tok != EoF) error(); } int main(void){ advance(); Z(); } void Z(void) { A(); eOf(); } void A(void) { switch(tok){ case NUM: case EoF: B(); C(); break; case SEMI: eat(SEMI); break; default: error(); } } void B(void) { } void C(void) { switch(tok){ case NUM: eat(NUM); break; case EoF: B(); break; default: error(); } } //ここまで //******************************************** //***** 以下は、fig06_14.c **** //******************************************** //******************************************** //ここから #include #include #include "fig06.h" void Z(void); void Program(void); void DeclStmts(void); void DeclStmts2(void); void DeclStmt(void); void VarDefs(void); void VarDefs2(void); void PrintStmts(void); void PrintStmt(void); void VarRefs(void); void VarRefs2(void); void error(void){ printf("syntax error_n"); exit(1); } int tok; int gettoken(void); void advance(void){ tok = gettoken(); } void eat(int t){ if(tok == t) advance(); else error(); } void eOf(void){ if(tok != EoF) error(); } int main(void){ advance(); Z(); } void Z(void){ Program(); eOf(); } void Program(void){ DeclStmts(); PrintStmts(); } void DeclStmts(void){ DeclStmt(); eat(SEMI); DeclStmts2(); } void DeclStmts2(void){ switch(tok){ case EX: case EoF: break; case INT: DeclStmts(); break; default: error(); } } void DeclStmt(void){ eat(INT); VarDefs(); } void VarDefs(void){ eat(ID); eat(EQ); eat(NUM); VarDefs2(); } void VarDefs2(void){ switch(tok){ case COMMA: eat(COMMA); eat(ID); eat(EQ); eat(NUM); VarDefs2(); break; case SEMI: break; default: error(); } } void PrintStmts(void){ switch(tok){ case EX: PrintStmt(); eat(SEMI); PrintStmts(); break; case EoF: break; default: error(); } } void PrintStmt(void){ eat(EX); VarRefs(); } void VarRefs(void){ eat(ID); VarRefs2(); } void VarRefs2(void){ switch(tok){ case COMMA: eat(COMMA); eat(ID); VarRefs2(); break; case SEMI: break; default: error(); } } //ここまで //******************************************** //***** 以下は、fig08_02.y **** //******************************************** //******************************************** //ここから %token INT, FLOAT, ID, NUM, REAL, COMMA, EQ, EX, QU, SEMI, ADD, SUB, MUL, DIV, LPAR, RPAR, ERROR; %% Program : DeAsInStmts PrintStmts {} DeAsInStmts : DeclStmt SEMI {} | DeAsInStmts DeAsInStmt SEMI {} DeAsInStmt : DeclStmt {} | AssignStmt {} | InputStmt {} DeclStmt : Type VarDefs {} Type : INT {} | FLOAT {} VarDefs : VarDef {} | VarDefs COMMA VarDef {} VarDef : ID {} | ID EQ NumReal {} AssignStmt : ID EQ Exp {} InputStmt : QU VarRefs {} VarRefs : ID {} | VarRefs COMMA ID {} PrintStmts : /* empty */ {} | PrintStmts PrintStmt SEMI {} PrintStmt : EX Exps {} Exps : Exp {} | Exps COMMA Exp {} Exp : Exp ADD Term {} | Exp SUB Term {} | Term {} Term : Term MUL Factor {} | Term DIV Factor {} | Factor {} Factor : ID {} | NumReal {} | LPAR Exp RPAR {} NumReal : NUM {} | REAL {} %% #include "lex.yy.c" int main(){ if(!yyparse()) printf("successfully ended_n"); } void yyerror(char* s){ fprintf(stderr,"%s_n",s); } //ここまで //******************************************** //***** 以下は、fig09_02.SL0 **** //これはfig02_04.SL0と同じ //******************************************** //******************************************** //ここから int x = 0, abc = 1, z1 = 66; int z2 = 77; !z2, abc; ! x; /* z1 is not used in this program */ //ここまで //******************************************** //***** 以下は、fig09_04.h **** //******************************************** //******************************************** //ここから typedef struct _node { int label; int type; char *name; int ival; float fval; struct _node *left; struct _node *right; } node; enum {TINT, TFLOAT }; //ここまで //******************************************** //***** 以下は、fig09_06.SL1 **** //これはfig02_05.SL1と同じ //******************************************** //******************************************** //ここから int x, abc = 2.1; float z1 = 1.7; ? x; int z2; z2 = 2*abc*(x-2.6)+z1; /* this is an assignment statement */ ! z2, abc+3.0; ! 1+2.0*3; //ここまで //******************************************** //***** 以下は、fig09_09.h **** //******************************************** //******************************************** //ここから enum { TProgram,TDeAsInSeq,TDecl,TAssign,TInput,TPrintSeq, TPrint,TNewline,TAdd,TSub,TMul,TDiv,TVar,TInt,TFloat }; node *newTProgram(node *left, node *right); node *newTDeAsInSeq(node *left, node *right); node *newTDecl(char *name, int type, node *left); node *newTAssign(char *name, node *left); node *newTInput(char *name); node *newTPrintSeq(node *left, node *right); node *newTPrint(node *left); node *newTNewline(); node *newTAdd(node *left, node *right); node *newTSub(node *left, node *right); node *newTMul(node *left, node *right); node *newTDiv(node *left, node *right); node *newTVar(char* name); node *newTInt(int ival); node *newTFloat(float fval); node *append(node *a, node *b); node *newnode(int label, int type, char *name, int ival, float fval, node *left, node *right); //ここまで //******************************************** //***** 以下は、fig09_09.c **** //これはfig09_09.h の関数の実装例である。 //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" node *newnode(int label, int type, char *name, int ival, float fval, node *left, node *right){ node* np = (node*) malloc(sizeof(node)); np->label = label; np->type = type; np->name = name; np->ival = ival; np->fval = fval; np->left = left; np->right = right; return np; } node *newTProgram(node *left, node *right){ return newnode(TProgram,-1,NULL,0,0,left,right); } node *newTDeAsInSeq(node *left, node *right){ return newnode(TDeAsInSeq,-1,NULL,0,0,left,right); } node *newTDecl(char *name, int type, node *left){ return newnode(TDecl,type,name,0,0,left,NULL); } node *newTAssign(char *name, node *left){ return newnode(TAssign,-1,name,0,0,left,NULL); } node *newTInput(char *name){ return newnode(TInput,-1,name,0,0,NULL,NULL); } node *newTPrintSeq(node *left, node *right){ return newnode(TPrintSeq,-1,NULL,0,0,left,right); } node *newTPrint(node *left){ return newnode(TPrint,-1,NULL,0,0,left,NULL); } node *newTNewline(){ return newnode(TNewline,-1,NULL,0,0,NULL,NULL); } node *newTAdd(node *left, node *right){ return newnode(TAdd,-1,NULL,0,0,left,right); } node *newTSub(node *left, node *right){ return newnode(TSub,-1,NULL,0,0,left,right); } node *newTMul(node *left, node *right){ return newnode(TMul,-1,NULL,0,0,left,right); } node *newTDiv(node *left, node *right){ return newnode(TDiv,-1,NULL,0,0,left,right); } node *newTVar(char *name){ return newnode(TVar,-1,name,0,0,NULL,NULL); } node *newTInt(int ival){ return newnode(TInt,TINT,NULL,ival,0,NULL,NULL); } node *newTFloat(float fval){ return newnode(TFloat,TFLOAT,NULL,0,fval,NULL,NULL); } node *append(node* ap, node* bp){ if(ap == NULL) return bp; else{ node* np = ap; while(np->right != NULL) np = np->right; np->right = bp; return ap; } } //ここまで //******************************************** //***** 以下は、fig09_10.l **** //******************************************** //******************************************** //ここから %{ enum { INT = 1, ID, NUM, COMMA, EQ, EX, SEMI, ERROR }; node *lval; %} %% int { return INT; } [a-z][a-z0-9]* { lval = newTVar(strdup(yytext)); return ID; } 0|[1-9][0-9]* { lval = newTInt(strtol(yytext,NULL,10)); return NUM; } "," { return COMMA; } "=" { return EQ; } "!" { return EX; } ";" { return SEMI; } " "|"_n"|"_t" { } "/*"[a-z0-9 ]*"*/" { } . { return ERROR; } %% int yywrap(){ return 1; } //ここまで //******************************************** //***** 以下は、fig09_11.c **** //このプログラムはfig09_12.cに含めた。 //******************************************** //******************************************** //******************************************** //***** 以下は、fig09_12.c **** //******************************************** //******************************************** //ここから #include #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig09_20.h" #include "lex.yy.c" #define EoF 0 node *Z(void); node *Program(void); node *DeclStmts(void); node *DeclStmts2(void); node *DeclStmt(void); node *VarDefs(void); node *VarDefs2(void); node *PrintStmts(void); node *PrintStmt(void); node *VarRefs(void); node *VarRefs2(void); void error(){ fprintf(stderr,"syntax error_n"); exit(1); } int tok; void advance(void){ tok = yylex(); } node *eat(int t){ node *p = lval; if(tok == t) advance(); else error(); return p; } void eOf(void){ if(tok != EoF) error(); } int main(){ node *np; advance(); np = Z(); print(np); } node *Z(){ node *np1; np1 = Program(); eOf(); return np1; } node *Program(void){ node *np1,*np2; np1 = DeclStmts(); np2 = PrintStmts(); return newTProgram(np1, np2); } node *DeclStmts(void){ node *np1,*np3; np1 = DeclStmt(); eat(SEMI); np3 = DeclStmts2(); return append(np1,np3); } node *DeclStmts2(void){ node *np1; switch(tok){ case EX: case EoF: return NULL; case INT: np1 = DeclStmts(); return np1; default: error(); } } node *DeclStmt(void){ node *np2; eat(INT); np2 = VarDefs(); return np2; } node *VarDefs(void){ node *np1,*np3,*np4; np1 = eat(ID); eat(EQ); np3 = eat(NUM); np4 = VarDefs2(); return newTDeAsInSeq( newTDecl( np1->name, TINT, np3), np4); } node *VarDefs2(void){ node *np2,*np4,*np5; switch(tok){ case COMMA: eat(COMMA); np2 = eat(ID); eat(EQ); np4 = eat(NUM); np5 = VarDefs2(); return newTDeAsInSeq( newTDecl( np2->name, TINT, np4), np5); case SEMI: return NULL; default: error(); } } node *PrintStmts(void){ node *np1,*np3; switch(tok){ case EX: np1 = PrintStmt(); eat(SEMI); np3 = PrintStmts(); return append(np1,np3); case EoF: return NULL; default: error(); } } node *PrintStmt(void){ node *np2; eat(EX); np2 = VarRefs(); return append( np2, newTPrintSeq( newTNewline(), NULL)); } node *VarRefs(void){ node *np1,*np2; np1 = eat(ID); np2 = VarRefs2(); return newTPrintSeq( newTPrint(np1), np2); } node *VarRefs2(void){ node *np2,*np3; switch(tok){ case COMMA: eat(COMMA); np2 = eat(ID); np3 = VarRefs2(); return newTPrintSeq( newTPrint(np2), np3); case SEMI: return NULL; default: error(); } } //ここまで //******************************************** //***** 以下は、fig09_13.c **** //このプログラムは fig09_13.c に含めた。 //******************************************** //******************************************** //******************************************** //***** 以下は、fig09_14.l **** //******************************************** //******************************************** //ここから %% int { return INT; } float { return FLOAT; } [a-z][a-z0-9]* { yylval = newTVar(strdup(yytext)); return ID; } 0|[1-9][0-9]* { yylval = newTInt(strtol(yytext,NULL,10)); return NUM; } ([0-9]+"."[0-9]*)|([0-9]*"."[0-9]+) { yylval = newTFloat(strtof(yytext,NULL)); return REAL; } "," { return COMMA; } "=" { return EQ; } "!" { return EX; } "?" { return QU; } ";" { return SEMI; } "+" { return ADD; } "-" { return SUB; } "*" { return MUL; } "/" { return DIV; } "(" { return LPAR; } ")" { return RPAR; } "_n"|" "|"_t" { } "/*"[a-z0-9 ]*"*/" { } . { return ERROR; } %% int yywrap(){ return 1; } //ここまで //******************************************** //***** 以下は、fig09_15.y **** //このプログラムは、fig09_16.yに含めた。 //******************************************** //******************************************** //******************************************** //***** 以下は、fig09_16.y **** //******************************************** //******************************************** //ここから %token INT, FLOAT, ID, NUM, REAL, COMMA, EQ, EX, QU, SEMI, ADD, SUB, MUL, DIV, LPAR, RPAR, ERROR; %{ #include #include "fig09_04.h" #include "fig09_09.h" #include "fig09_20.h" #define YYSTYPE node* int declType; %} %% Program : DeAsInStmts PrintStmts { $$ = newTProgram( $1, $2); } DeAsInStmts : DeclStmt SEMI { $$ = $1; } | DeAsInStmts DeAsInStmt SEMI { $$ = append($1,$2); } DeAsInStmt : DeclStmt { $$ = $1; } | AssignStmt { $$ = $1; } | InputStmt { $$ = $1; } DeclStmt : Type VarDefs { $$ = $2; } Type : INT { declType = TINT; } | FLOAT { declType = TFLOAT; } VarDefs : VarDef { $$ = newTDeAsInSeq( $1, NULL); } | VarDefs COMMA VarDef { $$ = append( $1, newTDeAsInSeq( $3, NULL)); } VarDef : ID { $$ = newTDecl( $1->name, declType, newTInt(0)); } | ID EQ NumReal { $$ = newTDecl( $1->name, declType, $3); } AssignStmt : ID EQ Exp { $$ = newTDeAsInSeq( newTAssign( $1->name, $3), NULL); } InputStmt : QU VarRefs { $$ = $2; } VarRefs : ID { $$ = newTDeAsInSeq( newTInput( $1->name), NULL); } | VarRefs COMMA ID { $$ = append( $1, newTDeAsInSeq( newTInput($3->name), NULL)); } PrintStmts : /* empty */ { $$ = NULL; } | PrintStmts PrintStmt SEMI { $$ = append($1,$2); } PrintStmt : EX Exps { $$ = append( $2, newTPrintSeq( newTNewline(), NULL)); } Exps : Exp { $$ = newTPrintSeq( newTPrint($1), NULL); } | Exps COMMA Exp { $$ = append( $1, newTPrintSeq( newTPrint($3), NULL)); } Exp : Exp ADD Term { $$= newTAdd($1,$3); } | Exp SUB Term { $$= newTSub($1,$3); } | Term { $$ = $1; } Term : Term MUL Factor { $$= newTMul($1,$3); } | Term DIV Factor { $$= newTDiv($1,$3); } | Factor { $$ = $1; } Factor : ID { $$ = $1; } | NumReal { $$ = $1; } | LPAR Exp RPAR { $$ = $2; } NumReal : NUM { $$ = $1; } | REAL { $$ = $1; } %% #include "lex.yy.c" int main(int argc, char *argv[]) { if(!yyparse()){ print(yyval); } } void yyerror(char* s){ fprintf(stderr,"%s_n",s); } //ここまで //******************************************** //***** 以下は、fig09_17.y **** //このプログラムは、fig09_16.yに含めた。 //******************************************** //******************************************** //******************************************** //***** 以下は、fig09_20.h **** //******************************************** //******************************************** //ここから void print(node* np); void print2(node* np, int); //ここまで //******************************************** //***** 以下は、fig09_20.c **** //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig09_20.h" #include "fig10_03.h" void printSpc(int d){ int i; for(i = 0; i < d; i++) putchar(' '); } char* getStrType(node* np){ if(np->type < 0) return "?"; else if(np->type == TINT) return "I"; else if(np->type == TFLOAT) return "F"; else { fprintf(stderr,"ERROR 10_n"); exit(1); } } void print(node *np){ print2(np,0); } void print2(node *np, int d){ if(np == NULL){ printSpc(d); printf("->NULL_n"); }else{ switch(np->label){ case TProgram: printSpc(d); printf("->TProgram_n"); print2(np->left,d+2); print2(np->right,d+2); break; case TDeAsInSeq: printSpc(d); printf("->TDeAsInSeq_n"); print2(np->left,d+2); print2(np->right,d+2); break; case TDecl: printSpc(d); printf("->TDecl(%s,%s)_n",getStrType(np),np->name); print2(np->left,d+2); break; case TAssign: printSpc(d); printf("->TAssign(%s,%s)_n",getStrType(np),np->name); print2(np->left,d+2); break; case TInput: printSpc(d); printf("->TInput(%s,%s)_n",getStrType(np),np->name); break; case TPrintSeq: printSpc(d); printf("->TPrintSeq_n"); print2(np->left,d+2); print2(np->right,d+2); break; case TPrint: printSpc(d); printf("->TPrint(%s)_n",getStrType(np)); print2(np->left,d+2); break; case TNewline: printSpc(d); printf("->TNewline_n"); break; case TAdd: printSpc(d); printf("->TAdd(%s)_n",getStrType(np)); print2(np->left,d+2); print2(np->right,d+2); break; case TSub: printSpc(d); printf("->TSub(%s)_n",getStrType(np)); print2(np->left,d+2); print2(np->right,d+2); break; case TMul: printSpc(d); printf("->TMul(%s)_n",getStrType(np)); print2(np->left,d+2); print2(np->right,d+2); break; case TDiv: printSpc(d); printf("->TDiv(%s)_n",getStrType(np)); print2(np->left,d+2); print2(np->right,d+2); break; case TVar: printSpc(d); printf("->TVar(%s,%s)_n",getStrType(np),np->name); break; case TInt: printSpc(d); printf("->TInt(%s,%d)_n",getStrType(np),np->ival); break; case TFloat: printSpc(d); printf("->TFloat(%s,%f)_n",getStrType(np),np->fval); break; case TI2F: printSpc(d); printf("->TI2F(F)_n"); print2(np->left,d+2); break; case TF2I: printSpc(d); printf("->TF2I(I)_n"); print2(np->left,d+2); break; default: fprintf(stderr,"i-tree error %d_n",np->label); exit(1); } } } //ここまで //******************************************** //***** 以下は、fig10_01.h **** //******************************************** //******************************************** //ここから void putVar(char* name, int type); int getType(char* name); void updateVar(char *name, node *val); node *getVal(char* name); void printTable(); #define N 1000 //ここまで //******************************************** //***** 以下は、fig10_01.c **** //これは、fig10_01.hの実装例である。 //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig10_01.h" char *STname[N]; int STtype[N]; node *STval[N]; int STidx = 0; void putVar(char* name, int type){ int i; for(i = 0; i < STidx; i++){ if(strcmp(name,STname[i]) == 0){ fprintf(stderr, "multiple declaration: %s_n",name); exit(1); } } if(STidx == N){ fprintf(stderr,"symbol table overflow_n"); exit(1); } STname[STidx] = name; STtype[STidx] = type; STidx++; } int getType(char* name){ int i; for(i = 0; i < STidx; i++){ if(strcmp(name,STname[i]) == 0) return STtype[i]; } fprintf(stderr,"no declaration: %s_n",name); exit(1); } node *getVal(char* name){ int i; for(i = 0; i < STidx; i++){ if(strcmp(name,STname[i]) == 0) return STval[i]; } fprintf(stderr,"no declaration: %s_n",name); exit(1); } void updateVar(char* name, node *val){ int i; for(i = 0; i < STidx; i++){ if(strcmp(name,STname[i]) == 0) { STval[i] = val; return; } } fprintf(stderr,"no declaration: %s_n",name); exit(1); } void printTable(){ int i; for(i = 0; i < STidx; i++){ switch(STtype[i]){ case TINT: printf("%d : int %s_n",i,STname[i]); break; case TFLOAT: printf("%d : float %s_n",i,STname[i]); break; default: fprintf(stderr,"ERROR: printTable %d_n",STtype[i]); exit(1); } } } //ここまで //******************************************** //***** 以下は、tab10_01.c **** //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig10_01.h" void checkSem(node* np){ if(np == NULL) return; switch(np->label){ case TDecl: putVar(np->name,np->type); break; case TInput: case TVar: getType(np->name); break; case TAssign: getType(np->name); checkSem(np->left); break; case TPrint: checkSem(np->left); break; case TProgram: case TDeAsInSeq: case TPrintSeq: case TAdd: case TSub: case TMul: case TDiv: checkSem(np->left); checkSem(np->right); } } //ここまで //******************************************** //***** 以下は、fig10_03.h **** //******************************************** //******************************************** //ここから enum { TI2F = TFloat+1, TF2I }; node *newTI2F(node *left); node *newTF2I(node *left); node *castType(node *np, int type); //ここまで //******************************************** //***** 以下は、fig10_03.c **** //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig10_03.h" node *newTI2F(node *left){ return newnode(TI2F,TFLOAT,NULL,0,0,left,NULL); } node *newTF2I(node *left){ return newnode(TF2I,TINT,NULL,0,0,left,NULL); } node *castType(node *np, int type){ if(np->type != type){ if(type == TINT) { printf("warning: assignment to `int' from `float'_n"); return newTF2I(np); } else return newTI2F(np); } else return np; } //ここまで //******************************************** //***** 以下は、tab10_03.c **** //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig10_01.h" #include "fig10_03.h" void insertType(node *np){ if(np == NULL) return; switch(np->label){ case TDecl: np->left = castType(np->left,np->type); break; case TInput: case TVar: np->type = getType(np->name); break; case TAssign: np->type = getType(np->name); insertType(np->left); np->left = castType(np->left,np->type); break; case TPrint: insertType(np->left); np->type = np->left->type; break; case TProgram: case TDeAsInSeq: case TPrintSeq: insertType(np->left); insertType(np->right); break; case TAdd: case TSub: case TMul: case TDiv: insertType(np->left); insertType(np->right); if(np->left->type == np->right->type) { np->type = np->left->type; } else { np->left = castType(np->left,TFLOAT); np->right = castType(np->right,TFLOAT); np->type = TFLOAT; } } } //ここまで //******************************************** //***** 以下は、tab11.h **** //これは、tab11_01.cなどに必要なヘッダ・ //ファイルである。 //******************************************** //******************************************** //ここから node *evalExp(node*); void eval(node*); int genExp(node*); void gen(node*); extern FILE* code; //ここまで //******************************************** //***** 以下は、tab11_01.c **** //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig10_01.h" #include "fig10_03.h" #include "tab11.h" node *evalExp(node *np){ node *left,*right; switch(np->label){ case TAdd: left = evalExp(np->left); right = evalExp(np->right); if(np->type == TINT) return newTInt(left->ival + right->ival); else return newTFloat(left->fval + right->fval); case TSub: left = evalExp(np->left); right = evalExp(np->right); if(np->type == TINT) return newTInt(left->ival - right->ival); else return newTFloat(left->fval - right->fval); case TMul: left = evalExp(np->left); right = evalExp(np->right); if(np->type == TINT) return newTInt(left->ival * right->ival); else return newTFloat(left->fval * right->fval); case TDiv: left = evalExp(np->left); right = evalExp(np->right); if(np->type == TINT) return newTInt(left->ival / right->ival); else return newTFloat(left->fval / right->fval); case TVar: return getVal(np->name); case TInt: case TFloat: return np; case TI2F: left = evalExp(np->left); return newTFloat((float)left->ival); case TF2I: left = evalExp(np->left); return newTInt((int)left->fval); } } //ここまで //******************************************** //***** 以下は、tab11_02.c **** //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig10_01.h" #include "fig10_03.h" #include "tab11.h" void eval(node *np){ node *left; static int numPrint = 0; if(np == NULL) return; switch(np->label){ case TProgram: case TDeAsInSeq: case TPrintSeq: eval(np->left); eval(np->right); break; case TDecl: case TAssign: updateVar(np->name,evalExp(np->left)); break; case TInput: if(np->type == TINT){ int i; scanf("%d",&i); updateVar(np->name,newTInt(i)); }else{ float f; scanf("%f",&f); updateVar(np->name,newTFloat(f)); } break; case TPrint: if(numPrint++ > 0) printf(","); left = evalExp(np->left); if(np->type == TINT) printf("%d",left->ival); else printf("%f",left->fval); break; case TNewline: printf("_n"); numPrint = 0; } } //ここまで //******************************************** //***** 以下は、fig11_01.c **** //******************************************** //******************************************** //ここから int main(int argc, char *argv[]) { if(argc > 1) { yyin = fopen(argv[1], "r"); if(!yyin){ fprintf(stderr,"fopen error_n"); exit(1); } }else { fprintf(stderr,"arg error_n"); exit(1); } if(!yyparse()){ ... } } //ここまで //******************************************** //***** 以下は、tab11_04.c **** //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig10_01.h" #include "fig10_03.h" #include "tab11.h" FILE *code; int genExp(node *np){ static int iregnum = 1; static int fregnum = 1; int left,right; switch(np->label){ case TAdd: left = genExp(np->left); right = genExp(np->right); if(np->type == TINT){ fprintf(code,"add.i r%d = r%d,r%d_n",iregnum,left,right); return iregnum++; }else{ fprintf(code,"add.f f%d = f%d,f%d_n",fregnum,left,right); return fregnum++; } case TSub: left = genExp(np->left); right = genExp(np->right); if(np->type == TINT){ fprintf(code,"sub.i r%d = r%d,r%d_n",iregnum,left,right); return iregnum++; }else{ fprintf(code,"sub.f f%d = f%d,f%d_n",fregnum,left,right); return fregnum++; } case TMul: left = genExp(np->left); right = genExp(np->right); if(np->type == TINT){ fprintf(code,"mul.i r%d = r%d,r%d_n",iregnum,left,right); return iregnum++; }else{ fprintf(code,"mul.f f%d = f%d,f%d_n",fregnum,left,right); return fregnum++; } case TDiv: left = genExp(np->left); right = genExp(np->right); if(np->type == TINT){ fprintf(code,"div.i r%d = r%d,r%d_n",iregnum,left,right); return iregnum++; }else{ fprintf(code,"div.f f%d = f%d,f%d_n",fregnum,left,right); return fregnum++; } case TVar: if(np->type == TINT) { fprintf(code,"load.i r%d = [&%s]_n",iregnum,np->name); return iregnum++; }else{ fprintf(code,"load.f f%d = [&%s]_n",fregnum,np->name); return fregnum++; } case TInt: fprintf(code,"const.i r%d = %d_n",iregnum,np->ival); return iregnum++; case TFloat: fprintf(code,"const.f f%d = %f_n",fregnum,np->fval); return fregnum++; case TI2F: fprintf(code,"conv.fi f%d = r%d_n",fregnum,genExp(np->left)); return fregnum++; case TF2I: fprintf(code,"conv.if r%d = f%d_n",iregnum,genExp(np->left)); return iregnum++; } } //ここまで //******************************************** //***** 以下は、tab11_05.c **** //******************************************** //******************************************** //ここから #include #include #include "fig09_04.h" #include "fig09_09.h" #include "fig10_01.h" #include "fig10_03.h" #include "tab11.h" void gen(node *np){ int left; static int numPrint = 0; if(np == NULL) return; switch(np->label){ case TProgram: case TDeAsInSeq: case TPrintSeq: gen(np->left); gen(np->right); break; case TDecl: case TAssign: if(np->type == TINT){ fprintf(code,"store.i [&%s] = r%d_n",np->name,genExp(np->left)); }else{ fprintf(code,"store.f [&%s] = f%d_n",np->name,genExp(np->left)); } break; case TInput: if(np->type == TINT){ fprintf(code,"call in_int_n"); fprintf(code,"store.i [&%s] = r0_n",np->name); }else{ fprintf(code,"call in_float_n"); fprintf(code,"store.f [&%s] = f0_n",np->name); } break; case TPrint: if(numPrint++ > 0) fprintf(code,"call out_comma_n"); left = genExp(np->left); if(np->type == TINT){ fprintf(code,"move.i r0 = r%d_n",left); fprintf(code,"call out_int_n"); }else{ fprintf(code,"move.f f0 = f%d_n",left); fprintf(code,"call out_float_n"); } break; case TNewline: fprintf(code,"call out_newline_n"); numPrint = 0; } } //ここまで //以上