Syntax Directed Transla1on

Similar documents
LR2: LR(0) Parsing. LR Parsing. CMPT 379: Compilers Instructor: Anoop Sarkar. anoopsarkar.github.io/compilers-class

EXAM. CS331 Compiler Design Spring Please read all instructions, including these, carefully

Shift-Reduce parser E + (E + (E) E [a-z] In each stage, we shift a symbol from the input to the stack, or reduce according to one of the rules.

Administrivia. Test I during class on 10 March. Bottom-Up Parsing. Lecture An Introductory Example

Syntax Analysis Part I

Bottom-Up Syntax Analysis

Syntax Analysis Part I

EXAM. CS331 Compiler Design Spring Please read all instructions, including these, carefully

Lecture VII Part 2: Syntactic Analysis Bottom-up Parsing: LR Parsing. Prof. Bodik CS Berkley University 1

Syntax Analysis Part I. Position of a Parser in the Compiler Model. The Parser. Chapter 4

Compiling Techniques

CMSC 330: Organization of Programming Languages. Pushdown Automata Parsing

THEORY OF COMPILATION

CA Compiler Construction

Computing if a token can follow

Creating a Recursive Descent Parse Table

Introduction to Bottom-Up Parsing

Bottom-Up Parsing. Ÿ rm E + F *idÿ rm E +id*idÿ rm T +id*id. Ÿ rm F +id*id Ÿ rm id + id * id

Syntax Analysis Part III

Announcement: Midterm Prep

Top-Down Parsing and Intro to Bottom-Up Parsing

Introduction to Bottom-Up Parsing

Introduction to Bottom-Up Parsing

CS415 Compilers Syntax Analysis Bottom-up Parsing

Syntactic Analysis. Top-Down Parsing

CSE302: Compiler Design

2.4 Parsing. Computer Science 332. Compiler Construction. Chapter 2: A Simple One-Pass Compiler : Parsing. Top-Down Parsing

Introduction to Bottom-Up Parsing

Parsing Algorithms. CS 4447/CS Stephen Watt University of Western Ontario

Syntactical analysis. Syntactical analysis. Syntactical analysis. Syntactical analysis

CS 406: Bottom-Up Parsing

Compiling Techniques

Introduction to Theory of Computing

1. For the following sub-problems, consider the following context-free grammar: S AA$ (1) A xa (2) A B (3) B yb (4)

CS415 Compilers Syntax Analysis Top-down Parsing

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

EXAM. Please read all instructions, including these, carefully NAME : Problem Max points Points 1 10 TOTAL 100

Syntax Analysis, VII The Canonical LR(1) Table Construction. Comp 412

Compiler Principles, PS4

CONTEXT FREE GRAMMAR AND

CYK Algorithm for Parsing General Context-Free Grammars

Outline. CS21 Decidability and Tractability. Machine view of FA. Machine view of FA. Machine view of FA. Machine view of FA.

Even More on Dynamic Programming

Lecture 11 Sections 4.5, 4.7. Wed, Feb 18, 2009

CS 314 Principles of Programming Languages

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

n Top-down parsing vs. bottom-up parsing n Top-down parsing n Introduction n A top-down depth-first parser (with backtracking)

Syntax Analysis, VI Examples from LR Parsing. Comp 412

CFLs and Regular Languages. CFLs and Regular Languages. CFLs and Regular Languages. Will show that all Regular Languages are CFLs. Union.

Compiler Construction Lent Term 2015 Lectures (of 16)

Syntax Analysis - Part 1. Syntax Analysis

Context free languages

Compiler Construction Lent Term 2015 Lectures (of 16)

Computer Science 160 Translation of Programming Languages

Syntax Analysis (Part 2)

Harvard CS 121 and CSCI E-207 Lecture 10: CFLs: PDAs, Closure Properties, and Non-CFLs

h>p://lara.epfl.ch Compiler Construc/on 2011 CYK Algorithm and Chomsky Normal Form

Compiler Design Spring 2017

Pushdown Automata: Introduction (2)

LR(1) Parsers Part III Last Parsing Lecture. Copyright 2010, Keith D. Cooper & Linda Torczon, all rights reserved.

Compiler Construction Lectures 13 16

CPS 220 Theory of Computation Pushdown Automata (PDA)

CFGs and PDAs are Equivalent. We provide algorithms to convert a CFG to a PDA and vice versa.

Bottom up parsing. General idea LR(0) SLR LR(1) LALR To best exploit JavaCUP, should understand the theoretical basis (LR parsing);

CSE 105 THEORY OF COMPUTATION

Follow sets. LL(1) Parsing Table

LL(1) Grammar and parser

Exercises. Exercise: Grammar Rewriting

Parsing. Unger s Parser. Laura Kallmeyer. Winter 2016/17. Heinrich-Heine-Universität Düsseldorf 1 / 21

Context-Free Grammars (and Languages) Lecture 7

Introduction to Computational Linguistics

Pushdown Automata (Pre Lecture)

Notes for Comp 497 (454) Week 10

Intro to Theory of Computation

Pushdown Automata (2015/11/23)

Harvard CS 121 and CSCI E-207 Lecture 10: Ambiguity, Pushdown Automata

LR(1) Parsers Part II. Copyright 2010, Keith D. Cooper & Linda Torczon, all rights reserved.

Recursive descent for grammars with contexts

Theory of Computation - Module 3

Static Program Analysis

EDA045F: Program Analysis LECTURE 10: TYPES 1. Christoph Reichenbach

Notes for Comp 497 (Comp 454) Week 10 4/5/05

Parsing -3. A View During TD Parsing

COSE312: Compilers. Lecture 17 Intermediate Representation (2)

A brief introduction to Logic. (slides from

Compiler Principles, PS7

Syntax Analysis, VII The Canonical LR(1) Table Construction. Comp 412 COMP 412 FALL Chapter 3 in EaC2e. source code. IR IR target.

MA/CSSE 474 Theory of Computation

Announcements. H6 posted 2 days ago (due on Tue) Midterm went well: Very nice curve. Average 65% High score 74/75

Foundations of Informatics: a Bridging Course

Compilerconstructie. najaar Rudy van Vliet kamer 124 Snellius, tel rvvliet(at)liacs.

Lecture 11 Context-Free Languages

1. For the following sub-problems, consider the following context-free grammar: S AB$ (1) A xax (2) A B (3) B yby (5) B A (6)

CISC4090: Theory of Computation

Computer Science 160 Translation of Programming Languages

CMPT-825 Natural Language Processing. Why are parsing algorithms important?

CSE 355 Test 2, Fall 2016

Lecture Notes on Inductive Definitions

CSC 4181Compiler Construction. Context-Free Grammars Using grammars in parsers. Parsing Process. Context-Free Grammar

MTH401A Theory of Computation. Lecture 17

Transcription:

Syntax Directed Transla1on Syntax Directed Transla1on CMPT 379: Compilers Instructor: Anoop Sarkar anoopsarkar.github.io/compilers-class

Syntax directed Translation Models for translation from parse trees o assembly/machine code Representation of translations Attribute Grammars (semantic actions for CFGs) Tree Matching Code Generators Tree Parsing Code Generators

Attribute Grammars Syntax-directed translation uses a grammar to produce code (or any other semantics ) Consider this technique to be a generalization of a CFG definition Each grammar symbol is associated with an attribute An attribute can be anything: a string, a number, a tree, any kind of record or object

Attribute Grammars A CFG can be viewed as a (finite) representation of a function that relates strings to parse trees Similarly, an attribute grammar is a way of relating strings with meanings Since this relation is syntax-directed, we associate each CFG rule with a semantic (rules to build an abstract syntax tree) In other words, attribute grammars are a method to decorate or annotate the parse tree

Expr concrete syntax tree Input: 4+3*5 T + E E E T + E E T T T * T.lexval=4 T T ( E ).lexval=3 * T.lexval=5

Expr concrete syntax tree Input: 4+3*5 T.val=4 T + E E E T + E E T T T * T.lexval=4 T T ( E ).lexval=3 * T T.val=5.lexval=5

Expr concrete syntax tree Input: 4+3*5 T.val=4 T + E E E T + E E T T T * T.lexval=4 T T.val=15 T ( E ).lexval=3 * T T.val=5.lexval=5

Expr concrete syntax tree Input: 4+3*5 T.val=4 T + E E E.val=15 E T + E E T T T * T.lexval=4 T T.val=15 T ( E ).lexval=3 * T T.val=5.lexval=5

Expr concrete syntax tree Input: 4+3*5 T.val=4 T + E E.val=19 E E.val=15 E T + E E T T T * T.lexval=4 T T.val=15 T ( E ).lexval=3 * T T.val=5.lexval=5

Syntax directed definition T { $0.val = $1.lexval; } T * T { $0.val = $1.lexval * $3.val ; } E T { $0.val = $1.val; } E T + E { $0.val = $1.val + $3.val; } T ( E ) { $0.val = $2.val; } In yacc: { $$ = $1 }

Flow of Attributes in Expr Consider the flow of the attributes in the E syntax-directed defn The lhs attribute is computed using the rhs attributes Purely bottom-up: compute attribute values of all children (rhs) in the parse tree And then use them to compute the attribute value of the parent (lhs)

Synthesized Attributes Synthesized attributes are attributes that are computed purely bottom-up A grammar with semantic actions (or syntax-directed definition) can choose to use only synthesized attributes Such a grammar plus semantic actions is called an S-attributed definition

Inherited Attributes Synthesized attributes may not be sufficient for all cases that might arise for semantic checking and code generation Consider the (sub)grammar: Var-decl Type Id-comma-list ; Type bool Id-comma-list ID Id-comma-list ID, Id-comma-list

Example input: x, y, z ; Var-decl Type Id-Comma-List ; ID, Id-Comma-List x ID y, Id-Comma-List ID z

Example input: x, y, z ; Var-decl Type Type.val= Id-Comma-List I-C-L.in= ; ID, Id-Comma-List x ID, Id-Comma-List y ID z

Example input: x, y, z ; Var-decl Type Type.val= Id-Comma-List I-C-L.in= ; ID.val= ID, Id-Comma-List I-C-L.in= x ID, Id-Comma-List y ID z

Example input: x, y, z ; Var-decl Type Type.val= Id-Comma-List I-C-L.in= ; ID, Id-Comma-List I-C-L.in= ID.val= x ID, Id-Comma-List I-C-L.in= ID.val= y ID z

Example input: x, y, z ; Var-decl Type Type.val= Id-Comma-List I-C-L.in= ; ID, Id-Comma-List I-C-L.in= ID.val= x ID, Id-Comma-List I-C-L.in= ID.val= y ID.val= ID z

Flow of Attributes in Var-decl How do the attributes flow in the Var-decl grammar? ID takes its attribute value from its parent node Id-Comma-List takes its attribute from its left sibling Type (or from its parent Id- Comma-list)

Syntax-directed definition Var-decl Type Id-comma-list ; {$2.in = $1.val; } Type { $0.val = ; } bool { $0.val = bool; } Id-comma-list ID { $1.val = $0.in; } Id-comma-list ID, Id-comma-list { $1.val = $0.in; $3.in = $0.in; }

Inherited Attributes Inherited attributes are attributes that are computed at a node based on attributes from siblings or the parent Typically we combine synthesized attributes and inherited attributes It is possible to convert the grammar o a form that only uses synthesized attributes

Removing Inherited Attributes Var-decl Type-list ID ; Type-list ID, Type-list ID, Type x, y, z ;

Removing Inherited Attributes Var-decl.val= Var-decl Type-list.val= Type-list ID ; Type-list.val= Type-list ID, Type-list.val= Type-list ID, Type x, y, z ;

Removing inherited attributes Var-decl Type-List ID ; { $0.val = $1.val; } Type-list Type-list ID, { $0.val = $1.val; } Type-list Type { $0.val = $1.val; } Type { $0.val = ; } bool { $0.val = bool; }

Direction of inherited attributes Consider the syntax directed defns: A L M { $1.in = $0.in; $2.in = $1.val; $0.val = $2.val; } A Q R { $2.in = $0.in; $1.in = $2.val; $0.val = $1.val; } Problematic definition: $1.in = $2.val Difference between incremental processing vs. using the completed parse tree

Incremental Processing Incremental processing: constructing output as we are parsing Bottom-up or top-down parsing Both can be viewed as left-to-right and depth-first construction of the parse tree Some inherited attributes cannot be used in conjunction with incremental processing

L-attributed Definitions A syntax-directed definition is L-attributed if for each production A X 1..X j-1 X j..x n, for each j=1 n, each inherited attribute of X j depends on: The attributes of X 1...X j-1 The inherited attributes of A These two conditions ensure left to right and depth first parse tree construction Every S-attributed definition is L-attributed

Syntax-directed defns Different SDTs are defined based on the parser which is used. Two important classes of SDTs: 1. LR parser, syntax directed definition is S-attributed 2. LL parser, syntax directed definition is L-attributed

Syntax-directed defns LR parser, S-attributed definition Implementing S-attributed definitions in LR parsing is easy: execute action on reduce, all necessary attributes have to be on the stack LL parser, L-attributed definition Implementing L-attributed definitions in LL parsing: we need an additional action record for storing synthesized and inherited attributes on the parse stack

Top-down translation Assume that we have a top-down predictive parser Typical strategy: take the CFG and eliminate left-recursion Suppose that we start with an attribute grammar We should still eliminate left-recursion

Top-down translation E E + T { $0.val = $1.val + $3.val; } E E - T { $0.val = $1.val - $3.val; } T { $0.val = $1.lexval; } E T { $0.val = $1.val; } T ( E ) { $0.val = $2.val; } example

Top-down translation Remove left recursion example E E + T E E T E T T ( E ) T E T R R + T R R - T R R ε T ( E ) T

input: 9-5 + 2 E T R 9 - T R + T R 5 2 ε

input: 9-5 + 2 val=9 T E R 9 - T R + T R 5 2 ε

input: 9-5 + 2 val=9 T E R in=9 9 - T R + T R 5 2 ε

input: 9-5 + 2 val=9 T E R in=9 9 - Tval=5 R + T R 5 2 ε

input: 9-5 + 2 val=9 T E R in=9 9 - Tval=5 R in=4 + T R 5 2 ε

input: 9-5 + 2 val=9 T E R in=9 9 - Tval=5 R in=4 + T val=2 R 5 2 ε

input: 9-5 + 2 val=9 T E R in=9 - Tval=5 R in=4 9 + T val=2 R in=6 5 2 ε

input: 9-5 + 2 val=9 T 9 val=6 E val=6 in=9 R - Tval=5 R val=6 in=4 + T val=2 R val=6 in=6 5 2 ε

Top-down translation example SDT for the LL(1) grammar: E E + T { $0.val = $1.val + $3.val; } E E - T { $0.val = $1.val - $3.val; } E T { $0.val = $1.val; } T ( E ) { $0.val = $2.val; } T { $0.val = $1.lexval; } E T R {$2.in = $1.val; $0.val =$2.val; } R + T R {$3.in = $0.in + $2.val; $0.val = $3.val; } R - T R { $3.in = $0.in - $2.val; $0.val = $3.val; } R ε { $0.val = $0.in; } T ( E ) { $0.val = $2.val; } T { $0.val = $1.lexval; }

Dependencies and SDTs There can be circular definitions: A B { $0.val = $1.in; $1.in = $0.val + 1; } It is impossible to evaluate either $0.val or $1.in first (each value depends on the other) We want to avoid circular dependencies Detecting such cases in all parse trees takes exponential time! S-attributed or L-attributed definitions cannot have cycles

Dependency Graphs Each dependency shows the flow of information in the parse tree All dependencies in each parse tree create a dependency graph

Dependency Graphs val=6 E val=6 T val=9 R in=9 val=6 - T val=5 R in=4 9 in=6 + T val=2 R 5 2 ε

Dependency Graphs Each dependency shows the flow of information in the parse tree All dependencies in each parse tree create a dependency graph Dependencies can be ordered and each ordering is called a topological sort of the dependency edges Each topological sort is a valid order of evaluation for semantic rules

A directed acyclic graph has many valid topological sort: 7,5,3,11,8,2,9,10 (visual left-to-right top-to-bottom) 3,5,7,8,11,2,9,10 (smallest-numbered available vertex first) 3,7,8,5,11,10,2,9 5,7,3,8,11,10,9,2 (least number of edges first) 7,5,11,3,10,8,9,2 (largest-numbered available vertex first) 7,5,11,2,3,8,9,10 Source: Wikipedia

Dependency Graphs Topological sort : Order the nodes of the graph as N 1,, N k such that no edge in the graph goes fromn i to N j ( j < i )

Dependency Graphs 12 val=6 E val=6 2 T val=9 R in=9 3 10 6 val=6 - T val=5 in=4 R 19 5 9 in=6 + T val=2 R 8 4 Topological sorts: 5 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ε 4, 5, 7, 8, 1, 2, 3, 6, 9, 10, 11, 12 27 11

Syntax-directed definition with actions Some definitions can have side-effects: E T R {$2.in = $1.val; $0.val = $2.val; prf("%s", $2.in); } When will these side-effects occur? The order of evaluating attributes is linked to the order of creating nodes in the parse tree

Syntax-directed definition with actions A definition with side-effects: B X {a} Y Bottom-up parser: Perform action a as soon as X appears on top of the stack (if X is a nonterminal, we can move action a to X A 1 A 2 {a}) Top-down parser: Perform action a just before we attempt to expand Y (if Y is a non-terminal) or check for Y on the input (if Y is a terminal)

SDTs with Actions A syntax directed definition with actions: E T R R + T { pr( + ); } R R T { pr( ); } R R ε T { pr(.lookup ); }

Stack Input Action Input:9-5 + 2 E $ T R $ R $ R $ 9-5+2$ 9-5+2$ 9-5+2$ -5+2$ pr(9) E T R R + T { pr( + ); } R R T { pr( ); } R R ε T { pr(.lookup ); } - T R $ -5+2$ T R $ R $ R $ 5+2$ 5+2$ +2$ pr(5) pr(-) + - $ E T R T R + T R - T R ε +T R $ +2$ T R$ 2$ output: 9 5-2 + R$ R$ $ 2$ $ $ pr(2) pr(+) terminate SDT maps infix expressions to postfix

Actions in stack Action a for B X {a} Y is pushed to the stack when the derivation step B X {a}y is made But the action is performed only after complete derivations for X has been carried out

Stack Input Action Input:9-5 + 2 E $ T R $ R $ R $ 9-5+2$ 9-5+2$ 9-5+2$ -5+2$ pr(9) E T R R + T { pr( + ); } R R T { pr( ); } R R ε T { pr(.lookup ); } - T #A R $ -5+2$ T #A R $ #A R $ #A R $ 5+2$ 5+2$ +2$ pr(5) pr(-) + - $ E T R T R + T R - T R ε +T #B R $ +2$ T #B R$ #B R$ 2$ 2$ pr(2) #A: pr( ) #B: pr( + ) #B R$ $ pr(+) $ $ terminate

SDTs with Actions Syntax directed definition that tries to map infix expressions to prefix: E T R R { pr( + ); } + T R R { pr( ); } T R R ε T { pr(.lookup ); } Impossible to implement SDT during either top-down or bottom-up parsing, because the parser would have to perform pring actions long before it knows whether these symbols will appear in its input.

Marker non-terminals Bottom-up translation for L-attributed definitions: Assumption: each symbol X has one synthesized (X val ) and one inherited (X in ) attribute (or actions) 1. Replace each A X 1 X n by: A M 1 X 1 M n X n, M i ε (new marker non-terminals) 2. When reducing by M i ε Compute X i.in (M i.val = X i.in) push it o stack M i X i.in X i-1 X i-1.val M i-1 X i-1.in.... X 1 X 1.val M 1 X 1.in M A A.in..

Marker non-terminals 3. When reducing by A M 1 X 1 M n X n : A.val = f(m 1.val, X 1.val M n.val, X n.val) Push A o stack (M i.val = X i.in) X n.val X n.in.... X 1.val X 1.in A.in.. X n M n X 1 M 1 M A A A.val M A A.in.. 4. Simplification: if X j has no attributes or is computed by a copy rule X j.in=x j-1.val discard M j ; adjust indices suitably. If X 1.in exist and X 1.in = A.in, omit M 1

Marker Non-terminals E T R R + T { pr( + ); } R R - T { pr( - ); } R R ε T { pr(.lookup ); }

Marker Non-terminals E T R R + T M R R - T N R R ε T { pr(.lookup ); } M ε { pr( + ); } N ε { pr( - ); } Equivalent SDT using marker non-terminals

Impossible Syntax-directed Definition E { pr( + ); } E + T E { pr( - ); } E T E T T ( E ) T { pr(.lookup); } E M E + T E N E T E T M ε { pr( + ); } N ε { pr( - ); } T ( E ) T { pr(.lookup); } Tries to convert infix to prefix Causes a reduce/reduce conflict when marker non-terminals are roduced.

Summary The parser produces concrete syntax trees Abstract syntax trees: define semantic checks or a syntax-directed translation to the desired output Attribute grammars: static definition of syntaxdirected translation Synthesized and Inherited attributes S-attribute grammars L-attributed grammars Complex inherited attributes can be defined if the full parse tree is available

Extra Slides

Syntax-directed defns LR parser, S-attributed definition more details later LL parser, L-attributed definition Stack $T )T F $T )T id $T )T Input id)*id$ id)*id$ )*id$ action record: T.in = F.val Output T F T { $2.in = $1.val } F id { $0.val = $1.val } The action record stays on the stack when T is replaced with rhs of rule

