Semantic actions for expressions

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

Semantic actions for declarations and expressions

Semantic actions for declarations and expressions

Intermediate Code Generation

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

CMPT 379 Compilers. Parse trees

CSE 12 Abstract Syntax Trees

Last time. What are compilers? Phases of a compiler. Scanner. Parser. Semantic Routines. Optimizer. Code Generation. Sunday, August 29, 2010

Syntax-Directed Translation. Introduction

Chapter 20: Binary Trees

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

COMPILER CONSTRUCTION Seminar 03 TDDB

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

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

CSE 307: Principles of Programming Languages

Summary: Direct Code Generation

Time : 1 Hour Max Marks : 30

CS 6353 Compiler Construction Project Assignments

What is a compiler? var a var b mov 3 a mov 4 r1 cmpi a r1 jge l_e mov 2 b jmp l_d l_e: mov 3 b l_d: ;done

The role of semantic analysis in a compiler

Chapter 4 :: Semantic Analysis

Syntax-Directed Translation

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

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

More On Syntax Directed Translation

PRINCIPLES OF COMPILER DESIGN UNIT I INTRODUCTION TO COMPILERS

Intermediate Representation Prof. James L. Frankel Harvard University

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

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

MODULE 32 DAG based Code Generation and Dynamic Programming

Chapter 4 - Semantic Analysis. June 2, 2015

Compilers and computer architecture Code-generation (2): register-machines

Program Representations

Using an LALR(1) Parser Generator

Intermediate representation

Symbol Tables. ASU Textbook Chapter 7.6, 6.5 and 6.3. Tsan-sheng Hsu.

Expressions and Casting. Data Manipulation. Simple Program 11/5/2013

CS 432 Fall Mike Lam, Professor. Code Generation

Section 5.5. Left subtree The left subtree of a vertex V on a binary tree is the graph formed by the left child L of V, the descendents

CSc 453 Intermediate Code Generation

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

Expressions and Casting

Dynamic Memory Allocation

CS 415 Midterm Exam Spring SOLUTION

Writing an Interpreter Thoughts on Assignment 6

MULTIMEDIA COLLEGE JALAN GURNEY KIRI KUALA LUMPUR

COP4020 Programming Languages. Semantics Robert van Engelen & Chris Lacher

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

CS Programming In C

The SPL Programming Language Reference Manual

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

Compilers CS S-07 Building Abstract Assembly

COP4020 Programming Languages. Semantics Prof. Robert van Engelen

Declaration and Memory

Pointers II. Class 31

EI326 ENGINEERING PRACTICE & TECHNICAL INNOVATION (III-G) Kenny Q. Zhu Dept. of Computer Science Shanghai Jiao Tong University

Semantic Analysis. Role of Semantic Analysis

Programming Languages Third Edition. Chapter 7 Basic Semantics

CSE 431S Type Checking. Washington University Spring 2013

TACi: Three-Address Code Interpreter (version 1.0)

CS 4201 Compilers 2014/2015 Handout: Lab 1

Semantic analysis and intermediate representations. Which methods / formalisms are used in the various phases during the analysis?

A programming language requires two major definitions A simple one pass compiler

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

CS162 - POINTERS. Lecture: Pointers and Dynamic Memory

Semantic Analysis. Compiler Architecture

Last Time. What do we want? When do we want it? An AST. Now!

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

Intermediate Representations

JJTree. The Compilation Task. Automated? JJTree. An easier way to create an Abstract Syntax Tree

There are many other applications like constructing the expression tree from the postorder expression. I leave you with an idea as how to do it.

Agenda. 1. Quiz 2. (Short) Quiz Discussion 3. Finish off Type-Bound Procedures 4. Semcheck2 Questions 5. Coding Tips 6. Phase II Suggestions

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

CSC 467 Lecture 13-14: Semantic Analysis

An Overview of Compilation

Compilers. Compiler Construction Tutorial The Front-end

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

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

Project Compiler. CS031 TA Help Session November 28, 2011

Lecture Overview Code generation in milestone 2 o Code generation for array indexing o Some rational implementation Over Express Over o Creating

