正在加载图片...
Here is an example of a simple Decaf program and its tac translation void maino[ mmain t ai int b t0=1; int C t1=2; b b=2; c= a+ b Print(c)i PushParam c LCall PrintInt Endfunc What we have to do is figure out how to get from one to the other as we This includes not only generating the TAC, but figuring out the use of temp variables, creating labels, calling functions, etc. Since we have a lot to do, we will make the mechanics of generating the tac as easy as possible. In our parser, we will create the TAC instructions one at a time. We can immediately print them out or store them for further processing. We will simplify the Decaf language a little by cluding doubles for code generation and internally treating bools as 4-byte integers. Classes arrays, and strings will be implemented with 4-byte pointers. This means we only ever need to deal with 4-byte integer/pointer variables As each production is reduced, we will create the necessary instructions. This strategy makes our code-generation a bit limited--particularly for the way we would have to do switch statements-but we can translate more-or-less any language structure into an executable program in a single pass without needing to go back and edit anything, which is pretty convenient To see how a syntax-directed translation can generate TAC, we need to look at the derivation, and figure out where the different TAC statements should be generated as the productions are reduced Lets start with a trivial program void main() main Print(hello world") Beginfunc; to =hello world"; LCall Printstringi Endfunc Notice that we call the built-in library function labelled PrintString to do the actual printing. The library functions are called like any ordinary global function, but the code is provided by the compiler as part of linking with the standard library. Here is the derivation of the source program The trick is to identify where and what processing occurs as these productions are reduced to generate the given TAC Type - void Stmtlist - Constant - stringConstant Expr - Constant ExprLlst - Expr Printstmt - Print( Exprlist Stmt - Printstmt i Stmtlist - stmtlist stmt StmtBlock - stmtlist FunctionDefn - Type identifier( Formals StmtBlock3 Here is an example of a simple Decaf program and its TAC translation: void main() { int a; int b; int c; a = 1; b = 2; c = a + b; Print(c); } main: BeginFunc; _t0 = 1; a = _t0; _t1 = 2; b = _t1; _t2 = a + b; c = _t2; PushParam c; LCall _PrintInt; EndFunc; What we have to do is figure out how to get from one to the other as we parse. This includes not only generating the TAC, but figuring out the use of temp variables, creating labels, calling functions, etc. Since we have a lot to do, we will make the mechanics of generating the TAC as easy as possible. In our parser, we will create the TAC instructions one at a time. We can immediately print them out or store them for further processing. We will simplify the Decaf language a little by excluding doubles for code generation and internally treating bools as 4-byte integers. Classes, arrays, and strings will be implemented with 4-byte pointers. This means we only ever need to deal with 4-byte integer/pointer variables. As each production is reduced, we will create the necessary instructions. This strategy makes our code-generation a bit limited—particularly for the way we would have to do switch statements—but we can translate more-or-less any language structure into an executable program in a single pass, without needing to go back and edit anything, which is pretty convenient. To see how a syntax-directed translation can generate TAC, we need to look at the derivation, and figure out where the different TAC statements should be generated as the productions are reduced. Let’s start with a trivial program: void main() { Print("hello world"); } main: BeginFunc; _t0 = "hello world"; PushParam _t0; LCall _PrintString; EndFunc; Notice that we call the built-in library function labelled _PrintString to do the actual printing. The library functions are called like any ordinary global function, but the code is provided by the compiler as part of linking with the standard library. Here is the derivation of the source program. The trick is to identify where and what processing occurs as these productions are reduced to generate the given TAC: Type -> void Formals -> StmtList -> Constant -> stringConstant Expr -> Constant ExprList -> Expr PrintStmt -> Print ( ExprList ) Stmt -> PrintStmt ; StmtList -> StmtList Stmt StmtBlock -> { StmtList } FunctionDefn -> Type identifier ( Formals ) StmtBlock
<<向上翻页向下翻页>>
©2008-现在 cucdc.com 高等教育资讯网 版权所有