Semantic Analysis Wilhelm/Seidl/Hack: Compiler Design Syntactic and Semantic Analysis, Chapter 4

Similar documents
Semantic Analysis. Compiler Architecture

Prof. Mohamed Hamada Software Engineering Lab. The University of Aizu Japan

A Simple Syntax-Directed Translator

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler so far

The role of semantic analysis in a compiler

LECTURE 3. Compiler Phases

Computer Science Department Carlos III University of Madrid Leganés (Spain) David Griol Barres

1 Lexical Considerations

CS 415 Midterm Exam Spring SOLUTION

Theoretical Part. Chapter one:- - What are the Phases of compiler? Answer:

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

2.2 Syntax Definition

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Attribute Grammars. Wilhelm/Seidl/Hack: Compiler Design, Volume 2, Chapter 4. Reinhard Wilhelm Universität des Saarlandes

CSE450 Translation of Programming Languages. Lecture 4: Syntax Analysis

The Structure of a Syntax-Directed Compiler

CA Compiler Construction

Static Semantics. Lecture 15. (Notes by P. N. Hilfinger and R. Bodik) 2/29/08 Prof. Hilfinger, CS164 Lecture 15 1

Programming Languages Third Edition. Chapter 7 Basic Semantics

CSE450. Translation of Programming Languages. Lecture 11: Semantic Analysis: Types & Type Checking

Syntax Errors; Static Semantics

Anatomy of a Compiler. Overview of Semantic Analysis. The Compiler So Far. Why a Separate Semantic Analysis?

Syntax Analysis Check syntax and construct abstract syntax tree

Lecture 7: Type Systems and Symbol Tables. CS 540 George Mason University

Static Semantics. Winter /3/ Hal Perkins & UW CSE I-1

Lexical Considerations

PRINCIPLES OF COMPILER DESIGN UNIT I INTRODUCTION TO COMPILING

Semantic Analysis and Type Checking

Syntax-Directed Translation. Lecture 14

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

Principles of Programming Languages COMP251: Syntax and Grammars

Lexical Considerations

Semantic actions for declarations and expressions

Crafting a Compiler with C (II) Compiler V. S. Interpreter

Today's Topics. CISC 458 Winter J.R. Cordy

More Assigned Reading and Exercises on Syntax (for Exam 2)

Semantic actions for declarations and expressions. Monday, September 28, 15

COMP-421 Compiler Design. Presented by Dr Ioanna Dionysiou

The SPL Programming Language Reference Manual

Visitors. Move functionality

9/5/17. The Design and Implementation of Programming Languages. Compilation. Interpretation. Compilation vs. Interpretation. Hybrid Implementation

CS 4240: Compilers and Interpreters Project Phase 1: Scanner and Parser Due Date: October 4 th 2015 (11:59 pm) (via T-square)

Informal Semantics of Data. semantic specification names (identifiers) attributes binding declarations scope rules visibility

Section A. A grammar that produces more than one parse tree for some sentences is said to be ambiguous.

Principles of Programming Languages Topic: Scope and Memory Professor Louis Steinberg Fall 2004

Programming Language Concepts, cs2104 Lecture 04 ( )

COP 3402 Systems Software Syntax Analysis (Parser)

Lecture 16: Static Semantics Overview 1

Typescript on LLVM Language Reference Manual

Semantic Analysis. Lecture 9. February 7, 2018

COMPILER CONSTRUCTION LAB 2 THE SYMBOL TABLE. Tutorial 2 LABS. PHASES OF A COMPILER Source Program. Lab 2 Symbol table

Compiler construction

The Compiler So Far. Lexical analysis Detects inputs with illegal tokens. Overview of Semantic Analysis

Structure of a compiler. More detailed overview of compiler front end. Today we ll take a quick look at typical parts of a compiler.

4. An interpreter is a program that

RYERSON POLYTECHNIC UNIVERSITY DEPARTMENT OF MATH, PHYSICS, AND COMPUTER SCIENCE CPS 710 FINAL EXAM FALL 96 INSTRUCTIONS

CS 536 Midterm Exam Spring 2013

Lexical Analysis. COMP 524, Spring 2014 Bryan Ward

CS 4201 Compilers 2014/2015 Handout: Lab 1

Working of the Compilers

ChAmElEoN Parse Tree

The Structure of a Syntax-Directed Compiler

Parsing CSCI-400. Principles of Programming Languages.

CST-402(T): Language Processors

Context-Free Grammar. Concepts Introduced in Chapter 2. Parse Trees. Example Grammar and Derivation

