Winter Compiler Construction T5 – AST

Slides:



Advertisements
Similar presentations
Winter Compiler Construction T6 – semantic analysis part I scopes and symbol tables Mooly Sagiv and Roman Manevich School of Computer Science.
Advertisements

CPSC 388 – Compiler Design and Construction
1 Mooly Sagiv and Greta Yorsh School of Computer Science Tel-Aviv University Modern Compiler Design.
Abstract Syntax Mooly Sagiv html:// 1.
Winter Compiler Construction T7 – semantic analysis part II type-checking Mooly Sagiv and Roman Manevich School of Computer Science Tel-Aviv.
Mooly Sagiv and Roman Manevich School of Computer Science
Compiler Construction LR(0) + Visitor Ran Shaham and Ohad Shacham School of Computer Science Tel-Aviv University.
9/27/2006Prof. Hilfinger, Lecture 141 Syntax-Directed Translation Lecture 14 (adapted from slides by R. Bodik)
Compiler Construction Abstract Syntax Tree Ran Shaham and Ohad Shacham School of Computer Science Tel-Aviv University.
1 Semantic Processing. 2 Contents Introduction Introduction A Simple Compiler A Simple Compiler Scanning – Theory and Practice Scanning – Theory and Practice.
Abstract Syntax Trees Compiler Baojian Hua
Compiler Construction Abstract Syntax Tree Rina Zviel-Girshin and Ohad Shacham School of Computer Science Tel-Aviv University.
Slide 1 Chapter 2-b Syntax, Semantics. Slide 2 Syntax, Semantics - Definition The syntax of a programming language is the form of its expressions, statements.
Chapter 2 Chang Chi-Chung Lexical Analyzer The tasks of the lexical analyzer:  Remove white space and comments  Encode constants as tokens.
Chapter 2 A Simple Compiler
Compiler Construction Semantic Analysis I Rina Zviel-Girshin and Ohad Shacham School of Computer Science Tel-Aviv University.
2.2 A Simple Syntax-Directed Translator Syntax-Directed Translation 2.4 Parsing 2.5 A Translator for Simple Expressions 2.6 Lexical Analysis.
Chapter 1 Introduction Dr. Frank Lee. 1.1 Why Study Compiler? To write more efficient code in a high-level language To provide solid foundation in parsing.
CS412/413 Introduction to Compilers and Translators Spring ’99 Lecture 8: Semantic Analysis and Symbol Tables.
1 Mooly Sagiv and Greta Yorsh School of Computer Science Tel-Aviv University Modern Compiler Design.
Compiler Construction Dr. Noam Rinetzky and Orr Tamir School of Computer Science Tel Aviv University
Bernd Fischer RW713: Compiler and Software Language Engineering.
Chapter 2. Design of a Simple Compiler J. H. Wang Sep. 21, 2015.
CPS 506 Comparative Programming Languages Syntax Specification.
Abstract Syntax Trees Compiler Baojian Hua
11/25/2015© Hal Perkins & UW CSEH-1 CSE P 501 – Compilers Implementing ASTs (in Java) Hal Perkins Winter 2008.
Winter Compiler Construction T5 – AST Mooly Sagiv and Roman Manevich School of Computer Science Tel-Aviv University.
Compiler Principles Fall Compiler Principles Lecture 6: Parsing part 5 Roman Manevich Ben-Gurion University.
LESSON 04.
Compiler Construction Compiler Construction Semantic Analysis I.
Syntax and Semantics Form and Meaning of Programming Languages Copyright © by Curt Hill.
The Visitor Design Pattern and Java Tree Builder
Semantic Analysis II Type Checking EECS 483 – Lecture 12 University of Michigan Wednesday, October 18, 2006.
LECTURE 3 Compiler Phases. COMPILER PHASES Compilation of a program proceeds through a fixed series of phases.  Each phase uses an (intermediate) form.
Abstract Syntax Tree. 2 Compiler IC Program ic x86 executable exe Lexical Analysis Syntax Analysis Parsing ASTSymbol Table etc. Inter. Rep. (IR) Code.
Syntax-Directed Definitions CS375 Compilers. UT-CS. 1.
MiniJava Compiler A multi-back-end JIT compiler of Java.
Computer Programming – Grammar – data types – Variables – Keywords – Operators – decision making – Loops – Arrays – Functions – files Programming Environment.
Syntax Analysis Or Parsing. A.K.A. Syntax Analysis –Recognize sentences in a language. –Discover the structure of a document/program. –Construct (implicitly.
Syntax(1). 2 Syntax  The syntax of a programming language is a precise description of all its grammatically correct programs.  Levels of syntax Lexical.
Lecture 9 Symbol Table and Attributed Grammars
Chapter 3 – Describing Syntax
COMP261 Lecture 18 Parsing 3 of 4.
Context-Sensitive Analysis
Winter Compiler Construction
A Simple Syntax-Directed Translator
Constructing Precedence Table
Chapter 3 – Describing Syntax
Syntax (1).
What does it mean? Notes from Robert Sebesta Programming Languages
Implementing ASTs (in Java) Hal Perkins Autumn 2009
Winter LR(0) Parsing Summary
Syntax versus Semantics
Fall Compiler Principles Lecture 4: Parsing part 3
Presentation by Julie Betlach 7/02/2009
Basic Program Analysis: AST
CS 3304 Comparative Languages
Syntax-Directed Translation
CSE401 Introduction to Compiler Construction
R.Rajkumar Asst.Professor CSE
Syntax-Directed Translation
Implementing ASTs (in Java) Hal Perkins Autumn 2011
Mooly Sagiv and Roman Manevich School of Computer Science
Interpreter Pattern.
Computer Science and Engineering
Chapter 3 Describing Syntax and Semantics.
BNF 9-Apr-19.
Mooly Sagiv and Roman Manevich School of Computer Science
COP 4620 / 5625 Programming Language Translation / Compiler Writing Fall 2003 Lecture 2, 09/04/2003 Prof. Roy Levow.
Faculty of Computer Science and Information System
Presentation transcript:

Winter 2007-2008 Compiler Construction T5 – AST Mooly Sagiv and Roman Manevich School of Computer Science Tel-Aviv University TODO: ensure consistency in displaying the values of instrumentation predicates for concrete heaps

Today Today: Next week: EBNF Annotating ASTs AST construction IC Language ic Lexical Analysis Syntax Analysis Parsing AST Symbol Table etc. Inter. Rep. (IR) Code Generation Executable code exe Today: EBNF AST construction AST traversal Visitor pattern Next week: Annotating ASTs Symbol tables Type-checking

EBNF Extended Backus–Naur form Not supported by CUP Extends BNF with regular expressions R* R+ (ABC) R? [R] [R] stands for optional part (same as R?) Not supported by CUP Translate EBNF rules to BNF list ::= x* x ::= y [z] list ::= | x list x ::= y | y z

Abstract Syntax Trees Intermediate program representation Defines a tree What is the root of the AST? Preserves program hierarchy Node types defined by class hierarchy Generated by parser Keywords and punctuation symbols not stored (not relevant once parse tree exists) Provides clear interface to other compiler phases

Partial AST hierarchy for IC ASTNode ... Program ICClass Statement Method Field VirtualMethod StaticMethod LibraryMethod Expression ... Literal New Call Statement ... StatementBlock LocalVariable If While declaration

Eclipse type hierarchy view

used for error reporting AST node contents used for error reporting abstract class ASTNode { int getLine(); ... } class Program extends ASTNode { List<ICClass> classes; ... } Java 1.5 Generics class ICClass extends ASTNode { String name; List<Field> fields; List<Method> methods; // ICClass superclass; ... }

Reduce class_list ::= class_list:cl class:c {: RESULT = cl.add(c); :} Actions part of IC.cup non terminal Program program; non terminal ICClass class; non terminal List<ICClass> class_list; program ::= class_list:cl {: RESULT = new Program(getLine(), cl); :} ; class_list ::= class:c {: RESULT = new LinkedList<ICClass>(); RESULT.add(c); :} | class_list:cl class:c {: cl.add(c); RESULT = cl; :} ; In reality, use value field of Symbol object stack Symbol stack class_list class cl c Reduce class_list ::= class_list:cl class:c {: RESULT = cl.add(c); :} class_list RESULT Symbol stack object stack pop class pop class_list push class_list

Reduce class_list ::= class_list:cl class:c {: RESULT = cl.add(c); :} Actions part of IC.cup non terminal Program program; non terminal ICClass class; non terminal List<ICClass> class_list; program ::= class_list:cl {: RESULT = new Program(getLine(), cl); :} ; class_list ::= class:c {: RESULT = new LinkedList<ICClass>(); RESULT.add(c); :} | class_list:cl class:c {: cl.add(c); RESULT = cl; :} ; Reduce class_list ::= class_list:cl class:c {: RESULT = cl.add(c); :} class_list RESULT Symbol stack object stack

AST traversal Once AST stable want to operate on tree AST traversal for type-checking AST traversal for transformation (IR) AST traversal for pretty-printing (-dump-ast) Each operation in separate pass

Non-Object Oriented approach prettyPrint(ASTNode node) { if (node instanceof Program) { Program prog = (Program) node; for (ICClass icc : prog.classes) { prettyPrint(icc); } } else if (node instanceof ICClass) { ICClass icc = (ICClass) node; printClass(icc); } else if (node instanceof BinaryExpression) { BinaryExpression be = (BinaryExpression) node; prettyPrint(be.lhs); System.out.println(be.operator); prettyPrint(be.rhs); } ... } Messy code instanceof + down-casting error-prone Not extensible

Visitor Pattern Separate operations on objects of a data structure from object representation Each operation (pass) may be implemented as separate visitor Use double-dispatch to find right method for object Instance of a design pattern Recommended book Design Patterns / Gang of Four

Single dispatch - polymorphism conceptually, one-dimensional table index op class A { void op() {…} } A class B extends A { @Override void op() {…} } Java 1.5 annotation B class C extends A { @Override void op() {…} } C

What if we need more operations? class A { void op1() {…} void op2() {…} void op3() {…} } class B extends A { @Override void op1() {…} @Override void op2() {…} @Override void op3() {…} } Want to separate complicated operations from data structures class C extends A { @Override void op1() {…} @Override void op2() {…} @Override void op3() {…} }

What if we need more operations? class op1 { … // lots of code } class A { } class op2 { … // lots of code } class B extends A { } × class C extends A { } class op3 { … // lots of code } Problem: OO languages support only single-polymorphism. We seem to need double-polymorphism

Visitor pattern in Java interface Visitor { visit(A a); visit(B c); visit(C c); } class A { A x; accept(Visitor v) { v.visit(this); } } class op1 implements Visitor { visit(A a) {…} visit(B c) {…} visit(C c) {…} } class B extends A { accept(Visitor v) { v.visit(this); } } × class op2 implements Visitor { visit(A a) {…} visit(B c) {…} visit(C c) {…} } class C extends A { accept(Visitor v) { v.visit(this); } } class op3 implements Visitor { visit(A a) {…} visit(B c) {…} visit(C c) {…} }

Double dispatch example Visitor v = new op1(); // op1/2/3 A x = new B(); // x can be A/B/C x.accept(v); class op1 implements Visitor { visit(A a) { } 1st dispatch class B { accept(Visitor v) { // always calls visit(B b) v.visit(this); } } 2nd dispatch visit(B b) { … } }

Double dispatch example Visitor v = new op1(); // op1/2/3 A x = new B(); // x can be A/B/C x.accept(v); class op1 implements Visitor { visit(A a) { } 1st dispatch class B { accept(Visitor v) { // always calls visit(B b) v.visit(this); } } 2nd dispatch visit(B b) { … } } x.accept(v) op1 op2 op3 A B C 1st dispatch Visitor pattern conceptually implements two-dimensional table op1.visit(B b) v.visit(this) 2nd dispatch

Straight Line Program example prog  stmt_list stmt_list  stmt stmt_list  stmt_list stmt stmt  var = expr; stmt  print(expr); expr  expr + expr expr  expr - expr expr  expr * expr expr  expr / expr expr  - expr expr  ( expr ) expr  number expr  readi() expr  var ASTNode Stmt Expr PrintStmt BinaryOpExpr AssignStmt UnaryOpExpr StmtList NumberExpr ReadIExpr VarExpr (Code available on web site. Demonstrates scanning, parsing, AST + visitors)

Printing visitor example public class PrettyPrinter implements Visitor { public void print(ASTNode root) { root.accept(this); } public void visit(StmtList stmts) { for (Stmt s : stmts.statements) { s.accept(this); System.out.println(); } } // x = 2*7 public void visit(AssignStmt stmt) { stmt.varExpr.accept(this); System.out.print("="); stmt.rhs.accept(this); System.out.print(";"); } // x public void visit(VarExpr expr) { System.out.print(expr.name); } // 2*7 public void visit(BinaryOpExpr expr) { expr.lhs.accept(this); System.out.print(expr.op); expr.rhs.accept(this); } ... } Java 1.5 enhanced for loop interface Visitor { void visit(StmtList stmts); void visit(Stmt stmt); void visit(PrintStmt stmt); void visit(AssignStmt stmt); void visit(Expr expr); void visit(ReadIExpr expr); void visit(VarExpr expr); void visit(NumberExpr expr); void visit(UnaryOpExpr expr); void visit(BinaryOpExpr expr); }

Visitor variations interface PropagatingVisitor { /** Visits a statement node with a given * context object (book-keeping) * and returns the result * of the computation on this node. */ Object visit(Stmt st, Object context); Object visit(Expr e, Object context); Object visit(BinaryOpExpr e, Object context); ... } Propagate values down the AST (and back)

Evaluating visitor example public class SLPEvaluator implements PropagatingVisitor { public void evaluate(ASTNode root) { root.accept(this); } /** x = 2*7 */ public Object visit(AssignStmt stmt, Object env) { Expr rhs = stmt.rhs; Integer expressionValue = (Integer) rhs.accept(this, env); VarExpr var = stmt.varExpr; ((Environment)env).update(var, expressionValue); return null; } /** expressions like 2*7 and 2*y */ public Object visit(BinaryOpExpr expr, Object env) { Integer lhsValue = (Integer) expr.lhs.accept(this, env); Integer rhsValue = (Integer) expr.rhs.accept(this, env); int result; switch (expr.op) { case PLUS: result = lhsValue.intValue() + rhsValue.intValue() ; ... } return new Integer(result); } ... } class Environment { Integer get(VarExpr ve) {…} void update(VarExpr ve, int value) {…} }

AST traversal 1+2+x class BinaryOpExpr extends Expression { Object accept(Visitor v) { return v.visit(this); } Expression lhs, rhs; AST traversal 1+2+x class NumberExpr extends Expression { Object accept(Visitor v) { return v.visit(this); } int val; 6 root BinaryOpExpr + left right visit (lhs) 3 3 visit (rhs) public class SLPEvaluator … { public Object visit(BinaryOpExpr e, Object env) { Integer lhsValue=(Integer)e.lhs.accept(this,env); Integer rhsValue=(Integer)e.rhs.accept(this,env); int result; switch (expr.op) { case PLUS: result=lhsValue.intValue()+rhsValue.intValue(); ... } return new Integer(result); } public Object visit(NumberExpr e,Object env) { return e.value; } public Object visit(VarExpr e, Object env) { return ((Environment)env).get(e); } BinaryOpExpr + left right 2 1 visit (lhs) visit (rhs) NumberExpr NumberExpr VarExpr value = 1 value= 2 name = x SLPEvaluator ev = new SLPEvaluator(); Integer result = (Integer)root.accept(ev); (alternative: let accept do tree walking)

Visitor + Generics interface PropagatingVisitor<DownType,UpType> { UpType visit(Stmt st, DownType d); UpType visit(Expr e, DownType d); UpType visit(VarExpr ve, DownType d); ... } public class SLPEvaluator implements PropagatingVisitor<Environment,Integer> { public Integer visit(VarExpr expr, Environment env) { return env.get(expr); } ... }

See you next week