Compilers. Intermediate representations and code generation. Yannis Smaragdakis, U. Athens (original slides by Sam

Three-Address Code IR

Compiler Design. Code Shaping. Hwansoo Han

Short Notes of CS201

Arrays. Returning arrays Pointers Dynamic arrays Smart pointers Vectors

CS201 - Introduction to Programming Glossary By

Syntax-Directed Translation. Lecture 14

Compilers CS S-08 Code Generation

a data type is Types

Comp 204: Computer Systems and Their Implementation. Lecture 22: Code Generation and Optimisation

QUIZ. What is wrong with this code that uses default arguments?

Building the Abstract Syntax Trees

Intermediate Programming, Spring 2017*

Run-Time Environments

Syntax-Directed Translation

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

Delhi Noida Bhopal Hyderabad Jaipur Lucknow Indore Pune Bhubaneswar Kolkata Patna Web: Ph:

Intermediate Representations

Pointers, Dynamic Data, and Reference Types

Introduction to Programming Using Java (98-388)

Transcription:

Semantic actions for expressions

Semantic actions Semantic actions are routines called as productions (or parts of productions) are recognized Actions work together to build up intermediate representations Conceptually think of this as follows: Every non-terminal should have some information associated with it (code, declared variables, etc.) Each child of a non-terminal can pass the information it has to its parent non-terminal, which uses the information from its children to build up more information We call these semantic records

Semantic Records Data structures produced by semantic actions Associated with both non-terminals (code structures) and terminals (tokens/symbols) Build up semantic records by performing a bottom-up walk of the parse tree (as described in class)

Abstract syntax trees Tree representing structure of the program Built by semantic actions Some compilers skip this AST nodes Represent program construct Store important information about construct identifier "x" binary_op operator: + literal "10"

Referencing identifiers What do we return when we see an identifier? Check if it is symbol table Create new AST node with pointer to symbol table entry Note: may want to directly store type information in AST (or could look up in symbol table each time)

Referencing Literals What about if we see a literal? primary INTLITERAL FLOATLITERAL Create AST node for literal Store string representation of literal 155, 2.45 etc. At some point, this will be converted into actual representation of literal For integers, may want to convert early (to do constant folding) For floats, may want to wait (for compilation to different machines). Why?

Expressions Three semantic actions needed eval_binary (processes binary expressions) Create AST node with two children, point to AST nodes created for left and right sides eval_unary (processes unary expressions) Create AST node with one child Store operator in AST node process_op (determines type of operation)

x + y + 5 Expressions example

Expressions example x + y + 5 binary_op operator: + binary_op operator: + literal "5" identifier "x" identifier "y"

Expressions example x + y + 5 binary_op operator: + binary_op operator: + literal "5" identifier "x" identifier "y"

Expressions example x + y + 5 binary_op operator: + binary_op operator: + literal "5" identifier "x" identifier "y"

Expressions example x + y + 5 binary_op operator: + binary_op operator: + literal "5" identifier "x" identifier "y"

Expressions example x + y + 5 binary_op operator: + binary_op operator: + literal "5" identifier "x" identifier "y"

Generating three-address code For project, will need to generate three-address code op A, B, C //C = A op B Can do this directly or after building AST

Generating code from an AST Do a post-order walk of AST to generate code, pass generated code up data_object generate_code() { //pre-processing code data_object lcode = left.generate_code(); data_object rcode = right.generate_code(); return generate_self(lcode, rcode); } Important things to note: A node generates code for its children before generating code for itself Data object can contain code or other information

Generating code directly Generating code directly using semantic routines is very similar to generating code from the AST Why? Because post-order traversal is essentially what happens when you evaluate semantic actions as you pop them off stack AST nodes are just semantic records To generate code directly, your semantic records should contain structures to hold the code as it s being built

Data objects Records various important info The temporary storing the result of the current expression Flags describing value in temporary Constant, L-value, R-value Code for expression

L-values vs. R-values L-values: addresses which can be stored to or loaded from R-values: data (often loaded from addresses) Expressions operate on R-values Assignment statements: L-value := R-value Consider the statement a := a the a on LHS refers to the memory location referred to by a and we store to that location the a on RHS refers to data stored in memory location referred to by a so we will load from that location to produce the R-value

Temporaries Can be thought of as an unlimited pool of registers (with memory to be allocated at a later time) Need to declare them like variables Name should be something that cannot appear in the program (e.g., use illegal character as prefix) Memory must be allocated if address of temporary can be taken (e.g. a := &b) Temporaries can hold either L-values or R-values

Simple cases Generating code for constants/literals Store constant in temporary Generating code for identifiers Optional: pass up flag specifying this is a constant Generated code depends on whether identifier is used as L- value or R-value Is this an address? Or data? One solution: just pass identifier up to next level Mark it as an L-value (it s not yet data!) Generate code once we see how variable is used

Generating code for expressions Create a new temporary for result of expression Examine data-objects from subtrees If temporaries are L-values, load data from them into new temporaries Generate code to perform operation In project, no need to explicitly load (variables can be operands) If temporaries are constant, can perform operation immediately No need to perform code generation! Store result in new temporary Is this an L-value or an R-value? Return code for entire expression

Generating code for assignment Store value of temporary from RHS into address specified by temporary from LHS Why does this work? Because temporary for LHS holds an address If LHS is an identifier, we just stored the address of it in temporary If LHS is complex expression int *p = &x *(p + 1) = 7; it still holds an address, even though the address was computed by an expression

Pointer operations So what do pointer operations do? Mess with L and R values & (address of operator): take L-value, and treat it as an R- value (without loading from it) x = &a + 1; * (dereference operator): take R-value, and treat it as an L- value (an address) *x = 7;