Compiler Theory. (Semantic Analysis and Run-Time Environments)

The compilation process is driven by the syntactic structure of the program as discovered by the parser

Yacc: A Syntactic Analysers Generator

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

When do We Run a Compiler?

for (i=1; i<=100000; i++) { x = sqrt (y); // square root function cout << x+i << endl; }

Compiling Regular Expressions COMP360

Functional Programming. Pure Functional Programming

Chapter 3: CONTEXT-FREE GRAMMARS AND PARSING Part 1

COMPILERS BASIC COMPILER FUNCTIONS

11. a b c d e. 12. a b c d e. 13. a b c d e. 14. a b c d e. 15. a b c d e

Informatica 3 Syntax and Semantics

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division

SMURF Language Reference Manual Serial MUsic Represented as Functions

Introduction to Programming Using Java (98-388)

LL(k) Parsing. Predictive Parsers. LL(k) Parser Structure. Sample Parse Table. LL(1) Parsing Algorithm. Push RHS in Reverse Order 10/17/2012

CSE 12 Abstract Syntax Trees

CSE 307: Principles of Programming Languages

Time : 1 Hour Max Marks : 30

Syntactic Directed Translation

Answer: Early binding generally leads to greater efficiency (compilation approach) Late binding general leads to greater flexibility

The PCAT Programming Language Reference Manual

Principles of Programming Languages COMP251: Syntax and Grammars

CS Lecture 2. The Front End. Lecture 2 Lexical Analysis

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

COP4020 Programming Assignment 1 CALC Interpreter/Translator Due March 4, 2015

Compiler construction in4020 lecture 5

G Programming Languages - Fall 2012

A simple syntax-directed

IEEE LANGUAGE REFERENCE MANUAL Std P1076a /D3

Compiler Design (40-414)

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

Compiler Construction I

Transcription:

Semantic Analysis Wilhelm/Seidl/Hack: Compiler Design Syntactic and Semantic Analysis, Chapter 4 Reinhard Wilhelm Universität des Saarlandes wilhelm@cs.uni-sb.de

Standard Structure source(text) lexical analysis(chap. 2) tokenized-program syntax analysis(chap. 3) syntax-tree semantic-analysis(chap. 4) decorated syntax-tree optimizations(vol. 3) intermediate rep. code-generation(vol. 4) machine-program finite automata pushdown automata attribute grammar evaluators abstract interpretation + transformations tree automata + dynamic programming +

When is a Program Incorrect? A program is incorrect, if it does not adhere to language-specific constraints. Scanner: Catches sequence of characters that do not form valid tokens Example: ïnτ instead of int Specification mechanism: regular expressions (cannot describe matching parentheses) Parser: Catches sequence of symbols that do not form valid words in a CFG Example: while while int 2 do Specification mechanism: CFGs (cannot describe declaredness requirements) This leaves context sensitive constraints Example: int f(){return 4;} void g(){return f(6);}

Semantic Constraints Typical semantic constraints, checked by the compiler: Each variable declared in an enclosing scope. Variables uniquely declared within a scope. Types of operands and operators in expressions must match. Programs violating such semantic constraints are rejected by the compiler. Note: Dynamic semantic constraints (no division by zero, no dereferencing of null pointers) are not (cannot) be checked by the compiler, the potential can, cf. static program analysis (Vol. 3)!

Types and Variables: Terminology Identifiers denote program objects (variables, constants, types, methods,...). A declaration introduces an identifier, binds it to an element. A defining occurence of an identifier is an occurence in a declaration. An applied occurence of an identifier is an occurence somewhere else. The scope of a defining occurence is that (textual) part of a program, in which an applied occurence may refer to this defining occurrence. A defining occurence of an identifier is visible, if it is directly visible (in the scope) or made visible by name extensions (std::cin)

Types and Variables: Terminology (continued) The type of a constant (variable) constrains which operations can be applied to the constant (variable). Overload of an identifier is the legal existence of several defining occurrences of this identifier in the same scope.

Symbol Table A data structure used to store information on declared objects Supports insertions and deletions of declarations and opening and closing of scopes Supports efficient search for the defining occurrence associated with an applied occurrence: identification of identifiers

Symbol Table Functionality Language with nested scopes, (blocks create_symb_table creates an empty symbol table, enter_block notes the start of a new scope, exit_block resets the symbol table to the state before the last enter_block, enter_id(id, decl_ptr) inserts an entry for identifier id with a link to its defining occurrence passed in decl_ptr, search_id(id) searches the def. occ. for id returns a pointer to it if exists.

Symbol Table Implementation Data structure with constant time for search_id, all currently valid defining occurrences of an identifier are stored in a (stack like) linear list, new entry is inserted at the end of this list, the end of this list is pointed to by an array component for this identifier, all entries for a block are chained through a linear list.

proc create_symb_table; begin create empty stack of block entries end ; proc enter_block; begin push entry for the new block end ; proc exit_block; begin foreach decl. entry of the curr. block do delete entry od; pop block entry from stack end ; proc enter_id ( id: Idno; decl: node ); begin if exists entry for id in curr. block then error( double declaration ) fi; create new entry with decl and no. of curr. block; insert entry at tail of linear list for id; insert entry at tail of linear list for curr. block end ;

function search_id ( id: idno ) node; begin if list for id is empty then error( undeclared identifier ) else return (value of decl-field of first elem. in id-list) fi end

1 2 3 4 5 6 7 Semantic Analysis Wilhelm/Seidl/Hack: Compiler Design Syntactic and Semantic Analysis, Chapter 4 Example Program with Symboltable Decl. of a, b proc p (* forward decl. *) proc q proc p is 1 Decl. of a, c 2 Decl. of c, d proc q is Decl. of a, d proc r proc r is Decl. of a, c 4 3 a 4 / 3 / 1 / / b c d 1 1 / 4 1 5 / 3 1 1 3 / p q 1 2 / 1 4 / r 3 4 4 3 7 1 6 /

Declaration Analysis proc analyze_decl (k : node); proc analyze_subtrees (root: node); begin for i := 1 to #descs(root) do ( # children ) analyze_decl(root.i) ( i-th child of root ) od end ; begin case symb(k) of ( label of k ) block: begin enter_block; analyze_subtrees(k); exit_block end ; decl: begin analyze_subtrees(k); foreach identifier declared here id do enter_id(id, k) od end ; appl_id:( appl. occ. of identifier id ) store search_id(id) at k; otherwise: if k no leaf then analyze_subtrees(k) fi od end

Overloading of Operators An operator symbol (function, procedure identifier) is overloaded, if it may denote several operations at some point in the program. The different operators need to have different parameter profiles, i.e., tuples of argument and result types. The identification of identifiers may have legally associated several possible parameter profiles with an applied occurrence. Overload Resolution needs to identify exactly one defining occurrence depending on its parameter profile.

Overload Resolution I Overload resolution for Ada: Conceptually 4 passes over trees for assignments. Passes 1 (initialization) and 2 (bottom-up elimination) and passes 3 (top-down elimination) and 4 (check) can be merged. begin init_ops; bottom_up_elim(root); top_down_elim(root); check whether now all ops sets have exactly one element; otherwise report an error end

Overload Resolution II Functions applied at nodes of assignment trees: #descs(k) number of child nodes of k, symb(k) symbol labeling k, vis(k) set of definitions of symb(k) visible at k ops(k) set of actual candidates for overloaded symbol symb(k), k.i ith child of k. For def. occ. of overloaded symbol op with type t 1 t m t rank(op) = m res_typ(op) = t par_typ(op,i) = t i (1 i m).

Overload Resolution III proc resolve_overloading (root: node, a_priori_type: type); func pot_res_types (k: node): set of type; ( potential types of the result ) return {res_typ(op) op ops(k)} func act_par_types (k: node, i: integer): set of type; return {par_typ(op, i) op ops(k)} proc init_ops begin foreach k ops(k) := {op op vis(k) and rank(op) = #descs(k)} od; ops(root) := {op ops(root) res_typ(op) = a_priori_typ} end ;

Overload Resolution IV proc bottom_up_elim (k: node); begin for i := 1 to #descs(k) do bottom_up_elim (k.i); ops(k) := ops(k) {op ops(k) par_typ(op, i) pot_res_typ ( remove the operators, whose ith parameter type does not match the potential result types of the ith operand ) od; end ;

Overload Resolution V proc top_down_elim (k: node); begin for i := 1 to #descs(k) do ops(k.i) := ops(k.i) {op ops(k.i) res_typ(op) act_par_t ( remove the operators, whose result type does not match any type of the corresponding parameter ) top_down_elim(k.i) od; end ;

Overload Resolution VI mnop 1 mn{... X...} mnbottom up Elimination mn... mni mn... mnop 2 mn{... X...} mntop down Elimination Quite typical information flow, up and down the parse tree!