160 likes | 238 Views
Final Project. Description. Enhance the compiler in HW3 PL/0 instead of a subset of PL/0 Procedures Procedure calls, including recursive calls Begin, End statement If statement While statement. Change to Symbol Table.
E N D
Description • Enhance the compiler in HW3 • PL/0 instead of a subset of PL/0 • Procedures • Procedure calls, including recursive calls • Begin, End statement • If statement • While statement
Change to Symbol Table • The symbol table must be expanded to include attributes which allows the compiler to associate literal numbers and addresses with each identifier declared • For example • Identifier of a constant – constant value • Identifier of a variable – address, L and M • Identifier of a procedure – entry address and level
Common Mistakes in HW3 • No driver • You are making a real compiler. The input is the source file. The output is the bytecode file. • Should not require the user to run scanner, parser, and then the virtual machine • No code generation • Code is generated in parser
Code Generation Example <expression> [+ | - ] <term> {( + | - ) <term>} void expression() { IF ((token == plus) || (token == minus)) { addop = token; /*delaying the transmission of the arithmetic operator*/ GetToken; Term; IF (addop == minus) emit (opr, 0, 1 ) ; //Negate } ELSE Term; WHILE ((token == plus) || (token == minus)) { addop = token; GetToken; Term ; IF (addop == plus) emit (opr, 0, 2 ); /* addition */ ELSE emit (opr, 0, 3 ); /* substraction */ } } “The procedure emit(opcode, level, modifier) generates code” a := -5 a := b+c-7
Sources to Help You • In the following URL you will find the original PL/0 compiler written by Niklaus Wirth in Pascal: http://www.246.dk/pl0.html • In this URL: http://www.cosc.canterbury.ac.nz/tad.takaoka/cosc230/p1.c you will find a PL/0 compiler in C. • Do not copy. We will check.
Code Example – Main() Scan, Parse, and Code Generation Code Execution main(argc,argv) int argc; char *argv[]; { … getsym(); block(0,0); interpret(); … }
Code Example – Block() block(lev, tx) { … do { if (sym==constsym) { … } if (sym==varsym) { … } while(sym==procsym) { … } }while ((sym==constsym)||(sym==varsym)||(sym==procsym)); gen(inc, 0, 3+variable#); statement(le v,&tx); gen(opr,0,0); } 4. const, var, procedure must be followed by identifier. 5. Semicolon or comma missing. <statement> ::= <ident> := <expression> | call <ident> | begin <statement-list> end | if <condition> then <statement> | while <condition> do <statement> | e
Code Example – Block() while(sym==procsym) { getsym(); if(sym==ident){ enter(procedure,&tx,&dx,lev); getsym(); } else error(4); if (sym==semicolon) getsym(); else if (sym==lparen); else error(5); block(lev+1, tx); if(sym==semicolon) { getsym(); } else error(5); }
Code Example – Becomes Statement 11. Undeclared identifier. 12. Assignment to constant or procedure is not allowed. 13. Assignment operator expected. statement(lev,ptx) int lev, *ptx; { int i, cx1,cx2; if (sym==ident){ i=position(id,ptx); if(i==0) error(11); else if (table[i].kind!=variable) { error(12); i=0; }; getsym(); if (sym==becomes) getsym(); else error(13); expression(lev,ptx); if (i!=0) gen(sto, lev-table[i].level, table[i].adr); } else a:=5+b void emit(int op, int l, int m) { if(cx > CODE_SIZE) error(25); else { code[cx].op = op; //opcode code[cx].l = l; // lexicographical level code[cx].m = m; // modifier cx++; } }
Code Example – Call Statement if (sym==callsym) { getsym(); if (sym!=ident) error(14); else { i=position(id, ptx); if(i==0) error(11); else if (table[i].kind==procedure) gen(cal,lev-table[i].level, table[i].adr); else error(15); getsym(); } } else call fact; 11. Undeclared identifier. 14. call must be followed by an identifier. 15. Call of a constant or variable is meaningless.
Code Example – If Statement if (sym==ifsym) { getsym(); condition(lev,ptx); if (sym==thensym) getsym(); else error(16); cx1=cx; gen(jpc,0,0); statement(lev, ptx); code[cx1].a=cx; } else if n = 0 then f := 1; code JPC 0 0 ctemp statement changes JPC 0 0 to JPC 0 cx statement statement cx
Code Example – Begin, End Statement begin <statement-list> end if (sym==beginsym) { getsym(); statement(lev,ptx); while((sym==semicolon)||(sym==beginsym)|| (sym==ifsym)||(sym==whilesym)|| (sym==callsym)||(sym==writesym)) { if(sym==semicolon) getsym(); else error(10); statement(lev,ptx); } if (sym==endsym) getsym(); else error(17); } else begin ans1:=n; n:= n-1; if n = 0 then f := 1; if n > 0 then call fact; f:=f*ans1; end; 17. Semicolon or end expected.
Code Example – While Statement if (sym==whilesym) { cx1=cx; getsym(); condition(lev,ptx); cx2=cx; gen(jpc,0,0); if (sym==dosym) getsym(); else error(18); statement(lev,ptx); gen(jmp,0,cx1); code[cx2].a=cx; } else WHILE a > c DO a++ ; 18. do expected.
Code Example – Write Statement if (sym==writesym) { getsym(); if (sym!=lparen) error(98); else { getsym(); expression(lev, ptx); gen(wrt,0,0); if (sym!=rparen) error(99); else getsym(); } } } 98. Left parenthesis missing 99. Right parenthesis missing <expression> ::= <term> | <adding-operator> <term> | <expression> <adding-operator> <term>