We now allow any grammar symbol X to have attributes. The attribute a of symbol X is denoted X.a

Similar documents
Syntax-Directed Translation Part II

Summary: Semantic Analysis

Lecture 14 Sections Mon, Mar 2, 2009

Abstract Syntax Trees Synthetic and Inherited Attributes

Syntax-Directed Translation. Concepts Introduced in Chapter 5. Syntax-Directed Definitions

Syntax-Directed Translation Part I

Syntax-Directed Translation

COP4020 Programming Languages. Semantics Robert van Engelen & Chris Lacher

COP4020 Programming Languages. Semantics Prof. Robert van Engelen

Semantic Analysis Attribute Grammars

Semantic Analysis computes additional information related to the meaning of the program once the syntactic structure is known.

COP5621 Exam 3 - Spring 2005

Chapter 4. Action Routines

Syntax-Directed Translation

Syntax-Directed Translation. Introduction

[Syntax Directed Translation] Bikash Balami

Semantic Analysis with Attribute Grammars Part 3

COMPILER CONSTRUCTION (Evaluation Orders for SDD s)

Syntax-Directed Translation. CS Compiler Design. SDD and SDT scheme. Example: SDD vs SDT scheme infix to postfix trans

Syntax-Directed Translation

Compilers. 5. Attributed Grammars. Laszlo Böszörmenyi Compilers Attributed Grammars - 1

Static and Dynamic Semantics

Syntax Directed Translation

Principles of Programming Languages

10/18/18. Outline. Semantic Analysis. Two types of semantic rules. Syntax vs. Semantics. Static Semantics. Static Semantics.

COP4020 Spring 2011 Midterm Exam

Chapter 4 :: Semantic Analysis

Syntax Directed Translation

CSE302: Compiler Design

10/26/17. Attribute Evaluation Order. Attribute Grammar for CE LL(1) CFG. Attribute Grammar for Constant Expressions based on LL(1) CFG

CS 406: Syntax Directed Translation

Compiler Principle and Technology. Prof. Dongming LU April 15th, 2019

Syntax-Directed Translation

5. Syntax-Directed Definitions & Type Analysis

UNIT-3. (if we were doing an infix to postfix translator) Figure: conceptual view of syntax directed translation.

Context-sensitive Analysis

Chapter 6 Intermediate Code Generation

Context-sensitive Analysis

Syntax Directed Translation

UNIT IV INTERMEDIATE CODE GENERATION

A Simple Syntax-Directed Translator

Abstract Syntax Trees & Top-Down Parsing

Abstract Syntax Tree

Intermediate Code Generation

Principles of Programming Languages

More On Syntax Directed Translation

Chapter 4 - Semantic Analysis. June 2, 2015

Programming Languages

Syntax-directed translation. Context-sensitive analysis. What context-sensitive questions might the compiler ask?

Chapter 3 (part 3) Describing Syntax and Semantics

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

ΕΠΛ323 - Θεωρία και Πρακτική Μεταγλωττιστών. Lecture 8a Syntax-directed Transla1on Elias Athanasopoulos

Context-sensitive Analysis Part II Chapter 4 (up to Section 4.3)

Syntax-Directed Translation

Context-sensitive analysis. Semantic Processing. Alternatives for semantic processing. Context-sensitive analysis

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

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

Attribute Grammars. Attribute Grammars

Abstract Syntax Trees & Top-Down Parsing

Abstract Syntax Trees & Top-Down Parsing

A language is a subset of the set of all strings over some alphabet. string: a sequence of symbols alphabet: a set of symbols

Semantic Analysis with Attribute Grammars Part 1

NARESHKUMAR.R, AP\CSE, MAHALAKSHMI ENGINEERING COLLEGE, TRICHY Page 1

Semantic analysis. Syntax tree is decorated with typing- and other context dependent

Context-sensitive Analysis. Copyright 2003, Keith D. Cooper, Ken Kennedy & Linda Torczon, all rights reserved.

