1 / 45

コード生成(2)

コード生成(2). コード生成プログラム セマンティックアクション. 宣言,変数表. K言語    main(){ int a,b,sum; b=a+3; }. アセンブラ PUSHI 1 PUSH 0 PUSHI 3 ADD ASSGN REMOVE. 左辺 bのD番地. D番地. type. 右辺 aのD番地. 変数表. size. 数値3. 代入. 変数名. <Exp>::=<Term> “+” <Term>. b + 7 PUSH 1 0 PUSHI  7

palti
Download Presentation

コード生成(2)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. コード生成(2) コード生成プログラム セマンティックアクション

  2. 宣言,変数表 K言語    main(){ int a,b,sum; b=a+3; } アセンブラ PUSHI 1 PUSH 0 PUSHI 3 ADD ASSGN REMOVE 左辺 bのD番地 D番地 type 右辺 aのD番地 変数表 size 数値3 代入 変数名

  3. <Exp>::=<Term>“+”<Term> b+7 PUSH 10 PUSHI 7 ADD void parseExp(){ parseTerm(); if(token.checkSymbol(ADD))nextToken(); parseTerm(); appendCode(Operator.ADD); }

  4. if(a) b=3; a=0番地,b=10番地,c=20番地 とする 100  PUSH0 101  BEQ  106 102  PUSHI 10 103  PUSHI 3 104  ASSGN 105  REMOVE 106  appendCode replaceCode

  5. 変数表に関するセマンティックアクション VarTable varTable; 変数追加,Dseg番地を返す adr=varTable.addElement(type,name,size) 番地取得 varTable.getAddress(name)

  6. VSMのコード生成→iseg.の省略 命令だけのコード iseg.appendCode(opCode) 命令+アドレス iseg.appendcode(opCode,adr) アドレス変更 iseg.replaceCode(ptr番地,adr行先番地)    例: ptr番地  BEQadr行先番地 現在のiseg番地 iseg.getAddress()

  7. 最後にHALT void parseProgram(){ parseMain_function(); appendCode(HALT); } Operator.HALT を省略

  8. Var_decl(1) 初期値設定なし • <Var_decl> ::= “int” <Var1> { “,” <Var1> } • <Var1> ::= NAME | NAME “[“ INTEGER “]”

  9. Var_decl ⇒変数表に追加,配列 void parseVar_decl1(){int adr; String name=token.getString(); if(token.checkSymbol(NAME)) nextToken(); if(token.checkSymbol(LBRACKET)){ nextToken(); if(token.checkSymbol(INTEGER)){ adr=varTable.addVar(INTARRAY,name, token.getIntValue()); nextToken();} if(token.checkSymbol(RBRACKET)) nextToken();} elseadr=varTable.addVar(INTSCALAR,name, 1); ........

  10. Var_decl(2) 初期値設定あり • <Var_decl> ::= “int” <Var1> { “,” <Var1> } • <Var1> ::= NAME [ “=“ [ “-”] INTEGER ] | NAME “[“ INTEGER “]”

  11. Var_decl ⇒変数表に追加,初期値設定 void parseVar_decl1(){int adr; String name=token.getString(); if(token.checkSymbol(NAME)) nextToken(); if(token.checkSymbol(LBRACKET)){       ................ else { adr=varTable.addVar(name, INTSCALAR, 1); if(token.checkSymbol(ASSIGN)){int sign=1;nextToken(); appendCode(PUSHI,varTable.getAddress(name)); if(token.checkSymbol(SUB)){sign = -1;nextToken();} if(token.checkSymbol(INTEGER)){ appendCode(PUSHI,sign*token.getIntValue()); nextToken(); appendCode(ASSGN); appendCode(REMOVE);}

  12. ★<if>::=“if” ”(“ <expression> “)” <statement> void parseIf(){ if(token.checkSymbol(IF))nextToken(); if(token.checkSymbol(LPAREN))nextToken(); parseExpression(); int adr=appendCode(Operator.BEQ,-1); if(token.checkSymbol(RPAREN)))nextToken(); parseStatement(); replaceCode(adr, iseg.getAddress()); }

  13. どの位置にセマンティックアクションをいれるか?どの位置にセマンティックアクションをいれるか? • <While_state> ::= “while” “(” <Expression> “)” <State> void parseWhile_state(){ ? int isegAdr1=getIsegPtr(); if(symbol==Symbol.WHILE) nextToken(); ? int isegAdr1=getIsegPtr(); if(symbol==Symbol.LPAREN) nextToken(); ? int isegAdr1=getIsegPtr(); parseExpression(); //意味がある場所 ? int isegAdr2=appendCode(Operators.BEQ ); if(symbol==Symbol.RPAREN)nextToken(); ? int isegAdr2=appendCode(Operators.BEQ); parseState(); //意味がある場所 appendCode(Operators.JUMP,isegAdr1); replaceCode(isegAdr2);}

  14. 式[簡単化している] <Exp_statement> ::= <expression> “;” <expression>::=<Exp> [ “=“ <expression> ] <Exp>::= <Term> { “+” <Term> } <Term>::= NAME

  15. 式の最後 <Exp_statement> ::= <expression> “;” a=b; PUSHI aの番地 PUSHbの番地 ASSGN REMOVE セミコロン→REMOVE

  16. <Exp_statement> ::= <expression> “;” void parseExp_Statement(){ parseExpression(); if(token.checkSymbol(SEMICOLON)){ appendCode(Operator.REMOVE); nextToken(); } else syntaxError("exp_statement"); }

  17. <expression>::=<Exp>[“=“ <expression>] void parseExpression(){ if(parseExp()){ if(token.checkSymbol(ASSIGN)){ nextToken(); parseExpression(); appendCode(Operator.ASSGN); } } }

  18. 加算 <Exp> ::= <Term> +<Term>; a=b+c; PUSHI aの番地 PUSHbの番地 PUSHcの番地 ADD ASSGN REMOVE Symbol.ADD→Operator.ADD

  19. <Exp>::=<Term>{“+”<Term>} boolean parseExp(){ boolean sahenp=parseTerm(true); while(token.checkSymbol(ADD)){ sahenp=false; nextToken(); parseTerm(false); appendCode(Operator.ADD); } return sahenp; }

  20. 変数(左辺? 右辺?) <Term> ::= NAME a=b pushi aの番地 pushbの番地 ASSGN 左辺 → pushi 右辺 → push

  21. <Term>::=NAME booelan parseTerm(boolean sahenp){ if(token.checkSymbol(NAME)){ String name=token.getString(); int adr=varTable.getAddress(name); nextToken(); if(sahenp && token.checkSymbol(ASSGN)) appendCode(PUSHI,adr); else { appendCode(PUSH,adr); sahenp=false; } return sahenp; }

  22. ASSIGN? ASSIGNADD? <Term> ::= NAME a+=b PUSHI aの番地 COPY LOAD PUSHbの番地 ADD ASSGN

  23. 代入文 = と += void parseExpression(){ if(parseExp()){ Symbol symbol=token.getSymbol(); if(symbol==ASSIGNADD){ appendCode(Operator.COPY); appendCode(Operator.LOAD);} nextToken(); parseExpression(); if(symbol==ASSIGNADD)appendCode(Operator.ADD); appendCode(Operator.ASSGN); insertAssignCode(type); } }

  24. Arithmetic_expression(1) void parseArithmetic_expression(){ parseArithmetic_term(); while(token.checkSymbol(ADD) || token.checkSymbol(SUB)){ SymbolopCode=token.getSymbol(); nextToken(); parseArithmetic_term(); if(opCode==Symbol.ADD) appendCode(Operator.ADD); elseappendCode(Operator.SUB); } }

  25. Arithmetic_expression(2) void parseArithmetic_expression(){ parseArithmetic_term(); while(token.checkSymbol(ADD) || token.checkSymbol(SUB)){ if(token.checkSymbol(ADD)){ nextToken(); parseArithmetic_term(); appendCode(Operator.ADD); } else { nextToken(); parseArithmetic_term(); appendCode(Operator.SUB); } } }

  26. 配列 NAME[<exp>] a[3]=b[5] PUSHI aの番地 PUSHI 3 ADD PUSHI bの番地 PUSHI5 ADD LOAD ASSGN

  27. 配列 elseif(curType==LEFT_BRACKET){ appendCode(Operator.PUSHI,varTable.getAddress(name)); nextToken(); parseExpression(); if(token.checkSymbol(RBRACKET)) nextToken(); appendCode(Operator.ADD); if(! sahenp) appendCode(Operator.LOAD);} }

  28. ★<Arithmetic_factor>::=“-” <Arithmetic_factor> |... void parseArithmetic_factor(){ if(token.checkSymbol(SUB)){ nextToken(); parseArithmetic_factor(); appendCode(Operator.CSIGN); } ............. }

  29. 後置INC NAME ++ a ++ PUSH aの番地 COPY INC POP aの番地

  30. ★後置INC elseif(token.checkSymbol(Symbol.INC)){ nextToken(); appendCode(Operator.PUSH,varTable.getAddress(name)); appendCode(Operator.COPY); appendCode(Operator.INC); appendCode(Operator.POP,varTable.getAddress(name)); }

  31. 前置DEC -- NAME  --a PUSH aの番地 DEC COPY POP aの番地

  32. 前置DEC elseif(token.checkSymbol(Symbol.DEC)){ nextToken(); if(token.checkSymbol(NAME)){ String name=token.getString(); appendCode(Operator.PUSH,varTable.getAddress(name)); appendCode(Operator.DEC); appendCode(Operator.COPY); appendCode(Operator.POP,varTable.getAddress(name)); nextToken(); } }

  33. ★ 論理演算 void insertLogicalCode(Symbol symbol){ appendCode(COMP); switch(symbol){ case EQUAL: appendCode(Operator.BEQ,iseg.getAddress()+3); break; case NOTEQ: appendCode(Operator.BNE,iseg.getAddress()+3); break; } appendCode(Operator.PUSHI,0); appendCode(Operator.JUMP, iseg.getAddress()+2); appendCode(Operator.PUSHI,1); }

  34. 属性文法 構文規則+意味規則 attribute grammar スタックマシン用コードの属性文法

  35. スタックマシン用コードの属性文法 構文規則        意味規則を書くために書き方を変える (0)S→E”$” S→E”$” (1)E→E”+”EE0→E1”+”E2 (2)E→E”*”EE0→E1”*”E2 (3)E→”(”E”)” E0→”(”E1”)” (4)E→”i” E→”i” (注)構文規則では単にEを    意味規則を記述するためE1,E2などと書く 同じEでも意味 (値)が異なる⇒ E0,E1,E2

  36. スタックマシン用コードの属性文法 構文規則          意味規則 (0)S→E”$” S.code=E.code (1)E0→E1”+”E2 E0.code=E1.code||E2.code||"ADD\n” (2)E0→E1”*”E2 E0.code=E1.code||E2.code||"MUL\n” (3)E0→”(”E1”)” E0.code=E1.code (4)E→”i” E.code="PUSH " || i.name || "\n” (注) || は文字列をつなぐ演算子とする.

  37. ★ 加算 構文規則          意味規則 E→T1”+”T2 E.code=T1.code||T2.code||"ADD\n” Javaプログラム void parseE(){ parseT(); if(token.checkSymbol(ADD)) nextToken(); parseT(); iseg.appendCode(“ADD\n”); } T.codeを生成 T.codeを生成

  38. 繰り返し加算 構文規則          意味規則 E→T1{“+”T2} E.code=T1.code{||T2.code||"ADD\n”} Javaプログラム void parseE(){ parseT(); while(token.checkSymbol(ADD)) { nextToken(); parseT(); iseg.appendCode(“ADD\n”); } } T.codeを生成 T.codeを生成

  39. 課題7:下記構文のコンパイラを書きなさい <Program>::=<Main_function> <Main_function>::= “main” “(“ “)” <Block> <Block>::= “{“ { <Var_decl> } { <Statement> } “}” <Var_decl>::= “int” NAME { “,” NAME } “;” <Statement>::= <Assignment> | “{“ <Statement> “}” | “;” <Assignment>::= <Lefthand_side> “=” <Arithmetic_expression> “;” <Lefthand_side>::= NAME <Arithmetic_expression>::=<Arithmetic_term> { (“+”|”-“) <Arithmetic_term> } <Arithmetic_term>::=<Arithmetic_factor> { (“*”|”/”|”%”) <Arithmetic_factor> } <Arithmetic_factor>::=<Unsigned_factor> | “-“ <Unsigned_factor> <Unsigned_factor>::=NAME | INTEGER | “(“ <Arithmetic_expression> “)”

  40. 小テスト

  41. 問題1 T→F{*F} T.code=F1.code {||F2.code ||“MUL\n”} ①appendCode(F1) ②appendCode(F2) ③appendCode(MUL) ④replaceCode(ADD) ⑤appendCode(F) ⑥正解なし (注) iseg.を省略 問(1) 実際にコードを 生成する部分は?

  42. 問題2 F→”-”F; F0.code=F1.code || ① “SUB\n” ② “MINUS” ③ “CSIGN\n” ④ appendCode(SUB) ⑤ appendCode(CSIGN) ⑥正解なし 問(2)

  43. 問題3 後置-- elseif(token.checkSymbol(DEC)){ getToken(); appendCode(PUSH, varTable.getAddress(name)); appendCode(COPY); appendCode(POP, varTable.getAddress(name)); } ①appendCode(SUB) ②appendCode(DEC) ③appendCode(PUSH) ④appendCode(LOAD) ⑤appendCode(PUSHI) ⑥正解なし 問(3)

  44. 問題4while void parseWhile(){ nextToken(); if(token.checkSymbol(LPAREN)) nextToken(); int adr1=iseg.getAddress(); parseExpression(); if(token.checkSymbol(RPAREN)) nextToken(); int adr2=appendCode(BEQ,-1); parseStatement(); appendCode(JUMP,adr1); int adr3=iseg.getAddress(); } ①appendCode(BEQ,adr1); ②replaceCode(adr2,adr3); ③replaceCode(adr1,adr2); ④BEQ adr2 ⑤aqppendCode(JUMP); ⑥正解なし 問(4)

  45. 問題5 “>=“ parseArithmetic_expression(); if(token.checkSymbol(GREATEQ)) { nextToken(); parseArithmetic_expression(); appendCode(COMP); appendCode(BGE, iseg.getAddress()+3); appendCode(JUMP, iseg.getAddress()+2); appendCode(PUSHI,1); } ①appendCode(PUSHI,1); ②appendCode(PUSH,1); ③appendCode(PUSH,0); ④appendCode(PUSHI,0); ⑤replaceCode(JUMP); ⑥正解なし 問(5)

More Related