cse443 compilers
play

CSE443 Compilers Dr. Carl Alphonce ruhansa@buffalo.edu Ruhan Sa - PowerPoint PPT Presentation

CSE443 Compilers Dr. Carl Alphonce ruhansa@buffalo.edu Ruhan Sa alphonce@buffalo.edu 343 Davis Hall http:/ /www.cse.buffalo.edu/faculty/alphonce/SP17 /CSE443/index.php https:/ /piazza.com/class/iybn4ndqa1s3ei Phases of a compiler


  1. CSE443 Compilers Dr. Carl Alphonce ruhansa@buffalo.edu Ruhan Sa alphonce@buffalo.edu 343 Davis Hall http:/ /www.cse.buffalo.edu/faculty/alphonce/SP17 /CSE443/index.php https:/ /piazza.com/class/iybn4ndqa1s3ei

  2. Phases of a compiler Semantic analysis Figure 1.6, page 5 of text

  3. Semantics • “Semantics” has to do with the meaning of a program. • We will consider two types of semantics: – Static semantics: semantics which can be enforced at compile-time. – Dynamic semantics: semantics which express the run-time meaning of programs.

  4. Static semantics • Semantic checking which can be done at compile-time • Type-compatibility is a prime example – int can be assigned to double (type coercion) – double cannot be assigned to int without explicit type cast • Type-compatibility can be captured in grammar, but only at expense of larger, more complex grammar

  5. Ex: adding type rules in grammar • Must introduce new non-terminals which encode types: • Instead of a generic grammar rule for assignment: – <stmt> � <var> ‘=’ <expr> ‘;’ • we need multiple rules: – <stmt> � <doubleVar> ‘=’ <intExpr> | <doubleExpr> ‘;’ – <stmt> � <intVar> ‘=’ <intExpr> ‘;’ • Of course, such rules need to handle all the relevant type possibilities (e.g. byte , char , short , int , long , float and double ).

  6. Alternative: attribute grammars • Attribute grammars provide a neater way of encoding such information. • Each syntactic rule of the grammar can be decorated with: – a set of semantic rules/functions – a set of semantic predicates

  7. Attributes • We can associate with each symbol X of the grammar a set of attributes A(X). Attributes are partitioned into: synthesized attributes S(X) – pass info up parse tree inherited attributes I(X) – pass info down parse tree

  8. Semantic rules/functions • We can associate with each rule R of the grammar a set of semantic functions. • For rule X0 � X1 X2 … Xn – synthesized attribute of LHS: S(X0) = f(A(X1), A(X2), …, A(Xn)) – inherited attribute of RHS member: for 1<=j<=n, I(Xj) = f(A(X0),…,A(Xj-1)) (note that dependence is on siblings to left only)

  9. Predicates • We can associate with each rule R of the grammar a set of semantic predicates. • Boolean expression involving the attributes and a set of attribute values • If true , node is ok • If false , node violates a semantic rule

  10. Example <assign> � <var> = <expr> <expr>.expType � <var>.actType <expr> � <var>[2] + <var>[3] Start with a production of the grammar <expr>.actType � if (var[2].actType = int) and (var[3].actType = int) then int else real <expr>.actType == <expr>.expType <expr> � <var> <expr>.actType � <var>.actType <expr>.actType == <expr>.expType Syntactic rule <var> � A | B | C Semantic rule/function <var>.actType � lookUp(<var>.string) Semantic predicate

  11. Example <assign> � <var> = <expr> <expr>.expType � <var>.actType <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and Associate an attribute with a non- (var[3].actType = int) then int terminal, <expr>, on the right of the else real production: expType (the expected type <expr>.actType == <expr>.expType of the expression) <expr> � <var> <expr>.actType � <var>.actType <expr>.actType == <expr>.expType Syntactic rule <var> � A | B | C Semantic rule/function <var>.actType � lookUp(<var>.string) Semantic predicate

  12. Example <assign> � <var> = <expr> <expr>.expType � <var>.actType <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and Assign to <expr>.expType the value of (var[3].actType = int) then int <var>.actType, the actual type of the else real <expr>.actType == <expr>.expType variable (the type the variable was declared as). <expr> � <var> <expr>.actType � <var>.actType <expr>.actType == <expr>.expType Syntactic rule <var> � A | B | C Semantic rule/function <var>.actType � lookUp(<var>.string) Semantic predicate

  13. Example <assign> � <var> = <expr> <expr>.expType � <var>.actType <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and In other words, we expect the expression (var[3].actType = int) then int whose value is being assigned to a else real <expr>.actType == <expr>.expType variable to have the same type as the variable. <expr> � <var> <expr>.actType � <var>.actType <expr>.actType == <expr>.expType Syntactic rule <var> � A | B | C Semantic rule/function <var>.actType � lookUp(<var>.string) Semantic predicate

  14. Example <assign> � <var> = <expr> <expr>.expType � <var>.actType <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and (var[3].actType = int) then int else real Another grammar production <expr>.actType == <expr>.expType <expr> � <var> <expr>.actType � <var>.actType <expr>.actType == <expr>.expType Syntactic rule <var> � A | B | C Semantic rule/function <var>.actType � lookUp(<var>.string) Semantic predicate

  15. Example Syntactic rule <assign> � <var> = <expr> Semantic rule/function <expr>.expType � <var>.actType Semantic predicate <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and (var[3].actType = int) then int else real <expr>.actType == <expr>.expType This production has a more involved <expr> � <var> semantic rule: it handles type coercion. <expr>.actType � <var>.actType <expr>.actType == <expr>.expType This rule assume that there are only two numeric types (int and real) and that int <var> � A | B | C <var>.actType � lookUp(<var>.string) can be coerced to real.

  16. Example Syntactic rule <assign> � <var> = <expr> Semantic rule/function <expr>.expType � <var>.actType Semantic predicate <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and (var[3].actType = int) then int else real <expr>.actType == <expr>.expType <expr> � <var> Here is our first semantic predicate, <expr>.actType � <var>.actType <expr>.actType == <expr>.expType which enforces a type-checking constraint: the actual type of <expr> must <var> � A | B | C <var>.actType � lookUp(<var>.string) match the expected type (from elsewhere in the tree)

  17. Example Syntactic rule <assign> � <var> = <expr> Semantic rule/function <expr>.expType � <var>.actType Semantic predicate <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and (var[3].actType = int) then int else real <expr>.actType == <expr>.expType Another <expr> � <var> <expr>.actType � <var>.actType production, with <expr>.actType == <expr>.expType a semantic rule <var> � A | B | C and a semantic <var>.actType � lookUp(<var>.string) predicate.

  18. Example Syntactic rule <assign> � <var> = <expr> Semantic rule/function <expr>.expType � <var>.actType Semantic predicate <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and (var[3].actType = int) then int else real This semantic rule <expr>.actType == <expr>.expType says that the type <expr> � <var> of an identifier is <expr>.actType � <var>.actType <expr>.actType == <expr>.expType determined by <var> � A | B | C looking up its <var>.actType � lookUp(<var>.string) type in the symbol table.

  19. All the productions, rules and predicates <assign> � <var> = <expr> <expr>.expType � <var>.actType <expr> � <var>[2] + <var>[3] <expr>.actType � if (var[2].actType = int) and (var[3].actType = int) then int else real <expr>.actType == <expr>.expType <expr> � <var> <expr>.actType � <var>.actType <expr>.actType == <expr>.expType Syntactic rule <var> � A | B | C Semantic rule/function <var>.actType � lookUp(<var>.string) Semantic predicate

  20. Let's see how these rules work in practice! <assign> In this example A and B are both of type int. <expr> <var> <var>[2] <var>[3] Suppose: A = A + B A is int B is int

  21. Effects of the syntactic <assign> rules is shown in red. expected actual type = <expr> type = int int actual type = int <var> <var>[2] <var>[3] actual actual type = type = actual type = int int int Suppose: A = A + B A is int B is int

Recommend


More recommend