1 / 23

Semantic Analysis

This article explores the importance of semantic analysis in programming languages and discusses syntax-directed translations. It covers scope rules, forward declarations, and name-type compatibility. Examples are provided using the languages C, Pascal, and Tiger.

hnickelson
Download Presentation

Semantic Analysis

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Semantic Analysis Mooly Sagiv Schrierber 317 03-640-7606 Wed 10:00-12:00 html://www.cs.tau.ac.il/~msagiv/courses/wcc02.html

  2. Outline • What is Semantic Analysis • Why is it needed? • Syntax directed translations • Semantic analysis in Tiger (Targil)

  3. Semantic Analysis • The “meaning of the program” • Requirements related to the “context” in which a construct occurs • Context sensitive requirements - cannot be specified using a context free grammar • Requires complicated and unnatural context free grammars

  4. Example Semantic Condition • In C (and Tiger)break statements can only occur inside switch or loop statements

  5. Partial Grammar for C Stm ::= Exp; Stm ::= if (Exp) Stm StList ::= StList Stm Stm ::= if (Exp) Stm else Stm StList ::=emptyString Stm ::= while (Exp) do Stm Stm ::= break; Stm ::= {StList }

  6. LStm ::= Exp; LStm ::= if (Exp) LStm LStm ::= if (Exp) LStm else LStm LStList ::= LStList LStm LStm ::= while (Exp) do LStm LStm ::= {LStList } LStList ::=emptyString LStm ::= break; Refined Grammar for C Stm ::= Exp; Stm ::= if (Exp) Stm StList ::= StList Stm Stm ::= if (Exp) Stm else Stm StList ::=emptyString Stm ::= while (Exp) do LStm Stm ::= {StList }

  7. A Possible Abstract Syntax for C typedef struct A_St_ *A_St; struct A_St { enum {A_if, A_while, A_break, A_block, ...} kind; A_pos pos; union { struct { A_Exp e; A_St st1; A_St st2; } if_st; struct { A_Exp e; A_St st; } while_st; struct { A_St st1; A_St st2; } block_st; ... } u ; } A_St A_IfStm(A_Exp, A_St, A_St); A_St A_WhileStm(A_Exp A_St); A_St A_BreakStm(void); A_St A_BlockStm(A_St, A_St);

  8. Partial Bison Specification stm : IF ‘(‘ exp ‘)’ stm { $$ = A_IfStm($3, $5, NULL) ; } | IF ‘(‘ exp ‘)’ stm ELSE stm { $$ = A_IfStm($3, $5, $7) ; } | WHILE ‘(‘ exp ‘)’ stm { $$ = A_WhileStm($3, $5); } | ‘{‘ stmList ‘}’ { $$ = $2; } | BREAK `;' { $$ = A_BreakStm(); } ; stmList :stmList st { $$ = A_BlockStm($1, $2) ;} | /* empty */ {$$ = NULL ;}

  9. A Semantic Check(on the abstract syntax tree) void check_break(A_St st) { switch (st->kind) { case A_if: check_break(st-> u.if_st.st1); check_break(st->u.if_st.st2); break; case A_while: break ; case A_break: error(“Break must be enclosed within a loop”, st->pos); break; case A_block: check_break(st->u.block_st.st1) check_break(st->u.block_st.st2); break; } }

  10. Syntax Directed Solution %{static int loop_count = 0 ;%} %% stm : exp ‘;’ | IF ‘(‘ exp ‘)’ stm | IF ‘(‘ exp ‘)’ stm ELSE stm | WHILE ‘(‘ exp ‘)’ m stm { loop_count--;} | ‘{‘ stmList ‘}’ | BREAK ‘;’ { if (!loop_count) error(“Break must be enclosed within a loop”, line_count); } ; stmList :stmList st | /* empty */ ; m : /* empty */ { loop_count++ ;} ;

  11. Problems with Syntax Directed Translations • Grammar specification may be tedious (e.g., to achieve LALR(1)) • May need to rewrite the grammar to incorporate different semantics • Modularity is impossible to achieve • Some programming languages allow forwarddeclarations (Algol, Tiger, ML and Java)

  12. Example Semantic Condition: Scope Rules • Variables must be defined within scope • Dynamic vs. Static Scope rules • Cannot be coded using a context free grammar

  13. Dynamic vs. Static Scope Rules procedure p; var x: integer procedure q ; begin { q } … x … end { q }; procedure r ; var x: integer begin { r } q ; end; { r } begin { p } q ; r ; end { p }

  14. Example Semantic Condition • In Pascal (and Tiger)Types in assignment must be “compatible”'

  15. Partial Grammar for Pascal Stm ::= id Assign Exp Exp ::= IntConst Exp ::= RealConst Exp::= Exp + Exp Exp::= Exp -Exp Exp::= ( Exp ) Refined Grammar for Pascal

  16. Syntax Directed Solution %% ... stm : id Assign exp {compat_ass(lookup($1), $4) ; } ; exp : exp PLUS exp {compat_op(PLUS, $1, $3); $$ = op_type(PLUS, $1, $3); } | exp MINUS exp {compat_op(MINUS, $1, $3); $$ = op_type(MINUS, $1, $3); } | ID { $$ = lookup($1); } | INCONST { $$= ty_int ; } | REALCONST { $$ = ty_real ;} | ‘(‘ exp ‘)’ { $$ = $2 ; } ;

  17. Features of Tiger • Static scoping • Possible forward declarations of (recursive) functions and structures • Name Type Compatibly

  18. Static Scoping of Tiger env0 function f(a: int, b: int, c: int) (print_int(a+c), let var j := a+b var a := “hello” in print(a); print_int(j) end; print_int(b) ) env1 =env0+[aint, bint, cint] env2 =env1 +[jint] env3=env2 + [astring] How to implement?

  19. Forward Declarations of Fields type intlist = {hd: int, tl: intlist} type tree = {key: int, children: treelist } type treelist = {hd: tree, tl: treelist}

  20. Forward Declarations of Functions type tree = {key: int, children: treelist } type treelist = {hd: tree, tl: treelist} function treeLeaves(t: tree): int = if t = nil then 1 else treeListLeaves(t.children) function treeListLeaves(L: treelist): int = if t = nil then 0 else treeLeaves(L.hd) + treeListLeaves(L.tl)

  21. Name Type Compatibility let type a = { x: int, y : int} type b = { x: int, y : int } var i: a := ... var j: b := ... in i := j let type a = { x: int, y : int } type b = a var i: a := ... var j: b := ... in i := j

  22. Type Checking Module • Top-down traversal on the syntax tree/* semant.h */void SEM_transProg(A_exp exp); • Imperative hashing symbol tables (two environments) • Use C equality for type checking • Process “headers” of recursive declarations first • Generate code for expressions (will be studied later)

  23. Summary • Several ways to enforce semantic correctness conditions • syntax • syntax directed • traversals on the abstract syntax tree • later compiler phases? • Runtime? • There are tools that automatically generate semantic analyzer from specification(Based on attribute grammars)

More Related