COP4020 Programming Assignment 6

Similar documents
COP4020 Programming Assignment 2 Spring 2011

COP4020 Programming Assignment 2 - Fall 2016

JavaCC Parser. The Compilation Task. Automated? JavaCC Parser

COP4020 Programming Languages. Syntax Prof. Robert van Engelen

COP4020 Spring 2011 Midterm Exam

COP4020 Programming Languages. Syntax Prof. Robert van Engelen

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

CUP. Lecture 18 CUP User s Manual (online) Robb T. Koether. Hampden-Sydney College. Fri, Feb 27, 2015

Homework. Lecture 7: Parsers & Lambda Calculus. Rewrite Grammar. Problems

COP5621 Exam 3 - Spring 2005

COP4020 Programming Languages. Semantics Prof. Robert van Engelen

Name EID. (calc (parse '{+ {with {x {+ 5 5}} {with {y {- x 3}} {+ y y} } } z } ) )

COP4020 Programming Languages. Semantics Robert van Engelen & Chris Lacher

Syntax. Syntax. We will study three levels of syntax Lexical Defines the rules for tokens: literals, identifiers, etc.

Programming Languages. Dr. Philip Cannata 1

Programming Languages. Dr. Philip Cannata 1

4. Semantic Processing and Attributed Grammars

Lecture 12: Parser-Generating Tools

Parsing. Lecture 11: Parsing. Recursive Descent Parser. Arithmetic grammar. - drops irrelevant details from parse tree

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

Static and Dynamic Semantics

CS 61B Discussion 5: Inheritance II Fall 2014

LECTURE 7. Lex and Intro to Parsing

Parser and syntax analyzer. Context-Free Grammar Definition. Scanning and parsing. How bottom-up parsing works: Shift/Reduce tecnique.

CS 406: Syntax Directed Translation

Syntax-Directed Translation Part I

LL(k) Parsing. Predictive Parsers. LL(k) Parser Structure. Sample Parse Table. LL(1) Parsing Algorithm. Push RHS in Reverse Order 10/17/2012

Input & Output in Java. Standard I/O Exception Handling

Time : 1 Hour Max Marks : 30

CSE302: Compiler Design

Programming Languages (CS 550) Lecture 4 Summary Scanner and Parser Generators. Jeremy R. Johnson

Review main idea syntax-directed evaluation and translation. Recall syntax-directed interpretation in recursive descent parsers

COMPILER CONSTRUCTION LAB 2 THE SYMBOL TABLE. Tutorial 2 LABS. PHASES OF A COMPILER Source Program. Lab 2 Symbol table

Little Language [Grand]

Simple LR (SLR) LR(0) Drawbacks LR(1) SLR Parse. LR(1) Start State and Reduce. LR(1) Items 10/3/2012

CS 230 Programming Languages

Context free grammars and predictive parsing

Structure of a compiler. More detailed overview of compiler front end. Today we ll take a quick look at typical parts of a compiler.

Chapter 2 - Programming Language Syntax. September 20, 2017

CPS 506 Comparative Programming Languages. Syntax Specification

Syntax-Directed Translation. Lecture 14

Compiler principles, PS1

Recursive Descent Parsers

The Parsing Problem (cont d) Recursive-Descent Parsing. Recursive-Descent Parsing (cont d) ICOM 4036 Programming Languages. The Complexity of Parsing

LECTURE 3. Compiler Phases

Summary: Semantic Analysis

Question Marks 1 /12 2 /6 3 /14 4 /8 5 /5 6 /16 7 /34 8 /25 Total /120

Syntax-Directed Translation Part II

Relation Overriding. Syntax and Semantics. Simple Semantic Domains. Operational Semantics

Compiler Construction

Compiler Construction

Compiler Construction

Tree visitors. Context classes. CS664 Compiler Theory and Design LIU 1 of 11. Christopher League* 24 February 2016

Lecture 14 Sections Mon, Mar 2, 2009

2068 (I) Attempt all questions.

Compiling expressions

CSE302: Compiler Design

Syntax/semantics. Program <> program execution Compiler/interpreter Syntax Grammars Syntax diagrams Automata/State Machines Scanning/Parsing

JavaCC: SimpleExamples

Peace cannot be kept by force; it can only be achieved by understanding. Albert Einstein

Syntax-Directed Translation

Question Points Score

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

public LLParser( String sourcefile, boolean verbose ) source file location verbose mode switch

CMSC 330: Organization of Programming Languages. Operational Semantics

Many strategies have been developed for this, but they often produce surprising results.

Chapter 3 (part 3) Describing Syntax and Semantics

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

MASSACHUSETTS INSTITUTE OF TECHNOLOGY Fall Test I

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

Semantic Analysis. Lecture 9. February 7, 2018

A Simple Syntax-Directed Translator

Outline. Top Down Parsing. SLL(1) Parsing. Where We Are 1/24/2013

About the Tutorial. Audience. Prerequisites. Copyright & Disclaimer. Compiler Design

Automated Tools. The Compilation Task. Automated? Automated? Easier ways to create parsers. The final stages of compilation are language dependant

JavaCUP. There are also many parser generators written in Java

G53CMP: Lecture 4. Syntactic Analysis: Parser Generators. Henrik Nilsson. University of Nottingham, UK. G53CMP: Lecture 4 p.1/32

UMBC CMSC 331 Final Exam

CS165 Practice Final Exam Answer Key

Parsing Techniques. AST Review. AST Data Structures. LL AST Construction. AST Construction CS412/CS413. Introduction to Compilers Tim Teitelbaum

Syntax and Grammars 1 / 21

Introduction to Programming Using Java (98-388)

Full file at Chapter 2 - Inheritance and Exception Handling

Principles of Programming Languages 2017W, Functional Programming

Compiler Construction

Semantic Analysis with Attribute Grammars Part 3

Semantic Analysis Attribute Grammars

CSE 401 Midterm Exam Sample Solution 2/11/15

CS 335 Lecture 02 Java Programming

([1-9] 1[0-2]):[0-5][0-9](AM PM)? What does the above match? Matches clock time, may or may not be told if it is AM or PM.

CSE3322 Programming Languages and Implementation

EDA180: Compiler Construc6on. Top- down parsing. Görel Hedin Revised: a

Syntax Directed Translation

Chapter 4. Lexical and Syntax Analysis

Syntax-Directed Translation. Introduction

Getting Started in Java. Bill Pugh Dept. of Computer Science Univ. of Maryland, College Park

.jj file with actions

Abstract Syntax Trees Synthetic and Inherited Attributes

Programming Language Syntax and Analysis

Syntax Analysis The Parser Generator (BYacc/J)

Transcription:

COP4020 Programming Assignment 6 1. Consider the following augmented LL(1) grammar for an expression language: <expr> -> <term> <term_tail> term_tail.subtotal := term.value; expr.value := term_tail.value <term> -> <factor> <factor_tail> factor_tail.subtotal := factor.value; term.value := factor_tail.value <term_tail1> -> + <term> <term_tail2> term_tail2.subtotal := term_tail1.subtotal+term.value; term_tail1.value := term_tail2.value - <term> <term_tail2> term_tail2.subtotal := term_tail1.subtotal-term.value; term_tail1.value := term_tail2.value empty term_tail1.value := term_tail1.subtotal <factor1> -> ( <expr> ) factor1.value := expr.value - <factor2> factor1.value := -factor2.value number factor1.value := number <factor_tail1> -> * <factor> <factor_tail2> factor_tail2.subtotal := factor_tail1.subtotal*factor.value; factor_tail1.value := factor_tail2.value / <factor> <factor_tail2> factor_tail2.subtotal := factor_tail1.subtotal/factor.value; factor_tail1.value := factor_tail2.value empty factor_tail1.value := factor_tail1.subtotal Note: the indexing (1 and 2) that is used with nonterminals, such as <factor1> and <factor2>, is only relevant to the semantic rules to identify the specific occurrences of the nonterminals in a production. For example, there is only one <factor> nonterminal and production in the grammar. Draw the decorated parse tree for -2*3+1 that shows the attributes and their values. 2. The following calculator Java program implements the attribute grammar shown above to calculate the value of an expression. To this end, the synthesized value attributes are returned as integer values from the methods that correspond to nonterminals. Inherited subtotal attributes are passed to the methods as arguments: /* Calc.java Implementes a parser and calculator for simple expressions Uses java.io.streamtokenizer and recursive descent parsing Compile: javac Calc.java Execute: java Calc or: java Calc <filename> */ import java.io.*; public class Calc { private static StreamTokenizer tokens; private static int token; public static void main(string argv[]) throws IOException { InputStreamReader reader; if (argv.length > 0) reader = new InputStreamReader(new FileInputStream(argv[0])); 1

reader = new InputStreamReader(System.in); // create the tokenizer: tokens = new StreamTokenizer(reader); tokens.ordinarychar(. ); tokens.ordinarychar( - ); tokens.ordinarychar( / ); // advance to the first token on the input: // parse expression and get calculated value: int value = expr(); // check if expression ends with ; and print value if (token == (int) ; ) System.out.println("Value = " + value); System.out.println("Syntax error"); // gettoken - advance to the next token on the input private static void gettoken() throws IOException { token = tokens.nexttoken(); // expr - parse <expr> -> <term> <term_tail> private static int expr() throws IOException { int subtotal = term(); return term_tail(subtotal); // term - parse <term> -> <factor> <factor_tail> private static int term() throws IOException { int subtotal = factor(); return factor_tail(subtotal); // term_tail - parse <term_tail> -> <add_op> <term> <term_tail> empty private static int term_tail(int subtotal) throws IOException { if (token == (int) + ) int termvalue = term(); return term_tail(subtotal + termvalue); if (token == (int) - ) int termvalue = term(); return term_tail(subtotal - termvalue); return subtotal; // factor - parse <factor> -> ( <expr> ) - <expr> identifier number private static int factor() throws IOException { if (token == (int) ( ) int value = expr(); if (token == (int) ) ) System.out.println("closing ) expected"); return value; if (token == (int) - ) return -factor(); if (token == tokens.tt_word) // ignore variable names return 0; if (token == tokens.tt_number) 2

return (int)tokens.nval; { System.out.println("factor expected"); return 0; // factor_tail - parse <factor_tail> -> <mult_op> <factor> <factor_tail> empty private static int factor_tail(int subtotal) throws IOException { if (token == (int) * ) int factorvalue = factor(); return factor_tail(subtotal * factorvalue); if (token == (int) / ) int factorvalue = factor(); return factor_tail(subtotal / factorvalue); return subtotal; Download this example calculator Java program from: http://www.cs.fsu.edu/ engelen/courses/cop4020/calc.java Explain why the input 1/2; to this program produces the value 0. What are the relevant parts of the program involved in computing this result? 3. We extend the attribute grammar with two new productions and two new attributes for all nonterminals: the in inherited attribute is a symbol table with identifier-value bindings that defines the bindings of identifiers in the scope (context) in which (part of) the expression is evaluated, the out synthesized attribute is a symbol table with identifier-value bindings that holds the in bindings plus the new bindings introduced by (part of) the expression as explained below. The two new productions with corresponding semantic rules are: <expr1> -> let identifier = <expr2> expr2.in := expr1.in; expr1.value := expr2.value expr1.out := expr2.out.put(identifier=expr2.value) <term> <term_tail> term.in := expr1.in; term_tail.in := term.out; term_tail.subtotal := term.value; expr1.value := term_tail.value; expr1.out := term_tail.out <factor1> -> ( <expr> ) expr.in := factor1.in; factor1.value := expr.value factor1.out := expr.out - <factor2> factor2.in := factor1.in; factor1.value := -factor2.value; factor1.out := factor2.out identifier factor1.value = factor1.in.get(identifier) number factor1.value := number; factor1.out := factor1.in 3

The first production introduces an assignment construct as an expression, similar to the C/C++ assignment which can also be used within an expression. For example, (let x = 3) + x; Value = 6 The semantic rule expr2.in := expr1.in copies the symbol table of the context in which expr1 is evaluated to the context of expr2. The evaluation of expr2 may change the symbol table and the table is copied to expr1 with the semantic rule expr1.out := expr2.out. For this part of the assignment, you have to change the semantic rules of all other productions in the grammar to include assignments for the in and out attributes to pass the symbol table. Write down the grammar with these new semantic rules. 4. Implement the two new productions and semantic rules in an updated Calc.java program. To implement a symbol table with identifier-value bindings, you can use the Java java.util.hashtable class as follows: import java.util.*; public class Calc { public static void main(string argv[]) throws IOException { Hashtable exprin = new Hashtable(); Hashtable exprout; int value = expr(exprin, exprout); private static int expr(hashtable exprin, Hashtable exprout) throws IOException { if (token == tokens.tt_word && tokens.sval.equals("let")) // advance to identifier String id = tokens.sval; // advance to = // advance to <expr> int value = expr(exprin, exprout); exprout.put(id, new Integer(value)); { int subtotal = term(exprin, termout); return term_tail(subtotal, termout, exprout); private static int factor(hashtable factorin, Hashtable factorout) throws IOException { if (token == tokens.tt_word) { String id = tokens.sval; factorout = factorin; return ((Integer)factorin.get(id)).intValue(); The put method puts a key and value in the hashtable, where the value must be a class instance so an Integer instance is created. The get method returns the value of a key. The intvalue method of Integer class returns an int. 4

Test your new Calc.java application. For example: let x = 1; Value = 1 (let x = 1) + x; Value = 2 (let a = 2) + 3 * a; Value = 8 1 + (let a = (let b = 1) + b) + a; Value = 5 5