Evaluation of Semantic Actions in Predictive Non- Recursive Parsing

Functional Programming. Pure Functional Programming

CSE 12 Abstract Syntax Trees

Static semantics. Lecture 3-6: Semantics. Attribute grammars (2) Attribute grammars. Attribute grammars example. Dynamic semantics

CMPT 379 Compilers. Parse trees

Introduction to Syntax Directed Translation and Top-Down Parsers

Examples of attributes: values of evaluated subtrees, type information, source file coordinates,

Object Code (Machine Code) Dr. D. M. Akbar Hussain Department of Software Engineering & Media Technology. Three Address Code

LECTURE 3. Compiler Phases

Chapter 2: Syntax Directed Translation and YACC

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

PART 4 - SYNTAX DIRECTED TRANSLATION. F. Wotawa TU Graz) Compiler Construction Summer term / 309

Semantic Analysis. Role of Semantic Analysis

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

Intermediate Representations

Finite Automata Theory and Formal Languages TMV027/DIT321 LP4 2018

Test 1 Summer 2014 Multiple Choice. Write your answer to the LEFT of each problem. 5 points each 1. Preprocessor macros are associated with: A. C B.

2.2 Syntax Definition

Chapter 3. Syntax - the form or structure of the expressions, statements, and program units

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

COP 3402 Systems Software Top Down Parsing (Recursive Descent)

Program Assignment 2 Due date: 10/20 12:30pm

Introduction to Parsing

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

Intermediate Code Generation

1. (a) What are the closure properties of Regular sets? Explain. (b) Briefly explain the logical phases of a compiler model. [8+8]

4. Semantic Processing and Attributed Grammars

Defining Languages GMU

CS115 - Module 8 - Binary trees

Faculty of Electrical Engineering, Mathematics, and Computer Science Delft University of Technology

About the Authors... iii Introduction... xvii. Chapter 1: System Software... 1

CSE P 501 Compilers. Static Semantics Hal Perkins Winter /22/ Hal Perkins & UW CSE I-1

Formal Languages and Compilers Lecture X Intermediate Code Generation

JavaCC Parser. The Compilation Task. Automated? JavaCC Parser

Context-sensitive Analysis Part II

Transcription:

Attribute Grammars

Attribute Grammars were invented by Don Knuth as a way to unify all of the stages of compiling into one. They give a formal way to pass semantic information (types, values, etc.) around a parse tree. We now allow any grammar symbol X to have attributes. The attribute a of symbol X is denoted X.a

If there is a grammar rule P: X 0 ::= X 1 X 2...X k then a semantic rule for P computes the value of some attribute of one of the X i in terms of other attributes of symbols in the rule. If you think of the rule as forming the node of a tree, an attribute of a node gets its value from the attribute of its parent, siblings and children (but not from its grandparent, for example).

A syntax-directed definition (SDD) is a triple (G,A,R) where G is a context-free grammar, A is a set of attributes, and R is the set of semantic rules for G.

Example: Grammar symbols E, T, and F all have one attribute val. Where necessary we put subscripts on the grammar symbols to distinguish the child from the parent. E ::= E 1 +T {E.val = E 1.val + T.val} E ::= T {E.val = T.val} T ::= T 1 *F {T.val = T 1.val*F.val} T ::= F {T.val = F.val} F ::= num {F.val = num}

With this grammar the expression 2+3*5 parses to Note that the attributes implement the natural semantics of this simple language.

We say that an attribute X.a is synthesized if there is a grammar rule X ::= a and X.a is defined in terms of the attributes of the elements of a. We say that X.a is inherited if there is a rule Y ::= axb and X.a is defined in terms of the attributes of Y, a, and b. In other words, synthesized attributes get their values from their children while inherited attributes get their values from their parent and siblings

In the E ::= E+T example a from a few slides ago the attributes are all synthesized -- passed from the leaves up; evaluation of such attributes can be done easily in a bottom-up pass through the tree.