LR parsing and inherited attributes As we just saw, inherited attributes are possible when doing top-down parsing How can we compute inherited attributes in a bottom-up shift-reduce parser Problem: doing it incrementally (while parsing) Note that LR parsing implies depth-first visit which matches L-attributed definitions

LR parsing and inherited attributes Attributes can be stored on the stack used by the shift-reduce parsing For synthesized attributes: when a reduce action is invoked, store the value on the stack based on value popped from stack For inherited attributes: transmit the attribute value when executing the goto function

Example: Synthesized Attributes T F { $0.val = $1.val; } T T * F { $0.val = $1.val * $3.val; } F id { val := id.lookup(); if (val) { $0.val = $1.val; } else { error; } } F ( T ) { $0.val = $2.val; }

Productions 1 T F 2 T T*F 3 F id 4 F (T) 0: S T T F T T * F F id F ( T ) ( F T Reduce 1 1: T F 7: F ( T ) ) Reduce 4 id $ Accept 2: S T T T * F * 3: T T * F F id F ( T ) * 6: F ( T ) T T * F F ( T Reduce 2 4: T T * F id 8: F id id F Reduce 3 5: F ( T ) T F T T * F F id F ( T ) (

Trace (id val=3 )*id val=2 Stack Input Action Attributes 0 0 5 0 5 8 0 5 1 0 5 6 0 5 6 7 ( id ) * id $ id ) * id $ ) * id $ ) * id $ ) * id $ * id $ Shift 5 Shift 8 Reduce 3 F id, pop 8, goto [5,F]=1 Reduce 1 T F, pop 1, goto [5,T]=6 Shift 7 Reduce 4 F (T), pop 7 6 5, goto [0,F]=1 a.push id.val=3; { $0.val = $1.val } a.pop; a.push 3; { $0.val = $1.val } a.pop; a.push 3; { $0.val = $2.val } 3 pops; a.push 3

