11/8/2012 The Structure of a Compiler (2) The Structure of a Compiler (1) Any compiler must perform two major tasks Sourc rce Progra ram Tokens Syntactic Semantic Scanner Parser Structure re Routines (Chara racter r St Stre ream) Compiler Interm rmediate Representation Compiler Design and Construction Symbol and Analysis Synthesis Optimizer Attri ribute Semantic Analysis Tables Analysi ysis of the source program Slides modified from Louden Book, Dr. Scherger, & Y Chung (Used by all Phases of The Compiler) r) (NTHU), and Fischer, Leblanc Synthesis sis of a machine-language program Code Genera rator 3 2 Target machine code Source Code Semantic Processing Abstract Syntax Tree Compiler Stages Scanner Tokens Semantic routines interpret meaning based on syntactic 1 st step in semantic processing is to build a syntax tree structure of input (modern compilers do this) representing input program Parser Syntax Tree This makes the compilation syntax-directed Don't need literal parse tree Literal Semantic Intermediate nodes for precedence and associativity Table Semantic routines finish the analysis Analyzer Symbol e -rules Annotated Verify static semantics are followed Table Tree Source Code Just enough info to drive semantic processing Variables declared, compatible operands (type and #), etc. Optimizer Error Or even recreate input Handler Semantic routines also start the synthesis Intermediate Code Code Generate either IR or target machine code Generator Semantic processing performed by traversing the tree 1 The semantic action is attached to the productions (or Target or more times Code sub trees of a syntax tree). Target Code Optimizer Attributes attached to nodes aid semantic processing Target Chapter 1: Introduction January, 2010 5 Chapter 6:Semantic Analysis April, 2011 4 1
11/8/2012 7.1.1 Using a Syntax Tree Representation of a Parse (1) Abstract Syntax Tree Abstract Syntax Tree parse tree Parsing: <assign> build the parse tree := := <target> := <exp> Non-terminals for operator precedence and associatively are included. id <exp> + <term> Id + Id(Y) + <factor> <term> id <term> * <factoor> <factor> id * Id * Id(I) Semantic processing : Const build and decorate the A bstract S yntax T ree ( AST ) Const Id Const(3) Id(X) Non-terminals used for ease of parsing may be omitted in the abstract syntax tree. abstract syntax tree Abstract syntax tree for Y:=3*X+I Abstract syntax tree for Y:=3*X+I with initial := values id + id * 7 2012/11/8 const id 7.1.1 Using a Syntax Tree Representation of a Parse (2) Abstract Syntax Tree Abstract Syntax Tree Semantic routines traverse (post-order) the AST, computing attributes of the nodes of AST. Initially, attributes only at leaves :=(itof) Attributes propagate during the static semantic Initially, only leaves (i.e. terminals, e.g. const, id) have checking Id(Y)(f) +(i) attributes Processing declarations to build symbol table Find symbols in ST to get attributes to attach Ex. Y := 3*X + I * (i) Id(I,i) Determining expression/operand types := Declarations propagate top-down Const(3,i) Id(X,i) + Expressions propagate bottom-up id(Y) A tree is decorated after sufficient info for code * id(I) Abstract syntax tree for Y:=3*X+I with generation has propagated. propagated values const(3) id(X) 12 2012/11/8 2
11/8/2012 7.1.1 7.1.1 Static Semantic Checks Using a Syntax Tree Representation of a Parse (3) Using a Syntax Tree Representation of a Parse (4) The attributes are then propagated to other nodes using Static semantics can be checked at compile time After attribute propagation is done, some functions, e.g. the tree is decorated and ready for code generation, Check only propagated attributes build symbol table use another pass over the decorated AST to generate code. Type compatibility across assignment Int B; attach attributes of nodes B := 5.2; illegal check types, etc. B := 3; legal Actually, these can be combined in a single pass Build the AST Use attributes and structure bottom-up / top-down propagation Correct number and types of parameters Decorate the AST procedure foo(int a, float b, int c, float b); int C; Generate the target code <program> float D; ‘‘‘ ‘‘ ‘‘ <stmt> declaration call foo(C,D,3,2.9) legal ‘‘ := What we have described is essentially ‘‘‘‘‘ call foo(C,D,3.3, 2.9) illegal id + exp. the Attribute Grammars(AG) (Details in chap.14) call foo(1,2,3,4,5) illegal type symbol * id ‘ ‘‘‘check types: integer * or floating * table ” Need to consult symbol table for types of id’s. const id ‘‘‘ 15 Chapter 6:Semantic Analysis April, 2011 13 2012/11/8 14 2012/11/8 Dynamic Semantic Checks Translation Compiler Organization Some checks can’t be done at compile time Translation task uses attributes as data, but it is driven by one-pass compiler the structure Array bounds, arithmetic errors, valid addresses of pointers, Single pass used for both analysis and synthesis variables initialized before use. Translation output can be several forms Scanning, parsing, checking, & translation all interleaved, Some languages allow explicit dynamic semantic checks No explicit IR generated Machine code Semantic routines must generate machine code i.e. assert denominator not = 0 Intermediate representation Only simple optimizations can be performed Decorated tree itself T ends to be less portable These are handled by the semantic routines inserting Sent to optimizer or code generator code to check for these semantics Violating dynamic semantics result in exceptions 3
11/8/2012 7.1.2 Compiler Organization Compiler Organization Compiler Organization Alternatives (2) We prefer the code generator completely hides machine one-pass with peephole optimization one-pass analysis and IR synthesis plus a code generation details and semantic routines are independent of machines. pass Optimizer makes a pass over generated machine code, looking at a small number of instructions at a time Adds flexibility Allows for simple code generation Explicit IR created & sent to code generator Can be violated to produce better code. IR typically simple Suppose there are several classes of registers, each for a different purpose. Peephole: looking at only a few instructions at a time Optimization can examine as much of IR as wanted Better for register allocation to be performed by semantic Effectively a separate pass Less machine-dependent analysis routines than code generator since semantic routines have a So easier to retarget Simple but effective broader view of the AST. Simplifies code generator since there is a pass of post- processing. 19 2012/11/8 7.1.2 7.1.3 Compiler Organization Compiler Organization Alternatives (7) Single Pass (1) Multi-pass analysis Multi-language and multi-target compilers In Micro of chap 2, scanning, parsing and semantic processing Scan, then parse, then check declarations, then static semantics are interleaved in a single pass. Usually used to save space (memory usage or compiler) Components may be shared and parameterized. Ex : Ada uses Diana (language-dependent IR) (+) simple front-end Multi-pass synthesis (+) less storage if no explicit trees Separate out machine dependence Ex : GCC uses two IRs. Better optimization one is high-level tree-oriented (-) immediately available information is limited since no complete tree is built. Generate IR the other(RTL) is more machine-oriented Do machine independent optimization Generate machine code ..... FORTRAN PASCAL ADA C Machine dependent optimization Relationships Many complicated optimization and code generation algorithms require multiple passes semantic ..... rtn 1 i.e. optimizations that need a more global view call call machine-independent optimization semantic semantic scanner parser for I = 1 to N rtn 2 records tokens foo = 35*bar(i)+16; bar(i) { return 3;}; semantic rtn k SUN PC main-frame 23 2012/11/8 24 2012/11/8 language - and machine-independent IRs 4
Recommend
More recommend