Download Context-Sensitive Analysis and Attribute Grammars in Compiler Design and more Study notes Computer Science in PDF only on Docsity! Context-sensitive analysis What context-sensitive questions might the compiler ask? 1. Is x a scalar, an array, or a function? 2. Is x declared before it is used? 3. Are any names declared but not used? 4. Which declaration of x does this reference? 5. Is an expression type-consistent? 6. Does the dimension of a reference match the declaration? 7. Where can x be stored? (heap, stack, . . . ) 8. Does *p reference the result of a malloc()? 9. Is x defined before it is used? 10. Is an array reference in bounds? 11. Does function foo produce a constant value? These cannot be answered with a context-free grammar CMSC 430 Lecture 6, Page 1 Context-sensitive analysis Why is context-sensitive analysis hard? • need non-local information • answers depend on values, not on syntax • answers may involve computation How can we answer these questions? 1. use context-sensitive grammars • general problem is P-space complete 2. use attribute grammars • augment context-free grammar with rules • calculate attributes for grammar symbols 3. use ad hoc techniques • augment grammar with arbitrary code • execute code at corresponding reduction • store information in attributes, symbol tables CMSC 430 Lecture 6, Page 2 Attribute grammars Attribute grammar • generalization of context-free grammar • each grammar symbol has an associated set of attributes • augment grammar with rules that define values • high-level specification, independent of evaluation scheme Dependences between attributes • values are computed from constants & other attributes • synthesized attribute – value computed from children • inherited attribute – value computed from siblings & parent CMSC 430 Lecture 6, Page 3 Example attribute grammar A grammar to evaluate signed binary numbers due to Scott K. Warren, Rice Ph.D. Production Evaluation Rules 1 NUM ::= SIGN LIST LIST.pos← 0 NUM.val ← if SIGN.neg then -LIST.val else LIST.val 2 SIGN ::= + SIGN.neg ← false 3 SIGN ::= - SIGN.neg ← true 4 LIST ::= BIT BIT.pos← LIST.pos LIST.val ← BIT.val 5 LIST0 ::= LIST1 BIT LIST1.pos ← LIST0.pos + 1 BIT.pos← LIST0.pos LIST0.val ← LIST1.val + BIT.val 6 BIT ::= 0 BIT.val ← 0 7 BIT ::= 1 BIT.val ← 2BIT.pos CMSC 430 Lecture 6, Page 4 Example attribute grammar val: -5NUM neg: TSIGN - pos: 0 val: 5 LIST pos: 1 val: 4 LIST pos: 2 val: 4 LIST pos: 2 val: 4 BIT 1 pos: 1 val: 0 BIT 0 pos: 0 val: 1 BIT 1 • val and neg are synthesized attributes • pos is an inherited attribute CMSC 430 Lecture 6, Page 5 Syntax-directed translation Disadvantages of attribute grammars • handling non-local information, locating answers • storage management, avoiding circular evaluation Syntax-directed translation • allow arbitrary actions • provide central repository • can place actions amid production Examples • YACC — A ::= B C { $$ = concat($1,$2); } • CUP — A:n ::= B:m C:p {: n = concat(m,p); :} Typical uses • build abstract syntax tree & symbol table • perform error/type checking CMSC 430 Lecture 6, Page 6 Abstract syntax tree An abstract syntax tree (AST) is the procedure’s parse tree with the nodes for most non-terminal symbols removed. - <id,x> * <num,2> <id,y> This represents “x - 2 * y”. For ease of manipulation, can use a linearized (operator) form of the tree. x 2 y * - in postfix form. A popular intermediate representation. CMSC 430 Lecture 6, Page 7 Symbol tables A symbol table associates values or attributes (e.g., types and values) with names. What should be in a symbol table? • variable and procedure names • literal constants and strings What information might compiler need? • textual name • data type • declaring procedure • lexical level of declaration • if array, number and size of dimensions • if procedure, number and type of parameters CMSC 430 Lecture 6, Page 8