Trace (id val=3 )*id val=2 Stack Input Action Attributes 0 1 0 2 0 2 3 0 2 3 8 0 2 3 4 0 2 * id $ * id $ id $ $ $ $ Reduce 1 T F, pop 1, goto [0,T]=2 Shift 3 Shift 8 Reduce 3 F id, pop 8, goto [3,F]=4 Reduce 2 T T * F pop 4 3 2, goto [0,T]=2 Accept { $0.val = $1.val } a.pop; a.push 3 a.push mul a.push id.val=2 a.pop a.push 2 { $0.val = $1.val * $3.val; } 3 pops; a.push 3*2=6

Example: Inherited Attributes E T R { $2.in = $1.val; $0.val = $2.val; } R + T R { $3.in = $0.in + $2.val; $0.val = $3.val; } R ε { $0.val = $0.in; } T ( E ) { $0.val = $1.val; } T id { $0.val = id.lookup; }

Productions 1 E T R 2 R + T R 3 R ε 4 T (E) 5 T id 0: S E E T R T ( E ) T id E 8: S E Reduce 0 T ( id Reduce 3 1: E T R R + T R R ε 3: T ( E ) E T R T ( E ) T id id T 7: T id ( Reduce 5 6: R + T R Reduce 2 id R + ( Reduce 1 2: E T R 4: R + T R T ( E ) T id 5: R + T R R + T R R ε R + Reduce 3 T

Productions 1 E T R 2 R + T R 3 R ε 4 T (E) 5 T id 0: S E E T R T ( E ) T id E 8: S E Reduce 0 T ( id Reduce 3 1: E T R R + T R R ε 3: T ( E ) E T R T ( E ) T id id T 7: T id ( Reduce 5 6: R + T R Reduce 2 E id R + ( 9 Reduce 1 2: E T R 4: R + T R T ( E ) T id ) 5: R + T R R + T R R ε R 10 R4 + Reduce 3 T

Trace id val=3 +id val=2 Stack Input Action Attributes 0 0 7 0 1 0 1 4 0 1 4 7 0 1 4 5 id + id $ + id $ + id $ id $ $ Productions 1 E T R { $2.in = $1.val; $0.val = $2.val; } 2 R + T R { $3.in = $0.in + $2.val; $0.val = $3.val; } 3 R ε { $0.val = $0.in; } 4 T (E) { $0.val = $1.val; } 5 T id { $0.val = id.lookup; } $ Shift 7 Reduce 5 T id pop 7, goto [0,T]=1 Shift 4 Shift 7 Reduce 5 T id pop 7, goto [4,T]=5 Reduce 3 R ε goto [5,R]=6 { $0.val = id.lookup } { pop; attr.push(3) $2.in = $1.val $2.in := (1).attr } { $0.val = id.lookup } { pop; attr.push(2); } { $3.in = $0.in+$1.val (5).attr := (1).attr+2 $0.val = $0.in $0.val = (5).attr = 5 }

Trace id val=3 +id val=2 Stack Input Action Attributes 0 0 7 0 1 0 1 4 0 1 4 7 0 1 4 5 id + id $ + id $ + id $ id $ $ $ Shift 7 Reduce 5 T id pop 7, goto [0,T]=1 Shift 4 Shift 7 Reduce 5 T id pop 7, goto [4,T]=5 Reduce 3 R ε { $0.val = id.lookup } { pop; attr.push(3) $2.in = $1.val $2.in := (1).attr } { $0.val = id.lookup } { pop; attr.push(2); } goto [5,R]=6 { $3.in = $0.in+$1.val (5).attr := (1).attr+2 $0.val = $0.in $0.val = (5).attr = 5 }

Trace id val=3 +id val=2 Stack Input Action Attributes 0 1 4 5 6 0 1 2 $ $ Reduce 2 R + T R Pop 4 5 6, goto [1,R]=2 Reduce 1 E T R Pop 1 2, goto [0,E]=8 { $0.val = $3.val pop; attr.push(5); } { $0.val = $3.val pop; attr.push(5); } 0 8 $ Accept { $0.val = 5 attr.top = 5; }

A -> c { $0.val = $0.in } LR parsing with inherited attributes line 3 Bottom-Up/rightmost ccbca Acbca AcbB AB S A c B ca B cbb S AB Parse stack at line 3: [ x ] A [ x ] c b B $1.in = x $2.in = $1.val Consider: S AB { $1.in = x ; $2.in = $1.val } B cbb { $0.val = $0.in + y ; } Parse stack at line 4: [ x ] A B [ xy ]