Here is an example that uses attributes for automatic type evaluation. The st attribute is a symbol table -- a list of (id,type) pairs. S ::= DEC {S.st = DEC.st} S ::= S 1 DEC {S.st = S 1.st DEC.st} ( =concatenate) DEC ::= T L ; {L.type = T.type; DEC.st = L.st} T ::= int {T.type = int} T ::= string {T.type = string} L ::= id {L.st = (id.name, L.type)} L ::= L 1, id {L1.type = L.type; L.st = L 1.st (id.name, L.type)} Note that L.type is inherited, but the st attribute is synthesized.

Here is the attributed tree this grammar generates for int a, b, c; string s;

A grammar is L-attributed if each attribute defined in a rule A ::= X 1...X k is either a) Synthesized (i.e., an attribute of A) b) An inherited attribute of some Xi that depends only on the inherited attributes of A and the attributes of X j for j < i

We can evaluate the attributes in an L-attributed grammar in a bottom-up, left-to-right pass using the following invariant: When we get to a node during parsing, we must have all of the information we need to evaluate its inherited attributes. Before we leave the node we must have all of the information we need to evaluate its synthesized attributes.

Here is an example that evaluates fractional binary strings, such as.101 (which is 1/2+1/8, or 5/8) N ::=.L {N.v = L.v; L.c = -1} L ::= B L 1 {L.v=B.v+L 1.v; L 1.c=L.c-1; B.c=L.c} L ::= e {L.v=0} B ::= 0 {B.v=0} B ::= 1 {B.v=2 B.c } Note that L.c is inherited, while L.v is synthesized.

Here we use this grammar to parse and evaluate the string.1001

To write a recursive descent parser for an L- attributed grammar apply the following pattern. For rule A ::= X 1...X k the function A() that parses this rule should have as arguments all of the inherited attributes for A; before it returns it should evaluate all of the synthesized attributes of A.

A translation scheme has the same information as an L-attributed grammar but provides an ordering for the parsing and attribute evaluation. For example, the previous grammar could be written N ::=. {L.c = -1} L {N.v = L.v} L ::= {B.c = L.c} B {L 1.c=L.c-1} L 1 {L.v=B.v+L 1. v} L ::= e {L.v=0} B ::= 0 {B.v=0} B ::= 1 {B.v=2 B.c }

Here is a more realistic example of attribute grammars. This produces "assembly code" for an ifthen-else statement. Starting grammar: S ::= if (E) S if (E) S else S <other stuff> We will use 3 "assembly language" instructions: JMPF label conditional branch JMP label unconditional branch LABEL lab place a label

We want to produce something like this: if (e) s -------------- code for e JMPF L1 code for s LABEL L1 if (e) s 1 else s 2 ---------------------- code for e JMPF L1 code for s 1 JMP L2 LABEL L1 code for s 2 LABEL L2

First, left-factor the grammar so we can parse it: S ::= if (E) S TAIL S ::= <other stuff> TAIL ::= else S TAIL ::= e We will give S two inherited attributes: S.temp and S.label We give TAIL one synthesized attribute: TAIL.label

Here is the translation scheme: S ::= if (E) {TAIL.label = new label(); emit( "JMPF", TAIL.label)} S1 TAIL S ::= <other stuff> TAIL ::= else {S.temp=new label(); emit( "JMP", s.temp); emit( "LABEL", TAIL.label); } S {emit("label", s.temp);} TAIL ::= e {emit( "LABEL", TAIL.label);}

The expression if (e1) { if (e2) s1 else s2 } generates the following: code for e1 JMPF L1 code for e2 JMPF L2 code for s1 JMP L3 LABEL L2 code for s2 LABEL L3 LABEL L1

The expression if (e1) { if (e2) s1 } else s2 generates the following: code for e1 JMPF L1 code for e2 JMPF L2 code for s1 LABEL L2 JMP L3 LABEL L1 code for s2 LABEL L3