Semantic Analysis with Emphasis on Name Analysis

Slides:



Advertisements
Similar presentations
CPSC 388 – Compiler Design and Construction
Advertisements

Semantic Analysis and Symbol Tables
Symbol Table.
Semantic Analysis Chapter 6. Two Flavors  Static (done during compile time) –C –Ada  Dynamic (done during run time) –LISP –Smalltalk  Optimization.
1 Mooly Sagiv and Greta Yorsh School of Computer Science Tel-Aviv University Modern Compiler Design.
Winter Compiler Construction T7 – semantic analysis part II type-checking Mooly Sagiv and Roman Manevich School of Computer Science Tel-Aviv.
(1) ICS 313: Programming Language Theory Chapter 10: Implementing Subprograms.
The Symbol Table Lecture 13 Wed, Feb 23, The Symbol Table When identifiers are found, they will be entered into a symbol table, which will hold.
ISBN Chapter 10 Implementing Subprograms.
Tutorial 6 & 7 Symbol Table
PZ09A Programming Language design and Implementation -4th Edition Copyright©Prentice Hall, PZ09A - Activation records Programming Language Design.
Chapter 9: Subprogram Control
Chapter 10 Implementing Subprograms. Copyright © 2007 Addison-Wesley. All rights reserved. 1–2 Semantics of Call and Return The subprogram call and return.
Cs164 Prof. Bodik, Fall Symbol Tables and Static Checks Lecture 14.
Compilation (Chapter 3) 1 Course Overview PART I: overview material 1Introduction 2Language processors (tombstone diagrams, bootstrapping) 3Architecture.
Semantic Analysis CS 671 February 5, CS 671 – Spring The Compiler So Far Lexical analysis Detects inputs with illegal tokens –e.g.: main$
1 Semantic Analysis Aaron Bloomfield CS 415 Fall 2005.
CS412/413 Introduction to Compilers and Translators Spring ’99 Lecture 8: Semantic Analysis and Symbol Tables.
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Basic Semantics Associating meaning with language entities.
Interpretation Environments and Evaluation. CS 354 Spring Translation Stages Lexical analysis (scanning) Parsing –Recognizing –Building parse tree.
1 Mooly Sagiv and Greta Yorsh School of Computer Science Tel-Aviv University Modern Compiler Design.
Semantic Analysis. Find 6 problems with this code. These issues go beyond syntax.
CSC3315 (Spring 2008)1 CSC 3315 Subprograms Hamid Harroud School of Science and Engineering, Akhawayn University
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
CS536 Semantic Analysis Introduction with Emphasis on Name Analysis 1.
1 Compiler & its Phases Krishan Kumar Asstt. Prof. (CSE) BPRCE, Gohana.
Semantic Analysis II Type Checking EECS 483 – Lecture 12 University of Michigan Wednesday, October 18, 2006.
10-1 Chapter 10: Implementing Subprograms The General Semantics of Calls and Returns Implementing “Simple” Subprograms Implementing Subprograms with Stack-Dynamic.
Implementing Subprograms
LECTURE 3 Compiler Phases. COMPILER PHASES Compilation of a program proceeds through a fixed series of phases.  Each phase uses an (intermediate) form.
PZ09A Programming Language design and Implementation -4th Edition Copyright©Prentice Hall, PZ09A - Activation records Programming Language Design.
1 Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
CS412/413 Introduction to Compilers Radu Rugina Lecture 11: Symbol Tables 13 Feb 02.
UNIVERSITY OF SOUTH CAROLINA Department of Computer Science and Engineering CSCE 330 Programming Language Structures Operational Semantics (Slides mainly.
Scope of Variable. 2 Scope and visibility Scope (visibility) of identifier = portion of program where identifier can be referred to Lexical scope = textual.
ISBN Chapter 10 Implementing Subprograms.
Semantic Analysis. Find 6 problems with this code. These issues go beyond syntax.
Code Generation Instruction Selection Higher level instruction -> Low level instruction Register Allocation Which register to assign to hold which items?
Implementing Subprograms
Lecture 9 Symbol Table and Attributed Grammars
Functions + Overloading + Scope
CS 326 Programming Languages, Concepts and Implementation
Implementing Subprograms
CS 536 / Fall 2017 Introduction to programming languages and compilers
Semantic Analysis Chapter 6.
Implementing Subprograms
Chapter 10: Implementing Subprograms Sangho Ha
Implementing Subprograms
Compiler Design 18. Object Oriented Semantic Analysis (Symbol Tables, Type Checking) Kanat Bolazar March 30, 2010.
Syntax Errors; Static Semantics
Names, Binding, and Scope
CMPE 152: Compiler Design October 4 Class Meeting
Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)
CSE401 Introduction to Compiler Construction
CSC 533: Programming Languages Spring 2015
Syntax-Directed Translation
PZ09A - Activation records
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
UNIT V Run Time Environments.
Compiler Construction
COMPILERS Semantic Analysis
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
CSC 533: Programming Languages Spring 2018
Implementing Subprograms
Compiler Construction
CSC 533: Programming Languages Spring 2019
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
Implementing Subprograms
Presentation transcript:

Semantic Analysis with Emphasis on Name Analysis You’ll need this for P4 We’ll get back to Parsing next week

