138
DEREK RAYSIDE & ECE351 STAFF ECE351 LAB MANUAL UNIVERSITY OF WATERLOO

ECE351 Lab Manual - University of Waterloovganesh/TEACHING/S2014/ECE351/ECE351... · ece351 lab manual 5 ... 1 Overview of ece351 Labs . . . . . . . . . . . . . . . . . . 15 2 Lab

  • Upload
    dokiet

  • View
    223

  • Download
    1

Embed Size (px)

Citation preview

  • D E R E K R AY S I D E & E C E 3 5 1 S TA F F

    ECE 3 5 1 L A B M A N U A L

    U N I V E R S I T Y O F W AT E R L O O

  • 2 derek rayside & ece351 staff

    Copyright 2014 Derek Rayside & ECE351 StaffCompiled May 7, 2014

    acknowledgements:

    Prof Paul Ward suggested that we look into something with vhdl to have synergy with ece327.

    Prof Mark Aagaard, as the ece327 instructor, consulted throughout the development of this material.

    Prof Patrick Lam generously shared his material from the last offering of ece251.

    Zhengfang (Alex) Duanmu & Lingyun (Luke) Li [1b Elec] wrote solutions to most labs in txl.

    Jiantong (David) Gao & Rui (Ray) Kong [3b Comp] wrote solutions to the vhdl labs in antlr.

    Aman Muthrej and Atulan Zaman [3a Comp] wrote solutions to the vhdl labs in Parboiled.

    Michael Thiessen [3a Comp] improved the vhdl grammar in Parboiled.

    TAs Jon Eyolfson, Vajih Montaghami, Alireza Mortezaei, Wenzhu Man, and Mohammed Hassan.

    TA Wallace Wu developed the vhdl labs.

    High school students Brian Engio and Tianyu Guo drew a number of diagrams for this manual, wroteJavadoc comments for the code, and provided helpful comments on the manual.

    Licensed under Creative Commons Attribution-ShareAlike (CC BY-SA) version 2.5 or greater.http://creativecommons.org/licenses/by-sa/2.5/ca/http://creativecommons.org/licenses/by-sa/3.0/

    http://creativecommons.org/licenses/by-sa/2.5/ca/http://creativecommons.org/licenses/by-sa/3.0/

  • Contents

    0 Overview 15 Compiler Concepts: call stack, heapProgramming Concepts: version control,

    push, pull, merge, SSH keys, IDE,debugger, objects, pointers

    0.1 How the Labs Fit Together . . . . . . . . . . . . . . . . . . 150.2 Learning Progressions . . . . . . . . . . . . . . . . . . . . 170.3 How this project compares to CS241, the text book, etc. . 190.4 Student work load . . . . . . . . . . . . . . . . . . . . . . 200.5 How this course compares to MIT 6.035 . . . . . . . . . . 210.6 Where do I learn more? . . . . . . . . . . . . . . . . . . . 210.7 Full-Adder Circuit Example . . . . . . . . . . . . . . . . . 220.8 Pre-Lab: Computing Environment . . . . . . . . . . . . . 24

    0.8.1 Our Environment . . . . . . . . . . . . . . . . . . . 240.8.2 Getting Your Code . . . . . . . . . . . . . . . . . . 240.8.3 Updating Your Repository . . . . . . . . . . . . . 240.8.4 Committing Changes . . . . . . . . . . . . . . . . 240.8.5 Uploading Your Repository . . . . . . . . . . . . . 250.8.6 Picturing Git . . . . . . . . . . . . . . . . . . . . . 250.8.7 Eclipse on your computer . . . . . . . . . . . . . . 260.8.8 Configuring Eclipse . . . . . . . . . . . . . . . . . 260.8.9 Standard Java Data Structures . . . . . . . . . . . 260.8.10 Pre-Lab Exercise . . . . . . . . . . . . . . . . . . . 27

    0.9 How to do these labs . . . . . . . . . . . . . . . . . . . . . 270.10 Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280.11 I think I found a bug in the skeleton code . . . . . . . . . 290.12 I want to change the skeleton code for my own usage . . 290.13 Object-Oriented Programming . . . . . . . . . . . . . . . 30

    0.13.1 Visualizing Objects and Pointers . . . . . . . . . . 300.14 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300.15 Phases of Compilation . . . . . . . . . . . . . . . . . . . 320.16 Engineers and Other Educated Persons . . . . . . . . . . 33

    1 Recursive Descent Parsing ofW 35 Compiler Concepts: regular languages,regular expressions, ebnf, recognizers,parsing, recursive descent, lexing,pretty-printing, abstract syntax tree(ast)

    Programming Concepts: classes, objects,variables, aliasing, immutability, objectcontract, object equality, mathematicalequivalence classes

    1.1 Write a regular expression recognizer forW . . . . . . . 351.2 Write a recursive descent recognizer forW . . . . . . . 361.3 Write a pretty-printer forW . . . . . . . . . . . . . . . . . 37

  • 4 derek rayside & ece351 staff

    1.4 Write a recursive descent parser forW . . . . . . . . . . 371.5 Pointers, Aliasing, and Immutability . . . . . . . . . . . 371.6 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . 381.7 Object Diagram of ExampleW ast . . . . . . . . . . . . 401.8 Steps to success . . . . . . . . . . . . . . . . . . . . . . . . 401.9 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 431.10 Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

    1.10.1 Tiger Book . . . . . . . . . . . . . . . . . . . . . . . 431.10.2 Programming Language Pragmatics . . . . . . . . 431.10.3 Web Resources . . . . . . . . . . . . . . . . . . . . 43

    2 TransformingW SVG for Visualization 45 Compiler Concepts: trees, transforma-tions, xml, svg

    Programming Concepts: object contract,dom vs. sax parser styles, call-backs,iterator design pattern

    2.1 Write a translator fromW svg . . . . . . . . . . . . . 462.2 Write a translator from svg W . . . . . . . . . . . . . 462.3 Introducing the Object Contract . . . . . . . . . . . . . . 47

    2.3.1 Learning to write professional code . . . . . . . . 472.3.2 Reading . . . . . . . . . . . . . . . . . . . . . . . . 48

    2.4 dom vs. sax parser styles . . . . . . . . . . . . . . . . . 492.5 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 492.6 Steps to success . . . . . . . . . . . . . . . . . . . . . . . . 50

    3 Recursive Descent Parsing of F 53 Compiler Concepts: context-free gram-mars, ll(1) grammars, predict sets,parse trees, precedence, associativity,commutativity, program equivalence

    Programming Concepts: inheritance,polymorphism, dynamic dispatch, typetests, casting, memory safety, compositedesign pattern, template design pattern,singleton design pattern, recursivefunctions, recursive structures, higher-order functions

    3.1 A Tale of Three Hierarchies . . . . . . . . . . . . . . . . 533.1.1 Parse Tree . . . . . . . . . . . . . . . . . . . . . . . 543.1.2 ast . . . . . . . . . . . . . . . . . . . . . . . . . . . 543.1.3 A peak at the Expr class hierarchy . . . . . . . . . 56

    3.2 Write a recursive-descent recognizer for F . . . . . . . . 573.3 Write a pretty-printer for the ast . . . . . . . . . . . . . . 573.4 Equals, Isomorphic, and Equivalent . . . . . . . . . . . . 573.5 Write Equals and Isomorphic for the F ast classes . . . 583.6 Write a recursive-descent parser for F . . . . . . . . . . . 583.7 Steps to success . . . . . . . . . . . . . . . . . . . . . . . . 593.8 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 603.9 Background & Reading . . . . . . . . . . . . . . . . . . . . 60

    4 Circuit Optimization: F Simplifier 61 Compiler Concepts: intermediate lan-guages, identity element, absorbingelement, equivalence of logical for-mulas, term rewriting, termination,confluence, convergence

    Programming Concepts: interpreterdesign pattern, template design pattern,representation invariants

    4.1 Simplification Rules . . . . . . . . . . . . . . . . . . . . . . 624.2 Transforming BinaryExprs to NaryExprs . . . . . . . . . 634.3 Simplify Once . . . . . . . . . . . . . . . . . . . . . . . . . 644.4 Object sharing in the simplifier . . . . . . . . . . . . . . . 654.5 The Template Method Design Pattern . . . . . . . . . . . 664.6 Class Representation Invariants . . . . . . . . . . . . . . 674.7 Mathematical Properties of Binary Operators . . . . . . 68

    4.7.1 Commutativity . . . . . . . . . . . . . . . . . . . . 684.7.2 Associativity . . . . . . . . . . . . . . . . . . . . . 68

  • ece351 lab manual 5

    4.8 Identity Element & Absorbing Element . . . . . . . . . . 694.9 Iteration to a Fixed Point . . . . . . . . . . . . . . . . . . 694.10 Confluence . . . . . . . . . . . . . . . . . . . . . . . . . . 704.11 Logical equivalence for boolean formulas . . . . . . . . 724.12 Steps to Success . . . . . . . . . . . . . . . . . . . . . . . . 734.13 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

    5 ParsingW with Parboiled 75 Compiler Concepts: parser generators,Parsing Expression Grammars (peg),push-down automata

    Programming Concepts: domain specificlanguages (dsl): internal vs. external,debugging generated code, stacks

    5.1 Introducing Parboiled . . . . . . . . . . . . . . . . . . . . 765.2 Write a recognizer forW using Parboiled . . . . . . . . . 775.3 Add actions to recognizer to make a parser . . . . . . . . 77

    5.3.1 An alternative Name() rule . . . . . . . . . . . . . 785.3.2 The stack for ourW parser will have two objects 79

    5.4 Parsing Expression Grammars (pegs) . . . . . . . . . . 795.5 A few debugging tips . . . . . . . . . . . . . . . . . . . . 815.6 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 815.7 Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

    6 Parsing F with Parboiled 83 Compiler Concepts: parser generators,Parsing Expression Grammars (peg),push-down automata

    Programming Concepts: domain specificlanguages (dsl): internal vs. external,debugging generated code, stacks

    6.1 Write a recognizer for F using Parboiled . . . . . . . . . 836.2 Add actions to recognizer to make a parser . . . . . . . . 846.3 Introducing the Composite Design Pattern . . . . . . . . 846.4 Introducing the Singleton Design Pattern . . . . . . . . 856.5 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

    7 Technology Mapping: F Graphviz 87 Compiler Concepts: common subexpres-sion elimination

    Programming Concepts: hash struc-tures, iteration order, object identity,non-determinism, Visitor design pat-tern, tree traversals: preorder, postorder,inorder

    7.1 Interpreters vs. Compilers . . . . . . . . . . . . . . . . . 887.2 Introducing the Interpreter Design Pattern . . . . . . . . 887.3 Introducing the Visitor Design Pattern . . . . . . . . . . 90

    7.3.1 Is Visitor always better than Interpreter? . . . . . 927.4 Hash Structures, Iteration Order, and Object Identity . . 977.5 Non-determinism: Angelic, Demonic, and Arbitrary . . 997.6 Translate one formula at a time . . . . . . . . . . . . . . . 997.7 Perform common subexpression elimination . . . . . . . 997.8 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

    8 Simulation: F Java 103 Compiler Concepts: program generation,name capture

    Programming Concepts:8.1 Name Collision/Capture . . . . . . . . . . . . . . . . . . 1038.2 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 1058.3 Bonus Lab: F to x86 . . . . . . . . . . . . . . . . . . . . . 106

    9 vhdl Recognizer & Parser 107 Compiler Concepts:Programming Concepts:9.1 Keywords and Whitespaces . . . . . . . . . . . . . . . . . 110

    9.2 vhdl Recognizer . . . . . . . . . . . . . . . . . . . . . . . 1109.3 vhdl Parser . . . . . . . . . . . . . . . . . . . . . . . . . . 110

  • 6 derek rayside & ece351 staff

    9.4 Engineering a Grammar . . . . . . . . . . . . . . . . . . 1119.5 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

    10 vhdl vhdl: Desugaring & Elaboration 113 Compiler Concepts: desugaring, functioninlining

    Programming Concepts:10.1 Pointers, Immutability and Tree Rewriting with Visitor 11310.2 vhdl vhdl: Desugaring . . . . . . . . . . . . . . . . . 11410.3 Elaboration . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

    10.3.1 Inlining Components without Signal List in Archi-tecture . . . . . . . . . . . . . . . . . . . . . . . . . 114

    10.3.2 Inlining Components with Signal List in Architec-ture . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

    10.3.3 Inlining Components with Processes in Architec-ture . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

    10.3.4 Notes . . . . . . . . . . . . . . . . . . . . . . . . . . 11810.4 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

    11 vhdl Process Splitting & Combinational Synthesis 11911.1 Process Splitter . . . . . . . . . . . . . . . . . . . . . . . . 11911.2 Splitter Notes . . . . . . . . . . . . . . . . . . . . . . . . . 12111.3 Synthesizer . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

    11.3.1 If/Else Statements . . . . . . . . . . . . . . . . . . 12211.3.2 Example Synthesizing Signal Assignment Statements12311.3.3 Example Synthesizing If/Else Statements . . . . . 123

    11.4 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

    12 Simulation: F Assembly 12512.1 Which assembler to use? . . . . . . . . . . . . . . . . . . . 12512.2 masm32 Configuration . . . . . . . . . . . . . . . . . . . . 12612.3 masm32 JNI and x86 Assembly . . . . . . . . . . . . . . . 12612.4 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

    A Extra vhdl Lab Exercises 131A.1 Define-Before-Use Checker . . . . . . . . . . . . . . . . . 131

    A.1.1 Some Tips . . . . . . . . . . . . . . . . . . . . . . . 132A.2 Inline F intermediate variables . . . . . . . . . . . . . . . 132

    B Advanced Programming Concepts 133B.1 Immutability . . . . . . . . . . . . . . . . . . . . . . . . . . 133B.2 Representation Invariants . . . . . . . . . . . . . . . . . . 134 Tiger: repOk() methodsB.3 Functional Programming . . . . . . . . . . . . . . . . . . . 134

    C Design Patterns 135 See the Design Patterns book orWikipedia or SourceMaking.comC.1 Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

    C.2 Singleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135C.3 Composite . . . . . . . . . . . . . . . . . . . . . . . . . . . 135C.4 Template Method . . . . . . . . . . . . . . . . . . . . . . . 136 Tiger: Lab manual

  • ece351 lab manual 7

    C.5 Interpreter . . . . . . . . . . . . . . . . . . . . . . . . . . . 136C.6 Visitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 Tiger: 4.3 + lab manual

    D Bibliography 137 denotes conceptual sections

  • List of Figures

    1 Overview of ece351 Labs . . . . . . . . . . . . . . . . . . 152 Lab dependencies . . . . . . . . . . . . . . . . . . . . . . . 163 Descriptions of individual labs with the compiler and pro-

    gramming concepts introduced in each . . . . . . . . . . 184 Student hours spent on labs in winter 2013 . . . . . . . . 205 Student hours spent on labs in summer 2013. (Partial data

    to lab 9.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 Source code for full adder circuit (vhdl) . . . . . . . . . 227 Input waveform for full adder (W) . . . . . . . . . . . . . 228 Boolean formulas for full adder (F generated from source

    code in Figure 6) . . . . . . . . . . . . . . . . . . . . . . . 229 Gates for full adder (generated from formulas in Figure 8) 2210 Input and output waveforms for full adder (generated from

    formulas in Figure 8 and input waveform in Figure 7) . 2311 Relationship between local repository, student server repos-

    itory, and skeleton repository . . . . . . . . . . . . . . . . 2512 Basic terminology of oop . . . . . . . . . . . . . . . . . . 3013 Phases of compilation and the labs in which we see them 32

    1.1 Example waveform file for an or gate . . . . . . . . . . . 351.2 Grammar forW . . . . . . . . . . . . . . . . . . . . . . . . 351.3 Aliasing and mutable vs. immutable data . . . . . . . . . 381.4 Assignment and re-assignment of x . . . . . . . . . . . . 391.5 Assignment interferes with analysis and optimization . . 391.6 Object diagram for exampleW ast . . . . . . . . . . . . 401.7 Steps to success for Lab 1 . . . . . . . . . . . . . . . . . . 411.8 Legend for Figure 1.7 . . . . . . . . . . . . . . . . . . . . . 42

    2.1 Example waveform file for an or gate . . . . . . . . . . . 452.2 Rendered svg ofW file from Figure 2.1 . . . . . . . . . . 452.3 First 10 lines of svg text ofW file from Figure 2.1 . . . . 462.4 Objects with and without implemented equals methods 472.5 Steps to success for Lab 2 . . . . . . . . . . . . . . . . . . 502.6 How Lab 1 and Lab 2 fit together . . . . . . . . . . . . . . 51

  • 10 derek rayside & ece351 staff

    3.1 ll(1) Grammar for F . . . . . . . . . . . . . . . . . . . . 533.2 Object diagram for example F ast . . . . . . . . . . . . . 553.3 Some highlights from the Expr class hierarchy . . . . . . 563.4 Steps to success for Lab 3 . . . . . . . . . . . . . . . . . . 59

    4.1 Optimizations for F programs. . . . . . . . . . . . . . . . 624.2 Four trees that represent logically equivalent circuits. The

    sorted n-ary representation makes equivalence comparisonseasier. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

    4.3 AndExpr.simplifyOnce() . . . . . . . . . . . . . . . . . . . 644.4 OrExpr.simplifyOnce() . . . . . . . . . . . . . . . . . . . . 644.5 NaryExpr.simplifyOnce() . . . . . . . . . . . . . . . . . . 644.6 Object sharing in the F simplifier . . . . . . . . . . . . . 654.7 Template Design Pattern illustrated by UML Class Diagram 664.8 Code listing for Expr.simplify() showing iteration to a fixed

    point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694.9 Example of two confluent rewrites converging on a com-

    mon solution . . . . . . . . . . . . . . . . . . . . . . . . . . 704.10 Equivalent truth tables . . . . . . . . . . . . . . . . . . . . 72

    5.1 Snippet of a recognizer written in Parboileds dsl . . . . 775.2 Snippet of a parser written in Parboileds dsl . . . . . . 785.3 Stack of Parboiled parser from Figure 5.2 while process-

    ing input Ren Stimpy . . . . . . . . . . . . . . . . . . . . 785.4 An alternative definition of the Name() rule in Figure 5.2 785.5 Snippet of a parser written in Parboileds dsl (Figure 5.2).

    Extended with debugging commands. Corresponding tothe recognizer snippet in Figure 5.1. . . . . . . . . . . . . 79

    6.1 ll(1) Grammar for F (reproduced from Figure 3.1) . . . 836.2 uml class diagram for Composite Design Pattern . . . . 846.3 The only two instances of class ConstantExpr . . . . . . . 856.4 Preventing clients from instantiating class ConstantExpr . 85

    7.1 Example Graphviz input file and rendered output . . . . 877.2 A uml class diagram for a subset of F expression class hi-

    erarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 897.3 uml class diagram for F Expr hierarchy, Interpreter de-

    sign pattern . . . . . . . . . . . . . . . . . . . . . . . . . . 897.4 Matrix view of Interpreter Design Pattern . . . . . . . . . 897.5 uml class diagram for F Expr hierarchy, Visitor design pat-

    tern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 907.6 uml class diagram for F Expr hierarchy, Visitor design pat-

    tern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 917.7 Matrix view of Visitor Design Pattern . . . . . . . . . . . 91

  • ece351 lab manual 11

    7.8 Abstract super class for Visitors for F expression asts . 917.9 Signature and implementation of accept method. . . . . 927.10 The traverse methods of ExprVisitor . . . . . . . . . . . . 947.11 Implementation of PostOrderExprVisitor . . . . . . . . . 957.12 Implementation of ExtractAllExprs . . . . . . . . . . . . . 967.13 Iteration order for different data structures . . . . . . . . 977.14 Object identity for different data structures . . . . . . . . 987.15 Synthesized circuit without common subexpression elim-

    ination . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1007.16 Synthesized circuit with common subexpression elimina-

    tion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

    8.1 Simulator for F program x

  • Reflections

    3.1 Can you write a regular expression recognizer for F? No, be-cause F allows nested expressions / balanced parentheses. Check-ing that the parentheses are balanced requires a pushdown au-tomata, which is strictly more powerful the finite state machinethat would be adequate to recognize a regular language. . . . 57

    3.2 Is the result of pretty-printing an ast always character-by-characteridentical with the original input program? Write a program inF for which the result of pretty-printing the ast is not identi-cal to the original input string. . . . . . . . . . . . . . . . . . . 58

  • Overview

    Compiler Concepts: call stack, heapProgramming Concepts: version control,

    push, pull, merge, SSH keys, IDE,debugger, objects, pointers

    0.1 How the Labs Fit Together

    The overall structure of our vhdl synthesizer and simulator is de-picted in Figure 1.

    W

    SVG

    vizW

    F simplifier

    dot

    technology mapper

    .java

    simulator generator

    PNG

    Graphviz

    .class

    javac

    VHDL

    combinational synthesis

    desugaring elaboration

    process splitting

    Figure 1: Overview of ece351 Labs.Nodes represent file types (e.g.,

    vhdl). All of these file types, with theexception of .class and png files, aretext files.

    Edges represent translators betweendifferent file types. Solid edges repre-sent translators that we will implementin ece351. Dotted edges representtranslators provided by third-partiessuch as Sun/Oracle (javac) or AT&TResearch (dot).

    The three-part edge between .classand W nodes is intended to indicatethat the .class file we generate will reada waveform (W) file as input and writea waveform (W) file as output.

    Labels on edges describe the transla-tion(s) performed.

    Numbers on edges indicate theorder in which we will implement thosetranslators in ece351. For example, thefirst translator that we will implementwill transform waveform files to svgfiles (svg is an xml-based graphics fileformat).

    The general direction of our workin ece351 will be from the bottom ofthe figure towards the top. We will startwith file types that have the simplestgrammars and work towards file typeswith more complicated grammars.

  • 16 ece351 lab manual [may 7, 2014]

    1. W recursive descent

    2. W to SVG 3. F recursive descent 5. W parboiled

    4. F simplifier 6. F parboiled

    7. F tech. mapper 8. F simulator 9. V parboiled

    10. V elaborator 11. V splitter

    Figure 2: Lab dependencies. A solidline indicates that the code is neededto test the future lab. For example, youneed to have a working implementationof lab1 in order to test lab2.

    A dotted line indicates that ideasfrom one lab feeds into the next lab. Forexample, you learn the grammar ofWin lab1 and then use that idea againin lab5. Not all of the dotted lines areshown, in order to simplify the graph.

    The shaded nodes indicate labs thatyou need to focus on because they areused by future labs. If you must skip alab, skip something like 2, 5, 8, 10, or11 that are not used as much by futurelabs.

  • overview 17

    0.2 Learning Progressions

    There are a variety of undergraduate compiler projects. Almost all ofthem involve compiling a subset of some imperative programminglanguage to assembly. In the past Pascal was the popular language tocompile, whereas these days Java is.

    The ece351 labs are different. On a superficial level, the differ-ence is that these labs use a subset of vhdl as the input language,and produce circuit gate diagrams and simulations as outputs. Thedeeper difference is that our project is designed around two parallellearning progressionsrather than around the logical structure of a com- The idea of a learning progression

    has been used in hockey for severaldecades. It is recently attracting atten-tion in educational circles. For example,suppose that the goal of the practiceis to have the players skate quicklyaround the circles with the puck. Toprogress to that goal the team mightstart with skating around circles, thenskating in a straight line with the puck,then skating around the circles slowlywith the puck, and finally skatingaround the circles quickly with thepuck. The skills are first practiced inisolation and at slower speeds, and thenfinally all together at high speed.

    piler. This project comprises both a programming skills progression anda compiler concepts progression.

    The key technical decision that enables these progressions is torestrict our subset of vhdl to combinational circuits: no loops, notiming, etc.. From this decision flows the design of a simple interme-diate language, F , for boolean formulas, and the design of a simpleauxiliary language,W , for boolean waveforms. The project pro-gresses from the simplest language (W) to the most complex (vhdl),performing parsing, transformation, and translation on each of thethree languages. Repetition with increasing complexity (hopefully)leads to mastery.

  • 18 ece351 lab manual [may 7, 2014]

    # Description Compiler Concepts Programming Concepts

    0 Prelab call stack, heap version control, push, pull, merge,SSH keys, IDE, debugger, objects,pointers

    1 ParsingW by recur-sive descent

    regular languages, regular expres-sions, ebnf, recognizers, parsing,recursive descent, lexing, pretty-printing, abstract syntax tree (ast)

    classes, objects, variables, aliasing,immutability, object contract, objectequality, mathematical equivalenceclasses

    2 TranslatingW to svg(visualization)

    trees, transformations, xml, svg object contract, dom vs. sax parserstyles, call-backs, iterator designpattern

    3 Parsing F by recur-sive descent

    context-free grammars, ll(1) gram-mars, predict sets, parse trees, prece-dence, associativity, commutativity,program equivalence

    inheritance, polymorphism, dynamicdispatch, type tests, casting, memorysafety, composite design pattern,template design pattern, singletondesign pattern, recursive functions,recursive structures, higher-orderfunctions

    4 Simplifying F pro-grams(optimization)

    intermediate languages, identityelement, absorbing element, equiv-alence of logical formulas, termrewriting, termination, confluence,convergence

    interpreter design pattern, templatedesign pattern, representation invari-ants

    5 ParsingW with aparser generator

    parser generators, Parsing Expres-sion Grammars (peg), push-downautomata

    domain specific languages (dsl):internal vs. external, debugginggenerated code, stacks

    6 Parsing F with aparser generator

    parser generators, Parsing Expres-sion Grammars (peg), push-downautomata

    domain specific languages (dsl):internal vs. external, debugginggenerated code, stacks

    7 Translating F toGraphviz (technol-ogy mapping)

    common subexpression elimination hash structures, iteration order,object identity, non-determinism,Visitor design pattern, tree traversals:preorder, postorder, inorder

    8 Translating F to Java(circuit simulation)

    program generation, name capture

    9 Parsing vhdl with aparser generator

    10 vhdl elaboration desugaring, function inlining11 vhdl process split-

    ting and translationto F (combinationalsynthesis)

    B Translating F toassembly

    instruction selection, register alloca-tion

    assembly, linking

    DP stands for design pattern; B stands for bonus labFigure 3: Descriptions of individuallabs with the compiler and program-ming concepts introduced in each

  • overview 19

    0.3 How this project compares to CS241, the text book, etc.

    ece351 cs241 Tiger cs444 mit 6.035Language(s) vhdl, F ,W Java Java Java JavaCompiler Phases

    Parsing

    Symbol tables

    Type checking ?

    Dataflow analysis ?

    Optimization

    ?

    Translation

    Assembly

    PedagogySkills Progression

    Concept Progression

    Background

    Tests

    Workload

    2 2

  • 20 ece351 lab manual [may 7, 2014]

    0.4 Student work load

    lab0

    lab1

    lab2

    lab3

    lab4

    lab5

    lab6

    lab7

    lab8

    lab9

    lab1

    0

    lab1

    1

    0

    10

    20

    30

    40

    Lab Hours Data

    Lab

    Hou

    rsFigure 4: Student hours spent on labsin winter 2013. The target is five hoursper lab. About half the students hitthis target on most labs, as indicatedby the bars in the middle of the boxes.On most labs, 75% of the studentscompleted the lab within eight hours,as indicated by the top of the boxes.

    Some students took much longerthan eight hours. If you are one ofthose students, please consider takingadvantage of our course collaborationpolicy. The point of the collaborationpolicy is for you to learn more in lesstime.

    The exceptional labs that took moretime were 4 and 9. This term we willbe increasing the ta resources for lab4, and also changing the way we teachlab 9, in an effort to get these numbersdown.

    lab0 lab1 lab2 lab3 lab4 lab5 lab6 lab7 lab8 lab9

    010

    2030

    40

    Lab#

    Hou

    r

    Figure 5: Student hours spent on labs insummer 2013. (Partial data to lab 9.)

  • overview 21

    0.5 How this course compares to MIT 6.035

    mits (only) undergraduate compilers course is 6.035. It differs fromece351 in a two important ways:

    a. 6.035 is rated at 12 hours per week for 14 weeks, whereas ece351is rated at 10 hours per week for 12 weeks: a 48 hour nominaldifference. Moreover, 6.035 makes no effort to keep the workloadnear the course rating, whereas ece351 actively tracks studenthours and over half the students get the work done in the ratedtime. So the actual difference is much larger than the nominal.

    6.035 also comes in an 18 hour per week variant.

    b. 6.035 is an elective course, whereas ece351 is a required course.Elective courses only get students who have the interest and abil-ity; required courses get everyone. On the flipside, not everygraduate of mit eecs will know compilers: some will be totallyignorant. At uw we guarantee a minimum level of quality in ourgraduates (this approach is also required for ceab accreditation).

    0.6 Where do I learn more?

    If you are interested in learning more about compilers at uw yournext step is cs444. If you take ece351 and cs444 then you will knowmore than if you took mit 6.035. cs462 covers the theoretical endof formal languages and parsing, although this knowledge wontgreatly improve your practical skills. In the graduate curriculumcs644 and cs744 are offered on a semi-regular basis. There are also anumber of graduate courses in both ece and cs on program analysisthat are offered irregularly.

  • 22 ece351 lab manual [may 7, 2014]

    0.7 Full-Adder Circuit Example

    entity full_adder is port (A, B, Cin: in bit;S, Cout: out bit

    );

    end full_adder;

    architecture full_adder_arch of full_adder isbegin

    S

  • overview 23

    A

    B

    Cin

    Cout

    S

    Figure 10: Input and output waveformsfor full adder (generated from formulasin Figure 8 and input waveform inFigure 7)

  • 24 ece351 lab manual [may 7, 2014]

    0.8 Pre-Lab: Computing Environment

    0.8.1 Our Environment

    Follow the instructions at ecegit.uwaterloo.ca/documentation/ andensure you can authenticate properly. There are instructions for in-stalling git (the version control software were using) and a link togit references as well. Note that git is already installed in the comput-ers in E2 2363.

    0.8.2 Getting Your Code TERM is the term number, which youcan find at http://www.adm.uwaterloo.ca/infocour/CIR/SA/under.html. It isfour digits. The first digit is always 1.The second two digits are the year. Thelast digit is the month the term startson. So 1145 indicates spring term of2014 (starts in May, the fifth month).

    All of the code and materials are hosted on ecegit.uwaterloo.ca. Fol-low these steps to set up your repository.

    mkdir ~/git cd ~/git git clone [email protected]:ece351/TERM/USERNAME/labs ece351-labs

    replace USERNAME with your username

    cd ece351-labs git submodule init git submodule update git remote add skeleton [email protected]:ece351/TERM/skeleton

    0.8.3 Updating Your Repository

    If there are updates, assuming youre back on the master branch,type the following command to merge in the changes:

    cd ~/git/ece351-labs git pull git pull skeleton master git submodule update

    If there are any conflicts type git status to check which files youneed to modify. Modify the file(s) and keep whatever changes youwant. Afterwards commit your conflict resolution for the merge.Clean merges will create a commit for you.

    0.8.4 Committing ChangesCommit after every logical work unit.

    When you have changes you want to add to the repository (theyshould be visible when you type git status) you need to committhem. If status shows files that are modified you can do git commit -am "Descriptive message here"to add them to your repository. This should be the type of commityou use most of the time during the labs.

    ecegit.uwaterloo.ca/documentation/http://www.adm.uwaterloo.ca/infocour/CIR/SA/under.htmlhttp://www.adm.uwaterloo.ca/infocour/CIR/SA/under.htmlecegit.uwaterloo.ca

  • overview 25

    If you want to read up on git here are the most important partsyoull need to know:

    http://git-scm.com/book/en/Getting-Started-Git-Basics discussesworking directory / staging area / git repository

    http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repositoryhow to use it locally

    http://git-scm.com/book/en/Git-Branching-What-a-Branch-Isbasics on branching

    http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Mergingmerging

    http://git-scm.com/book/en/Git-Basics-Working-with-Remotesworking with servers, were using two remotes (origin for yourchanges and skeleton for staff changes)

    http://git-scm.com/book/en/Git-Tools-Submodules you wontneed this yet, but when we start testing youll need this

    0.8.5 Uploading Your RepositoryPush at the end of every work session.

    When you want to upload your commits to ecegit simply type thefollowing:

    git push

    0.8.6 Picturing Git

    ecegit server

    My Computer

    Student Repo Local Repopull

    Skeleton Repo pull skeleton master Git Working Copy

    commit

    Eclipse Workspace

    push

    Figure 11: Relationship between localrepository, student server repository,and skeleton repository

    http://git-scm.com/book/en/Getting-Started-Git-Basicshttp://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repositoryhttp://git-scm.com/book/en/Git-Branching-What-a-Branch-Ishttp://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merginghttp://git-scm.com/book/en/Git-Basics-Working-with-Remoteshttp://git-scm.com/book/en/Git-Tools-Submodules

  • 26 ece351 lab manual [may 7, 2014]

    0.8.7 Eclipse on your computer

    Eclipse is already installed on the lab computers. These instructions Q:\eng\ece\util\eclipse.batare for installing it on your computer, if you choose to do so.

    Download Eclipse Classic 4.2.2 from http://www.eclipse.org/downloads/packages/eclipse-classic-421/junosr1

    Launch Eclipse

    Click File then Import or pres Alt-f then i

    Open the General folder

    Select Existing Projects into Workspace

    Click Next

    Set Select root directory: ~/git/ece351-labs (or wherever yourrepository is

    Make sure ece351 is checked under Projects

    Make sure Copy projects into workspace is unchecked

    Click Finish

    0.8.8 Configuring Eclipse

    JUnit Launcher to enable assertions:

    Go to Window / Preferences / Java / JUnit Check Add -ea to VM arguments for new launch configurations Click Apply and close the window

    Switch package presentation mode to hierarchical:

    Click the downwards pointing triangle icon in the Package Ex-plorer

    Select Package Presentation / Heirarchical on the menu

    0.8.9 Standard Java Data StructuresTo open a type in Type Hierarchy viewselect Open Type in Hierarchy from theNavigate menu, or press Shift+Ctrl+H,and then key in the name of the type.

    Open java.util.List in Eclipses Type Hierarchy View. What are thesubclasses of List in the java.util package? What is the differencebetween them?

    Open java.util.Set in Eclipses Type Hierarchy View. What are thesubclasses of Set in the java.util package? What are the differencesbetween them?

    Open java.util.Map in Eclipses Type Hierarchy View. What are thesubclasses of Map in the java.util package? What are the differencesbetween them?

    Q:\eng\ece\util\eclipse.bathttp://www.eclipse.org/downloads/packages/eclipse-classic-421/junosr1http://www.eclipse.org/downloads/packages/eclipse-classic-421/junosr1

  • overview 27

    0.8.10 Pre-Lab Exercise

    We created an update for you to merge into yours, follow the aboveinstructions to get it. Afterwards there should be meta directories inyour repository. Edit meta/hours.txt with how many hours it tookfor lab0.1

    1 lab0 is this prelab exercise, includingany time you spend installing softwareon your own computer.

    Common Problem 1: Second TestPrelabtest fails. If you are on the machinesin E2 2363, you may find that the sec-ond test in TestPrelab does not pass.In order to fix this, do the following.Click Window and go to Preferences.In the tree view select Java, then In-stalled JREs and click Add. Hit Next(Standard VM should be selected al-ready), then Directory, navigate toC:\Program Files\Java\jdk, or some-thing similar, and hit Finish. Finally,check the jdk in the Installed JREs paneand click OK.Common Problem 2: testJUnitConfigu-ration fails, but you have followed thesteps above in 0.8.8. Probably youtried to run TestPrelab before followingthe steps from 0.8.8. The steps from0.8.8 only adds ea to new run con-figurations; it does not change existingrun configurations. You now need tochange the TestPrelab run configurationindividually so that it includes ea inthe VM arguments.

    Here is a checklist:

    Got updates from the skeleton Merged updates into your master branch Run TestPrelab (testEclipseJDKConfiguration and testJUnitConfig-

    uration should pass, the rest should fail and you should read thereason why)

    Run TestImports (should pass) Run build.xml (this is the marking script) Right-click on a single test to run it individually Familiarize yourself with the Eclipse debugger: breakpoints,

    watches, etc. Edit meta/hours.txt Uploaded your changes

    0.9 How to do these labs

    The lab manual will tell you what files you need to edit, what li-braries you should use, and what tests to run. The lab manual willalso explain what you need to do at each point in the code, and thebackground concepts you need to understand the lab. Most of thedagger () sections in the lab manual are to explain these backgroundconcepts. Every place in the skeleton code that you need to edit ismarked by both a Todo351Exception and a TODO marker. We will dis-cuss the next weeks lab in class every Friday.

    Despite this clear and explicit instruction, some students have dif-ficulty getting started on these labs. Why? What is missing from theinstructions described above? The lab manual doesnt tell you the orderin which you should edit the files. There is an important reason for this:execution order is the wrong way to think about developing object-oriented software (most of the time). The right way to think aboutobject-oriented software is to focus on developing cohesive and ex-tendible modules (classes). In this way object-oriented programming

    In ece250 you did object-orientedprogramming in the small. That is, youdefined structures that spanned oneor two classes and operations on thosestructures that spanned one or twomethods. The programs you workedon were perhaps several hundred lineslong.

    In ece351 you will work on a codebase that is over 8,000 lines of code, ofwhich you will write about 1000 lines,at an average rate of about 100 lines perweek. The structures we will work withare defined across dozens of classes,and the operations on those structuresare similarly defined across dozens ofmethods. This is the first time in theece curriculum that you are exposed toprogramming in the large. At this scale,modularity and code structure reallymatter.

    By the standards of modern industrialsoftware development, 8,000+ lines isjust approaching medium sized. Thecode structuring ideas you will learnin these labs can take you up to maybe100,000 lines: beyond that you will neednew ideas and modularity mechanisms.

    (in the large) is mentally quite different from procedural program-ming (in the small). In procedural programming (in the small) onethinks primarily about the order in which the steps are performed.

    Now dont misunderstand this to mean that execution orderdoesnt matter: it does. Its just that execution order is generally aseparate design concern from modularity and extensibility. The best

  • 28 ece351 lab manual [may 7, 2014]

    way to understand the execution order of a large object-oriented pro-gram is to run it and observe it in the debugger or via some othertracing mechanism (e.g., printf).

    If you want to figure out what code you should edit first, run thetest harness and see where an exception is thrown. Fix that. Then runagain, get another exception, etc.. The fix step might be quick andeasy, or it might require reading several pages of the lab manual tounderstand what needs to be done at that particular point. Remem-ber, the lab manual describes everything that needs to be done andwhere it needs to be done, it just doesnt describe the order in whichyou should do it. Aligning your editing order with the program exe-cution order is one way to guide your work that will help you buildan understanding of the code.

    Thinking on your own to develop an understanding of the skele-ton code is an important part of these labs. I promise you that it takesless time and effort to study 8,000+ lines of code than to write it fromscratch.

    0.10 Metadata

    Your workspace has a directory named meta that contains the follow-ing three files in which you can describe a few things about how yourwork on the lab went.

    collaboration.txt To record your collaborators. Each line is a triple of You must edit this file for every lab,even if all of your collaborations werejust verbal.

    lab number, collaboration role, and userid. Legal values for collab-oration roles are: verbal, partner, mentor, protege. The role fielddescribes the role of the other person, so lab2 mentor jsmith says thatJ Smith was your mentor for lab2. Similarly, lab3 protege jsmith saysthat J Smith was your protg for lab3 (i.e., you were his mentor).Both parties are required to report collaborations. If you collab-orated with more than one person on a lab then you should putmultiple lines into this file for that lab: one line for each collabora-tor on each lab.

    hours.txt Estimate of the hours you worked on each lab. This file will These data will be used solely forthe staff to assess the difficulty of thelabs. This assessment will be made inaggregate, and not on an individualbasis. These data will not be used toassess your grade. However, we willnot mark your lab until you report anestimate of your hours.

    have a line for each lab like so: lab1 5 (indicating five hours spenton lab 1). For pre-lab / computing environment time, use lab0.

    reflections.txt A free-form text file where you can give feedback to thecourse staff about what was interesting or difficult or annoying inthe labs. We will use this feedback to improve the labs for futureofferings of this course and for this offering if possible. If youwrite something interesting here it will count towards your classparticipation mark.

  • overview 29

    0.11 I think I found a bug in the skeleton code

    You are welcome to do what you like with the skeleton code. Ourrecommendation if you want to make a change is the following:

    a. Report the change you want to make (in the forum, or to a staffmember). Preferably by generating a patch.

    b. We tell you that the change is misguided and you really want todo something else.

    c. We say thanks, add that to your participation.txt and we patch theskeleton code with the change so everyone can use it.

    If you make the change yourself without reporting it then youlose out on class participation points, and if someone else reports thechange and we go to apply a patch the patch will fail on your code.This might or might not end up being a problem for you.

    0.12 I want to change the skeleton code for my own usage

    You may change the skeleton code for your own usage. Perhapsyou have a better idea of how to write something. If you make suchchanges, be careful to not create more problems than you solve. Somethings to look out for include:

    Breaking the JUnit test harnesses.

    Breaking some other code that depends on the code you arechanging.

    Messing up one of the design patterns that are an explicit part ofwhat you are supposed to be learning.

    Changing something from immutable to mutable because youdo not want to learn to work with immutable data. First, this isdepriving yourself of one of the important lessons of the labs.Second, you will likely be introducing some bugs that will be verydifficult to fix later. Immutable data is a good engineering practicethat helps you avoid many classes of difficult to diagnose and fixbugs.

    Algorithmic changes are usually safe, because the algorithmic partsof this code are usually encapsulated.

  • 30 ece351 lab manual [may 7, 2014]

    0.13 Object-Oriented Programming

    You will need to understand object-oriented programming,2 includ- 2 B. Eckel. Thinking in Java. Prentice-Hall, 2002. http://www.mindview.net/Books/TIJ/

    ing classes, objects, methods, fields, local variables, inheritance /subclassing / subtyping, polymorphism / dynamic dispatch, andmethod overloading. You will also need to understand some designpatterns,3 such as iterator, composite, and visitor. We will make some 3 E. Gamma, R. Helm, R. Johnson, and

    J. Vlissides. Design Patterns: Elementsof Reusable Object-Oriented Software.Addison-Wesley, Reading, Mass., 1995

    effort to cover these things, but they are in some sense really back-ground material for this course that you are expected to know.

    class B {String x;

    String foo() {

    String y = x + "_";

    return y;}

    }

    class D extends B {String foo() { return x; }

    }

    B is a base class or super-class D is a derived class or sub-class D extends/derives/subclasses B x is a field or instance variable y is a local variable foo is a method

    (a virtual method in C++ terms) the definition of foo in D over-

    rides the definition of foo in B

    Figure 12: Basic terminology of oop

    0.13.1 Visualizing Objects and Pointers

    It is absolutely vital that you understand objects and pointers, bothfor your own programming in the labs for this course and elsewhere,and to understand the subject material of this course. A great way tosolidify these concepts is through an appropriate visualization sys-tem such as Jeliot (for Java) and PythonTutor.com (for Python). The http://www.cs.joensuu.fi/jeliot/

    PythonTutor.comfundamental concepts of objects and pointers are the same regardlessof language: Java, Python, C#, C++, etc. You will notice that Jeliot andPythonTutor.com use very similar visualizations.

    There is also a nice set of learning objects (lessons) for learning http://cnx.org/content/col10915/latest/Java with the Jeliot visualization system.

    0.14 Testing

    Program testing can be used to show thepresence of bugs, but never to show theirabsence! Edsger W. Dijstra

    Just because your code passes all of the tests does not mean it iscorrect: there could be some as of yet unidentified test that it doesnot pass. Worse, that not-yet-identified test might occur during somelab later in the term.

    This might be the first course in which you have to write a realprogram: that is, a non-trivial program that you will have to dependon in the future. First, the labs are non-trivial: The total size of thecode for this course is about 8500 lines, of which you will have to

    http://www.mindview.net/Books/TIJ/http://www.mindview.net/Books/TIJ/PythonTutor.comhttp://www.cs.joensuu.fi/jeliot/PythonTutor.comPythonTutor.comhttp://cnx.org/content/col10915/latest/

  • overview 31

    write about 1500, and roughly 7000 will be provided for you. Second,the labs are cumulative: Each week you will run some labs that youwrote in the past. At the end of the term you will run all of themtogether. So testing will be important.

    Test inputs may be generated either manually or automaticallywith a testing tool. There are two main approaches used by tools: The Korat tool generates test inputs

    systematically based on representationinvariants.

    The Randoop tool generates inputsrandomly.

    systematic and random. Because the space of possible inputs is large,possibly infinite, systematic approaches tend to generate all small in-puts and no big inputs. Random approaches will generate a mixtureof small and large inputs. Programmers can use human insight togenerate interesting inputs that might be missed by automated tools.

    There are different strategies for evaluating whether a testpassed or failed. One is to check the computed result against aknown answer. In other words, the test suite consists of a set ofknown input/output pairs.

    Another strategy is to check general properties of functions. Forexample, that a function never returns null. An advantage of thisproperty-based approach is that one only needs the test inputs thecorresponding outputs do not need to known. Some properties thatwe will be interested in for this course include:

    reflexive x.equals(x)symmetric x.equals(y) y.equals(x)transitive x.equals(y) and y.equals(z) x.equals(z)antisymmetric x y and y x x = ytotal x y or y xidempotent f (x) = f ( f (x))invertible f ( f (x)) = x

    Some functions do not have any of these properties. But if weexpect a function to have one or more of these properties then it is agood idea to test for that property explicitly.

    In particular, the first three properties define a mathematical equiv-alence relation. We expect the equals() method in Java to represent amathematical equivalence relation.

    A total order is defined to be transitive, antisymmetric, and total.The integers, for example, are totally ordered. We expect the com-pareTo() method in Java to represent a total order.

    A good test suite will contain some of everything mentioned In a previous offering of this course thestaff provided tests that only lookedat general properties and none thatexamined specific input output pairs.It turned out that students could writecode that had the general propertywithout actually computing anythinguseful. They became unhappy whenthey discovered that their code thatpassed the staff-provided tests did notactually work when they wanted to runit on a future lab.

    above: test inputs that are generated manually and automatically,both systematically and randomly; evaluations that look at specificinput/output pairs and at general properties.

  • 32 ece351 lab manual [may 7, 2014]

    0.15 Phases of Compilation

    Scanner/Lexer/Tokenizer1, 3

    Parser1, 3, 5, 6, 9

    Type Checker

    Optimizer2, 4, 7, 10, 11

    Code Generator7, 8, 11

    Figure 13: Phases of compilation andthe labs in which we see them. Thescanner, parser, and type checker areconsidered the front end, whereas theoptimizer and code generator areconsidered the back end of the compiler.

  • overview 33

    0.16 Engineers and Other Educated Persons

    There are a number of important general skills that all educatedpersons, including engineers, should possess. The first two years ofengineering education need to focus on technical details in isolationin order for you to have the technical competency to tackle moreinteresting things. This focus on minuti sometimes comes at thecost of limited growth in these larger skills. In this course you willnot only learn lots of tiny technical details, but you will also needto develop some of the larger skills that all educated persons shouldpossess.

    The ability to quickly find relevant information. Infor- Simplicity and elegance are unpopularbecause they require hard work anddiscipline to achieve and education tobe appreciated.

    Edsgar W. Dijkstra, 1997

    mation is more accessible now than at any previous point in humanhistory. There are a wide variety of sources available to you: thecourse notes, the lab manual, old exams, the skeleton code, the rec-ommended text books, other text books, lecture notes and slides andvideos from other professors, etc. You should be facile in using all ofthese sources to find what you are looking for.

    Books, in particular, have helpful features for navigating them,such as the table of contents, the index, and the preface or introduc-tion. You should know how to use these features.

    The ability to quickly assess what information is rele- Fools ignore complexity; pragmatistssuffer it; experts avoid it; geniusesremove it.

    Alan Perlis

    vant. As old-time engineers used to say, there is always more heatthan light. Learn to see the light without being overwhelmed by theheat.

    When doctors, lawyers, accountants, and other professionals assessa case study problem, the first order of business is to discern whatthe relevant facts and issues are. Those professions explicitly traintheir people to separate the wheat from the chaff. Engineering educa-tion, especially in the first two years, is often guilty of spoon-feedingits students with only and all of the relevant information, and hencedeveloping a sense of intellectual complacency and entitlement in itsstudents.

    For example, you should be able to take a list of topics to be cov-ered from the course outline and be able to use that to determinewhich sections of the text book are relevant and which questionsfrom old exams are applicable.

  • 34 ece351 lab manual [may 7, 2014]

    The ability to accurately assess the credibility of a source.Information comes from a variety of sources. Some of them are more

    There are two ways of constructing asoftware design. One way is to makeit so simple that there are obviously nodeficiencies. And the other way is to makeit so complicated that there are no obviousdeficiencies.

    C.A.R. Hoare, 1982Turing Award Speech

    credible than others. An educated person knows, for example, thata report from the Transportation Safety Board of Canada is morelikely to be accurate than a newspaper report more likely, but notinfallibly so.

    The ability to manage large amounts of complex, inter-connected details. The human body is a complex system thatdoctors work with. The law is a complex system that lawyers workwith. Engineers work with complex socio-technical systems.

    In the first two years of engineering education you typically en-counter only small text book problems in order to gain understand-ing of specific technical concepts in isolation. The labs for this coursemight be the first time in your engineering education where youhave had to work with a non-toy system. Our skeleton code is still

    The total code base that we work within this course is about 8,000 lines.We provide about 7,000 lines of thatto you which you are expectedto understand while developing theremaining 1,000 lines.

    For reference, the source code forMicrosofts Windows operating systemis somewhere around 25 million linesof code. The source code for atisvideo card driver is about 60 millionlines more than double the Windowsoperating system. Modern chip designsalso get into millions of lines of code.

    small by industrial standards, but it might be an order of magnitudegreater than what you have worked with in your previous courses.Learning to manage this volume of complexity and interdependencyis an essential part of your professional education.

    The ability to think deep thoughts. In elementary school you Back where I come from we have universi-ties seats of great learning where mengo to become great thinkers. And when theycome out, they think deep thoughts, andwith no more brains than you have.

    The Wizard of Oz, 1939Of course, in the modern world, womennow go to (and graduate from) univer-sities in greater numbers than men.

    learned to multiply positive integers. In middle school you learnedto multiply all integers (including negative ones). In high school youlearned to multiply matrices, perhaps in two different ways: cross-product and dot-product. In first year you learned to write programsthat multiply matrices. In this course you will learn a bit about howto design and implement programming languages in which someonemight write a program to multiply matrices. You could go on in puremath and logic courses to learn more about multiplication. Its still For example, Gdels first incomplete-

    ness theorem shows that any formallogic that includes multiplication canexpress propositions that we know tobe true but which cannot be provenwithin that logic. A result that rockedthe world in 1931, and was an impor-tant intellectual precursor to Turingsproof of The Halting Problem in 1936.

    the multiplication of your childhood, but your understanding of itis much deeper for the twenty years of study that you have devotedto it. Understanding one or a few things in some depth like thishopefully cultivates in you the ability to think deeper thoughts inother domains and circumstances.

  • Lab 1Recursive Descent Parsing ofW

    Compiler Concepts: regular languages,regular expressions, ebnf, recognizers,parsing, recursive descent, lexing,pretty-printing, abstract syntax tree(ast)

    Programming Concepts: classes, objects,variables, aliasing, immutability, objectcontract, object equality, mathematicalequivalence classes

    We consider that the input and outputs of a circuit are a set of wave-forms. We use theW language for expressing waveforms in text files.Figure 1.1 shows an exampleW file and Figure 1.2 gives the gram-mar forW .

    A: 0 1 0 1 0 1 ;

    B: 1 0 1 0 1 0 ;

    OR: 1 1 1 1 1 1 ;

    Figure 1.1: Example waveform file foran or gate. The input pins are named Aand B, and the output pin is named OR.Our vhdl simulator will read aW filewith lines A and B and will produce aW file with all three lines.

    Program (Waveform)+Waveform Id : Bits ;Id Char ( Char | Digit | _ )*Char [A-Za-z]Digit [0-9]Bits (0 | 1)+

    Figure 1.2: Grammar forW in ebnf.By convention we will call the topproduction Program.

    1.1 Write a regular expression recognizer forWSources:

    ece351.w.regex.TestWRegexSimpleece351.w.regex.TestWRegexAcceptece351.w.regex.TestWRegexReject

    A recognizer is a program that accepts or rejects a string input basedon whether that string is a valid sentence in some language. A rec-ognizer forW will accept or reject a file if that file is a legalW sen-tence/program. The website regexper.com will draw

    finite-state machine diagrams foryour regular expressions. The websiteregexpal.com lets you test out yourregular expressions. There are manyother similar websites.

    W is a regular language. Regular is a technical term here that de-scribes the complexity of the grammar ofW . Regular languages arethe simplest kind of languages that we will consider. The grammar ofa regular language can be described by a regular expression.

    Your first task is to write a regular expression describing thegrammar ofW . Your final answer should be stored in the fieldTestWRegexAccept.REGEX. The file TestWRegexSimple contains meth-ods testr1 through testr9 that guide you through building up this

    regexper.comregexpal.com

  • 36 ece351 lab manual [may 7, 2014]

    regular expression in a systematic way.A challenge that you will face is that theW grammar in Figure 1.2

    does not explicitly specify whitespace, whereas your regular expres-sion will have to explicitly specify the whitespace. Grammars givenin ebnf usually implicitly assume some lexical specification thatdescribes how characters in the input string are to be grouped to-gether to form tokens. Usually any amount of whitespace may occurbetween tokens.

    1.2 Write a recursive descent recognizer forW Sources:

    ece351.w.rdescent.WRecursiveDescentRecognizer

    Libraries:ece351.util.Lexer

    Tests:ece351.w.rdescent.TestWRDRecognizerAcceptece351.w.rdescent.TestWRDRecognizerReject

    Recursive descent is a style of writing parsers (or recognizers) by hand(i.e., without using a parser generator tool). In this style we make amethod for each non-terminal in the grammar. For recognizers thesemethods return void.

    The bodies of these non-terminal methods consume the inputone token at a time. Kleene stars (*) or plusses (+) become loops.Alternation bars (|) become conditionals (if statements).

    Execution of these non-terminal methods starts at the top of thegrammar. This is what the term descent in recursive descent refers to.The term recursive in recursive descent simply means that the variousnon-terminal methods may call each other.

    By convention we will name the top production of our grammarsProgram, and so execution of our hand-written recursive descentparsers and recognizers will start in a method called program.

    YourW recognizer code will make use of the Lexer library classthat we provide. This class tokenizes the input string: i.e., strips outthe whitespace and groups the input characters into chunks called to-kens. The lexer provides a number of convenience methods, includingmethods for recognizing identifiers, so you wont need to write an id()method in your recognizer.

    The lexer has two main kinds of operations: inspect the next tokento see what it looks like, and consume the next token. The inspectmethods are commonly used in the tests of loops and conditionals.The consume methods are commonly used in regular statements.

  • [lab 1] recursive descent parsing of W 37

    1.3 Write a pretty-printer forWSources:

    ece351.w.ast.WProgramece351.w.ast.Waveform

    Libraries:java.lang.StringSystem.getProperty(line.separator)org.parboiled.common.ImmutableList

    Pretty-printing is the opposite of parsing. Parsing is the process ofconstructing an abstract syntax tree (ast) from a string input. Pretty-printing is the process of producing a string from an ast.

    For this step you will write the toString() methods for theW astclasses. These methods will be tested in the next step. Note that

    Once we have a function and its inversewe can test that f ( f (x)) = x for anyinput x.

    these toString() methods just return a string: they do not actually printto the console nor to a file. Pretty-printing is the name for the inverseof parsing, and does not necessarily involve actually printing theresult to an output stream. Whereas parsing constructs a tree from astring, pretty-printing produces a string from a tree.

    1.4 Write a recursive descent parser forWSources:

    ece351.w.rdescent.WRecursiveDescentParserLibraries:

    ece351.w.ast.WProgramece351.w.ast.Waveformece351.util.Lexerorg.parboiled.common.ImmutableList

    Tests:ece351.w.rdescent.TestWRDParserBasicece351.w.rdescent.TestWRDParserAcceptece351.w.rdescent.TestWRDParserReject

    A parser reads a string input and constructs a tree output. Specifi-cally, an abstract syntax tree (ast).

    To write your recursive descent parser forW start by copying overthe code from your recursive descent recognizer. The parser will bea superset of this code. The difference is that the recognizer discardsthe input whereas the parser will build up the ast based on theinput. The ast classes are WProgram and Waveform.

    The test performed here is to parse the input, pretty-print it, re-parse the pretty-printed output, and then compare the asts from thetwo parses to see that they are the same.

    1.5 Pointers, Aliasing, and Immutability

    One of the most important design decisions to be made in a program Mutable means can be changed orcan be mutated. Immutable meansunchangeable.

    is which data will be mutable. Mutability is a powerful feature thatcan introduce all kinds of difficult bugs if used carelessly. Two classicexamples of where to use mutability and where not to are bank ac-counts and integers, respectively. The whole point of a bank account How do decide if an object should be

    mutable?object is that the balance can change that it can be mutated. Aninteger object, by contrast, is representing an unchanging mathemat-ical abstraction. A good design question to ask yourself is whetherthe objects you are trying to model in your program represent thingsin the material world (that change, as all material things do); or aremathematical abstractions (which do not change). In this course weare dealing primarily with mathematical abstractions, and so most ofour objects will be immutable.

    A favourite example of aliasing forphilosophers is that the terms themorning star and the evening starboth refer to the planet Venus.

    Aliasing is common for people inreal life and in literature. For example,in Dostoevskys novel The BrothersKaramazov, each of the main charactershave several nicknames. The youngestbrother, Alexei Fyodorovich Karamazov,is also known as: Alyosha, Alyoshka,Alyoshenka, Alyoshechka, Alxeichick,Lyosha, and Lyoshenka. Nicknames,formal titles, and the like, add depthto human experience. But just as thisdepth can make it more difficult to readnovels, it can also make it more difficultto read programs.

    Aliasing occurs when there is more than one variable pointing toan object: i.e., the object has more than one name. Aliasing is not aproblem for immutable objects: because the immutable object can-

  • 38 ece351 lab manual [may 7, 2014]

    not change, it can be shared freely. Aliasing can introduce subtle Try PythonTutor.com to see some nicevisualizations of code execution thatmight help you understand variables,objects, and aliasing.

    bugs when mixed with mutable data though. Consider two people

    In some programming languages, suchas Python, all objects are mutable;whereas in other programming lan-guages, such as Haskell, all objects areimmutable. Languages like Java allowyou to choose which objects are muta-ble and which are immutable. Aliasingoccurs in all programming languages.

    X and Y who share a bank account. At the beginning of the day thebalance is $100. Both people head out their separate ways to sepa-rate stores. X makes a purchase for $50. A minute later, at a differentstore, Y attempts to make a purchase for $75 but is denied becausethe account no longer has sufficient funds. In this real life exampleit is fairly easy for person Y to debug what has happened. But in alarge program it can be very difficult to determine where aliases ex-ist. And, of course, discovering the alias is just the first step towardsfixing the program so that the problem does not occur during thenext execution.

    Introductory object-oriented programming is often taught in astyle where all objects are mutable and there is no aliasing. This styledoesnt work for large programs. Large programs have aliasing and probably aliasing across threads. Immutability is one simpletechnique to make aliasing a non-issue. Other solutions include com-plex sharing, locking, or usage protocols. These alternatives all intro-duce new possibilities for new kinds of subtle bugs: e.g., forgettingto follow the protocol and lock or unlock the object. Immutability All of our ast objects will be im-

    mutable. We will generally use mutabledata only in temporary local variables,and will try to avoid storing mutablevalues into the heap.

    might, in some circumstances, introduce minor inconvenience in theshort term, but it eliminates entire classes of bugs rather than intro-ducing new possibilities for bugs.

    The examples in Figure 1.3 illustrates the interaction of aliasingand mutability and immutability, respectively.

    List list = new LinkedList();List alias = list;

    list.add("hello");

    alias.add("world");

    System.out.println(list); // 1

    ImmutableList list = ImmutableList.of();

    ImmutableList alias = list;

    list.append("hello");

    alias.append("world");

    System.out.println(list); // 2

    list = list.append("hello");

    alias = alias.append("world");

    System.out.println(list); // 3

    Figure 1.3: Aliasing and mutablevs. immutable data. What output isprinted? What does the heap look like?Which variables point to which objects?What is the difference between theadd() and append() methods?

    The LinkedList class is part of theJDK. The ImmutableList class comeswith the Parboiled parser generator thatwe will use in later labs.

    1.6 Assignment

    Assignment is the feature of programming languages that lets youchange what a variable name means. It is one of the distinguishingcharacteristics of imperative programming languages. Consider thecode listing in Figure 1.4: the variable x points to foo first, and thenwe re-assign it to bar.

    PythonTutor.com

  • [lab 1] recursive descent parsing of W 39

    String x;

    x = "foo"; // assign String "foo" to variable x

    x = "bar"; // reassign variable x with String "bar"

    Figure 1.4: Assignment and re-assignment of x

    Assignment makes it more difficult to analyze and transformprograms, as illustrated in Figure 1.5. The issue is not that we give avalue a name, but that we then later change what that name meansby re-assigning it to some other value. In other words, re-assignmentis what introduces potential problems. Re-assignment is the basis ofmutation: all mutation involves changing the value associated withsome variable name (local variable, field, method parameter).

    (a) program that canbe optimized

    a = (x + y) + z;

    b = (x + y) * z;

    (b) optimization of (a)

    t = x + y;

    a = t + z;

    b = t * z;

    (c) program that can-not be optimized

    a = (x + y) + z;

    x = 7;

    b = (x + y) * z;

    Figure 1.5: Assignment interferes withanalysis and optimization. Program (c)cannot be optimized because x has beenre-assigned, so the expression x+y onthe last line will have a different valuethan the expression x+y on the first line.

    Assignment and aliasing are duals of each other. Assignment al-lows one name to have multiple meanings (values). Aliasing is whenone meaning has multiple names. Both of these language featurescan be very useful, but they both come at some cost: they make theprogram harder to understand, make it more likely to have bugs,make it more difficult to debug, and make it harder to analyze andoptimize. The cost of these features is born both by the end program-mer and by the compiler engineer.

    In the lab skeleton code we have made an effort to mitigate thecomplexities of these features by following some guidelines:

    All ast objects are immutable so that they may be safely aliasedand confidently reasoned about. Compilers typically have manyphases that transform the ast. If these transformations actuallymutate the original ast, instead of constructing a new ast, then itcan be more difficult to debug.

    Wherever possible, fields, local variables, and method parametersare declared to be final to prevent them from being re-assigned.The keyword final in Java requires the compiler to prove that thevariable is assigned exactly once on every control-flow path.

  • 40 ece351 lab manual [may 7, 2014]

    1.7 Object Diagram of ExampleW ast

    AST Tree W Example

    For the W File below the corresponding AST constructed will be:

    A: 1 0 1; B: 0 1 0;

    ASTW File

    A B[ 1 , 0 , 1 ]

    Waveform

    + name : String+ bits : ImmutableList

    Waveform

    + name : String+ bits : ImmutableList

    WProgram

    + waveforms: ImmutableList

    [ 0 , 1 , 0 ]

    [Waveform,Waveform]

    1 0 1 0 01

    Figure 1.6: Object diagram for exampleW ast

    1.8 Steps to success

  • [lab 1] recursive descent parsing of W 41

    Double Rectangle

    W Files

    Lexer1.3PrettyPrinter

    1.1Recursive Descent Recognizer

    1.2 Recursive Descent Recognizer

    1.4 Recursive Descent Parser

    RejectAccept

    Recursive Descent

    Recongnizer

    Recursive Descent Parser

    Accept RejectBasic

    RejectAccept

    Simple

    Waveform

    Wprogram

    Lab 1 Programming Procedure

    Figure 1.7: Steps to success for Lab 1.Legend for icon meanings in Figure 1.8.

  • 42 ece351 lab manual [may 7, 2014]

    Class Files / TXT Files that needed to be

    imported or exported

    Sources needed to be edit

    TXT Files that needed to be

    imported or exported

    Tests needed to be run

    Contains all the files in one section of the lab and shows the name of

    the section. Ex1.1 Recursive Descent Recognizer

    Class

    Programming Procedure Legend

    Logical Process Legend

    Method

    Figure 1.8: Legend for Figure 1.7

  • [lab 1] recursive descent parsing of W 43

    1.9 Evaluation

    The last pushed commit before the deadline is evaluated both on theshared test inputs and on a set of secret test inputs according to theweights in the table below. Note that you dont earn any points

    for the rejection tests until some of thecorresponding acceptance tests pass.Also, you dont earn any points for theparser until the TestWRDParserBasictests pass.

    Shared SecretTestWRegexAccept 10 5TestWRegexReject 5 5

    TestWRDRecognizerAccept 15 5TestWRDRecognizerReject 5 5

    TestWRDParserBasic 5 0TestWRDParserAccept 20 10TestWRDParserReject 5 5

    1.10 Reading

    1.10.1 Tiger Book1 1 A. W. Appel and J. Palsberg. Mod-ern Compiler Implementation in Java.Cambridge University Press, 2004 1 Introduction

    2.0 Lexical Analysis 2.1 Lexical Tokens 2.2 Regular Expressions 3.0 Parsing 3.2.0 Predictive Parsing / Recursive Descent

    skip First and Follow Sets for now read Constructing a Predictive Parser on p.50 skip Eliminating Left Recursion and everything that comes after

    it for now

    4.1.1 Recursive Descent

    1.10.2 Programming Language Pragmatics2 2 M. L. Scott. Programming LanguagePragmatics. Morgan Kaufmann, 3edition, 2009 2.2 Scanning

    2.3.1 Recursive Descent

    1.10.3 Web Resources

    Thinking in Java3 3 B. Eckel. Thinking in Java. Prentice-Hall, 2002. http://www.mindview.net/Books/TIJ/

    Prof Alex Aiken @ Stanford on recursive descent:http://www.youtube.com/watch?v=Kdx5HOtb-Zohttp://www.youtube.com/watch?v=S7DZdn33eFY

    http://www.mindview.net/Books/TIJ/http://www.mindview.net/Books/TIJ/http://www.youtube.com/watch?v=Kdx5HOtb-Zohttp://www.youtube.com/watch?v=S7DZdn33eFY

  • Lab 2TransformingW SVG for Visualization

    Compiler Concepts: trees, transforma-tions, xml, svg

    Programming Concepts: object contract,dom vs. sax parser styles, call-backs,iterator design pattern

    svg is a an xml-based graphics fileformat: in other words, it is structuredtext that describes some vectors to berendered. Any modern web browserwill render svg.

    While our circuit simulator programs will read and writeW files,people often prefer to look at waveforms in a graphical format. Inthis lab we will translateW files into svg files for visualization.

    An exampleW file is shown in Figure 2.1. Figure 2.2 showswhat the corresponding svg looks like when visualized with aweb browser such as Firefox or a vector graphics program such asInkscape. Figure 2.3 shows the first few lines of the textual content ofthe svg file.

    A: 0 1 0 1 0 1 ;

    B: 1 0 1 0 1 0 ;

    OR: 1 1 1 1 1 1 ;

    Figure 2.1: Example waveform file foran or gate. The input pins are named Aand B, and the output pin is named OR.Our vhdl simulator will read aW filewith lines A and B and will produce aW file with all three lines.

    Figure 2.2: Rendered svg ofW filefrom Figure 2.1

  • 46 ece351 lab manual [may 7, 2014]

    A

    Figure 2.3: First 10 lines of svg text ofW file from Figure 2.1. The boilerplateat the top is already in W2SVG.java foryour convenience.

    Note that the origin of an svgcanvas is the top left corner, not thebottom left corner (as you might expectfrom math). Consequently, Y=200 isvisually lower than Y=100, since Ycounts down from the top.

    2.1 Write a translator fromW svgSources:

    ece351.w.svg.TransformW2SVG

    Libraries:ece351.w.ast.WProgramece351.w.svg.Lineece351.w.svg.Pin

    Tests:ece351.w.svg.TestW2SVG

    The idea of the transformation is simple: for each bit (zero or one) inthe input file, produce a vertical line and a horizontal line. To do thisthe transformer needs to remember three things: the current X andY position of the (conceptual) cursor, and the YOffset so we can movethe cursor down the page when we start drawing the next waveform.

    Q : Where is the origin on an svgcanvas? Which directions are positiveand which are negative?

    Run your transformations and inspect the output both visually, ina program such as Firefox, and textually, using the text editor of yourchoice. Ensure that the output is sensible.

    2.2 Write a translator from svg WSources:

    ece351.w.svg.TransformSVG2W

    Libraries:ece351.w.ast.WProgramece351.w.svg.Lineece351.w.svg.Pin

    Tests:ece351.w.svg.TestW2SVG2W

    This translator is the inverse of the previous one. We write this in-verse function as a way to test the previous translator. Now we cantake advantage of the general property that x = f ( f (x)) or, in otherwords, w = toW(toSVG(w)).

    This inverse translation is a bit tricky because the svg files donot contain any explicit information about which line segments areassociated with which waveform: the svg file just contains a bunch oftext labels and a bunch of line segments. We have to infer, from the yvalues, which line segments belong to which waveform/label. Thenwe use the x values to infer the ordering of the bits, and the y valuesto infer the bit values (0 or 1).

    Many program analysis tasks used in optimizing compilers in-volve this kind of inference: recovering information that is implicitin a lower-level representation but was explicit in some higher-levelrepresentation.

  • [lab 2] transforming W svg for visualization 47

    2.3 Introducing the Object Contract

    Sources:ece351.objectcontract.TestObjectContract

    Libraries:ece351.objectcontract.TestObjectContractBase

    Tests:ece351.objectcontract.TestObjectContract

    The object contract is a term sometimes used to describe propertiesthat all objects should have. It is particularly concerned with theequals and hashCode methods. The equals method should representa mathematical equivalence relation and it should be consistent withthe hashCode method. A mathematical equivalence class has three The object contract looks simple (and

    it is), but even expert programmershave difficulty getting it right in allcircumstances.

    properties:reflexive x.equals(x)symmetric x.equals(y) y.equals(x)transitive x.equals(y) && y.equals(z) x.equals(z)

    Additionally, by consistent with hashCode we mean the following:consistent x.equals(y) x.hashCode() == y.hashCode() Q : What would happen if every

    hashCode method returned 42?Q : What would happen if everyhashCode method returned a randomvalue each time it was called?

    Finally, no object should be equal to null:not null !x.equals(null)

    The file TestObjectContract contains some code stubs for testing theobject contract. In order to fill in those stubs correctly you mightneed to read and understand the code in TestObjectContractBase.

    What is the default behaviour of the equals and hashCode meth- The == (double equals or equalsequals) comparison operator comparesthe memory addresses of the objectsreferred to by the two variables.

    ods? In other words, what happens if you do not implement thosemethods for your objects? Consider the code listings in Figure 2.4.What value is printed out by each statement?

    Integer x = new Integer(1);Integer y = new Integer(1);System.out.println(x.equals(y));

    System.out.println(x == y);

    List a = new LinkedList();List b = new LinkedList();System.out.println(a.equals(b));

    System.out.println(a == b);

    Object p = new Object();Object q = new Object();System.out.println(p.equals(q));

    System.out.println(p == q);

    Figure 2.4: Objects with and withoutimplemented equals methods

    2.3.1 Learning to write professional code

    It is important, in general, for you to learn the Object Contract be-cause it is a set of properties that must hold for all code you write inany object-oriented language (Java, C++, C#, Python, etc.). It is alsospecifically important that you learn the Object Contract to do thelabs in this course, because checking the equality of objects forms thebasis of the automated marking scripts. In this exercise you are alsolearning how to write professional code, with the Object Contract asan example. The steps that we are following here are:

    a. Identify the mathematical properties that the code should have.(Object contract: reflexive, symmetric, transitive, etc.)

    b. Write methods that check these mathematical properties on some

  • 48 ece351 lab manual [may 7, 2014]

    input object(s). (e.g., checkEqualsIsReflexive(x)) Call these the prop-erty check methods.

    c. Verify that the property check methods return true when expectedby using third party inputs (e.g., java.lang.String and java.lang.Integer).

    d. Verify that the property check methods return false when ex-pected by constructing pathological control objects with knowndeviant behaviour. (e.g., constructAlwaysTrue(), constructAlwaysFalse(),constructToggler(), etc.)

    e. Use the verified property check methods to assess real code.(We arent doing this step in this exercise.)

    In future labs we will use staff-provided property check methodsfor Object Contract properties. The purpose of this exercise is foryou to see what these property check methods look like, both so youunderstand the Object Contract and so you understand how yourfuture labs will be graded.

    2.3.2 Reading

    http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)http://www.artima.com/lejava/articles/equality.htmlhttp://www.angelikalanger.com/Articles/JavaSolutions/SecretsOfEquals/Equals.htmlImplementation of java.util.AbstractList.equals()Effective Java 1 1 J. Bloch. Effective Java. Addison-Wesley,

    Reading, Mass., 20010.14 of this lab manual on Testing

    Not yet discussed: inheritance, cyclicobject structures

    http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)http://www.artima.com/lejava/articles/equality.htmlhttp://www.angelikalanger.com/Articles/JavaSolutions/SecretsOfEquals/Equals.html

  • [lab 2] transforming W svg for visualization 49

    2.4 dom vs. sax parser styles

    Sources:ece351.w.svg.TransformW2SVGTry toggling the field TransformW2SVG.USE_DOM_XML_PARSER and

    see how that changes the performance of the test harnesses. One ismuch faster than the other. Why? The terms dom and sax are xml-

    specific, but the ideas are general.For example, the bcel library for

    manipulating Java bytecodes explicitlyconstructs an ast, whereas the asmlibrary for manipulating Java bytecodesis event-driven. If the transformationthat you want to do is simple enough tobe done with asm then it will probablyexecute faster if implemented with thatlibrary.

    dom-style parsers are the most common, and what we will alwayswrite in ece351. These parsers explicitly construct an ast, which canthen be examined and manipulated.

    sax-style, or event-driven parsers, on the other hand, do not explic-itly construct the ast: they just allow the user to register call-backfunctions that are triggered when certain productions in the grammarare parsed. These event-driven parsers often use much less memorybecause they do not explicitly construct an ast. They also often runfaster. But they are not suited to complex tasks. The idea of an event-driven parser

    might not be clear to you from this briefdescription. Knowing that such a styleof parser exists, its general properties,and the kinds of problems it is suitedor not suited for is enough for theexam. You are, however, encouragedto try writing a small event-drivenparser with an existing xml or Javabytecode library on your own time toget a deeper understanding of this idea.

    Why can we use a sax-style parser in our test harnesses for thislab? For a few reasons: our test harness does not need to manipu-late the xml tree; our test harness does not need to do any complexanalysis of the xml tree; we have separate ast classes (WProgram andWaveform) that we want to construct from the xml input, and the con-struction of these ast objects is simple enough to be done with anevent-driven parser.

    The Streaming api for xml (StAX)is a new event-driven parser wherethe application remains in control,instead of putting the parser in control.http://sjsxp.java.net/

    If you are interested to read more, this is a good article:http://geekexplains.blogspot.ca/2009/04/sax-vs-dom-differences-between-dom-and.html

    2.5 Evaluation

    The last pushed commit before the deadline is evaluated both on theshared test inputs and on a set of secret test inputs according to theweights in the table below.

    We provide you with about 30W files for these equations.

    Current New EquationTestW2SVG 20 10 legalSVG(TransformW2SVG(w))

    TestW2SVG2W 40 10 SVG2W(W2SVG(w)).equivalent(SVG2W(staff.svg))TestObjectContract 15 5 see 2.3 above

    http://sjsxp.java.net/http://geekexplains.blogspot.ca/2009/04/sax-vs-dom-differences-between-dom-and.html

  • 50 ece351 lab manual [may 7, 2014]

    2.6 Steps to success

    2.4 dom vs. sax parser styles2.3 Introducing the Object Contract

    2.1 Write a translator from W to svg 2.2 Write a translator from svg to W

    SVG FileTransformW2SVG

    W2SVG

    WProgram Line Pin

    TransformSVG2W

    WProgram Line Pin

    W2SVG2W

    TestObjectContract

    ObjectContract Base

    TransformW2SVG

    Lab 2 Programming Procedure

    W FIle W FIle

    Figure 2.5: Steps to success for Lab 2.Legend for icon meanings in Figure 1.8.

  • [lab 2] transforming W svg for visualization 51

    Recursive Descent Parser

    Regular Expression

    Recognizer

    1.11.4

    LAB 1W File

    WProgramWaveform

    Pretty PrintingPretty Printing

    1.3 1.3

    LAB 2

    SVG File

    TransformW2SVG TransformSVG2W

    2.1 2.2

    Figure 2.6: How Lab 1 and Lab 2 fittogether

  • Lab 3Recursive Descent Parsing of F

    Compiler Concepts: context-free gram-mars, ll(1) grammars, predict sets,parse trees, precedence, associativity,commutativity, program equivalence

    Programming Concepts: inheritance,polymorphism, dynamic dispatch, typetests, casting, memory safety, compositedesign pattern, template design pattern,singleton design pattern, recursivefunctions, recursive structures, higher-order functions

    This lab introduces formula language F , which we will use as anintermediate language in our circuit synthesis and simulation tool. Ina subsequent lab we will write a translator from vhdl to F .

    Compilers usually perform their optimizations on programs in in-termediate forms. These intermediate forms are designed to be easierto work with mechanically, at the cost of being less pleasant for peo-ple to write large programs in. A program written in F , for example,is just a list of boolean formulae. This is relatively easy to manipulatemechanically. vhdl, by contrast, has conditionals, module structure,etc., which are all of great benefit to the vhdl programmer but aremore work for the compiler writer to manipulate. In the next lab wewill write a simplifier/optimizer for F programs.

    Program Formula+ $$Fomula Var

  • 54 ece351 lab manual [may 7, 2014]

    3.1.1 Parse Tree

    Consider the F program X

  • [lab 3] recursive descent parsing of F 55

    AST Tree F Example For the F File below the corresponding AST constructed will be:

    x

  • 56 ece351 lab manual [may 7, 2014]

    3.1.3 A peak at the Expr class hierarchy

    The class hierarchy, on the other hand, does not depend on the in-put: it is how the code is organized. Find the class common.ast.Expr inEclipse, right-click on it and select Open Type Hierarchy. This will giveyou an interactive view of the main class hierarchy. Draw this hierar-chy in a uml class diagram, excluding the classes in common.ast thatyou do not need for this lab. For this lab you will need the classesAndExp