Where we are at So far, we’ve only defined the structure of a program—a.k.a. the syntax We are now diving into the semantics of the program

Semantics: The Meaning of a Program The parser can guarantee that the program is structurally correct The parser does not guarantee that the program makes sense: void var; Undeclared variables Ill-typed statements int doubleRainbow; doubleRainbow = true;

Static Semantic Analysis Two phases Name analysis (a.k.a. name resolution) For each scope Process declarations, insert them into the symbol table Process statements, update IdNodes to point to the appropriate symbol-table entry Type analysis Process statements Use symbol-table info to determine the type of each expression (and sub-expression)

Why do we need this phase? Code generation Different operations use different instructions: Consistent variable access Integer addition vs. floating-point addition Operator overloading Optimization Symbol-table entry serves to identify which variable is used Can help in removing dead code (with some further analysis) Can weaken the type (e.g., bool → int) NOTE: pointers can make these tasks hard Error checking

Semantic Error Analysis For non-trivial programming languages, we run into fundamental undecidability problems Does the program halt? Can the program crash? Even with simplifying assumptions, sometimes infeasible in practice, as well Combinations of thread interleavings Inter-procedural dataflow

Catch Obvious Errors We cannot guarantee the absence of errors … … but we can at least catch some: Undeclared identifiers Multiply declared identifiers Ill-typed terms

Name Analysis Associating ids with their uses Need to bind names before we can type uses What definitions do we need about identifiers? Symbol table How do we bind definitions and uses together? Scope

Symbol Table (Structured) dictionary that binds a name to information that we need What information do you think we need? Kind (struct, variable, function, class) Type (int, int × string → bool, struct) Nesting level Runtime location (where it is stored in memory)

Symbol-Table Operations Insert entry Lookup name Add new sub-table Remove/forget a sub-table When do you think we use these operations?

Scope: The Lifetime of a Name Block of code in which a name is visible/valid No scope Assembly / FORTRAN Static / most-nested scope Should be familiar – C / Java / C++

Many decisions related to scope!!

Static vs. Dynamic Scope Correspondence between a variable use / decl is known at compile time Dynamic Correspondence determined at runtime

Exercises What uses and declarations are OK in this Java code?

Exercises void main() { int x = 0; f1(); g(); f2(); } void f1() { void g() { print(x); What does this print, assuming dynamic scoping?

Variable Shadowing Do we allow names to be reused in nesting relations? What about when the kinds are different?

Overloading Same name; different type

Forward References Use of a name before it is added to symbol table How do we implement it? Requires two passes over the program 1 to fill symbol table, 1 to use it

Example int k=10, x=20; void foo(int k) { int a = x; int x = k; int b = x; while (...) { int x; if (x == k) { int k, y; k = y = x; } int x = y; Determine which uses correspond to which declarations

Example int (1)k=10, (2)x=20; void (3)foo(int (4)k) { int (5)a = x(2); int (6)x = k(4); int (7)b = x(6); while (...) { int (8)x; if (x(8) == k(4)) { int (9)k, (10)y; k(9) = y(10) = x(8); } int (11)x = y(ERROR); Determine which uses correspond to which declarations

Name Analysis for cimple Time to make some decisions What scoping rules will we allow? What info does a cimple compiler need in its symbol table? Relevant for P4

cimple: A Statically Scoped Language cimple is designed for ease of symbol-table use global scope + nested scopes all declarations are made at the top of a scope declarations can always be removed from table at end of scope

cimple: Nesting Like Java or C, we’ll use most deeply nested scope to determine binding Shadowing Variable shadowing allowed Struct-definition shadowing allowed

cimple: Symbol-Table Implementation We want a symbol-table implementation for which we can add an entry efficiently when we need to remove an entry when we are done with it We will use a list of hashmaps sensible because we expect to remove a lot of names from a scope at once you did most of this in P1

Example }

cimple: Symbol Kinds Symbol kinds (= types of identifiers) Variable Carries a name, primitive type Function declaration Carries a name, return type, list of parameter types Struct definition Carries a name, list of fields (types with names), size

cimple: Implementation of Class Sym There are many ways to implement your symbols Here’s one suggestion Sym class for variable definitions FnSym subclass for function declarations StructDefSym for struct type definitions Contains it’s OWN symbol table for its field definitions StructSym for when you want an instance of a struct

Implementing Name Analysis with an AST At this point, we are done with the parse tree (which never existed to begin with ) All subsequent processing done on the AST + symbol table Walk the AST, much like the unparse() method Augment AST nodes where names are used (both declarations and uses) with a link to the relevant object in the symbol table Put new entries into the symbol table when a declaration is encountered

List<Type>: [bool] DeclListNode int a; int f(bool r){ struct b{ int q; }; cout << r; } VarDeclNode FnDeclNode IntNode IdNode IntNode IdNode FormalsListNode FnNodeBody VarDeclNode StructDeclNode WriteStmtNode BoolNode IdNode IdNode DeclListNode IdNode SymbolTable VarDeclNode Sym Name: a Type: int IntNode IdNode Sym Name: r Type: bool FnSym Name: f RetType: int List<Type>: [bool] Sym Name: q Type: int StructDefSym Name: b Fields: