Attribute Grammars. An Example. Using an Attribute Grammar. Recall the context-sensitive language from Chapter 1: L = { a n b n c n n!

Similar documents
Specifying Syntax. An English Grammar. Components of a Grammar. Language Specification. Types of Grammars. 1. Terminal symbols or terminals, Σ

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

Compilers. Compiler Construction Tutorial The Front-end

Principles of Programming Languages COMP251: Syntax and Grammars

More Assigned Reading and Exercises on Syntax (for Exam 2)

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

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

Defining syntax using CFGs

Chapter 3. Describing Syntax and Semantics ISBN

Chapter 3. Describing Syntax and Semantics

Chapter 3 (part 3) Describing Syntax and Semantics

COMP-421 Compiler Design. Presented by Dr Ioanna Dionysiou

Errata Chapter 1 Chapter 2 touched surprised then else Chapter 3

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Describing Syntax and Semantics

Defining Program Syntax. Chapter Two Modern Programming Languages, 2nd ed. 1

Chapter 3. Semantics. Topics. Introduction. Introduction. Introduction. Introduction

A Simple Syntax-Directed Translator

CS 406: Syntax Directed Translation

COSC252: Programming Languages: Semantic Specification. Jeremy Bolton, PhD Adjunct Professor

Chapter 3. Describing Syntax and Semantics

Lexical Analysis. Introduction

Chapter 3. Topics. Languages. Formal Definition of Languages. BNF and Context-Free Grammars. Grammar 2/4/2019

Syntax and Semantics

Chapter 3: CONTEXT-FREE GRAMMARS AND PARSING Part2 3.3 Parse Trees and Abstract Syntax Trees

2.2 Syntax Definition

Lecture 14 Sections Mon, Mar 2, 2009

Syntax-Directed Translation Part II

CS 403: Scanning and Parsing

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

Syntax Directed Translation

Syntax and Grammars 1 / 21

ASTs, Objective CAML, and Ocamlyacc

Syntax Analysis Check syntax and construct abstract syntax tree

THE COMPILATION PROCESS EXAMPLE OF TOKENS AND ATTRIBUTES

Chapter 3: Syntax and Semantics. Syntax and Semantics. Syntax Definitions. Matt Evett Dept. Computer Science Eastern Michigan University 1999

3. DESCRIBING SYNTAX AND SEMANTICS

Syntax. A. Bellaachia Page: 1

COP5621 Exam 3 - Spring 2005

COP 3402 Systems Software Top Down Parsing (Recursive Descent)

CSc 520 Principles of Programming Languages

Chapter 3. Parsing #1

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

CS 536 Midterm Exam Spring 2013

Principles of Programming Languages COMP251: Syntax and Grammars

Computer Science Department Carlos III University of Madrid Leganés (Spain) David Griol Barres

Syntax-Directed Translation. Introduction

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

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

Abstract Syntax Trees Synthetic and Inherited Attributes

LECTURE 11. Semantic Analysis and Yacc

Programming Languages Third Edition

Introduction to Automata Theory. BİL405 - Automata Theory and Formal Languages 1

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

Introduction to Lexical Analysis

Attribute Grammars. Attribute Grammars

4. Semantic Processing and Attributed Grammars

Project 1: Scheme Pretty-Printer

CSCE 314 Programming Languages

Chapter 3. Semantics. Topics. Introduction. Introduction. Introduction. Introduction

Regular Expressions. Agenda for Today. Grammar for a Tiny Language. Programming Language Specifications

Syntax-Directed Translation

Defining syntax using CFGs

CSX-lite Example. LL(1) Parse Tables. LL(1) Parser Driver. Example of LL(1) Parsing. An LL(1) parse table, T, is a twodimensional

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

Table-Driven Top-Down Parsers

Appendix A OCL 2.0 Grammar

Building Compilers with Phoenix

Chapter 3: Describing Syntax and Semantics. Introduction Formal methods of describing syntax (BNF)

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

Syntax. In Text: Chapter 3

TML Language Reference Manual

Context-Free Grammar. Concepts Introduced in Chapter 2. Parse Trees. Example Grammar and Derivation

MASSACHUSETTS INSTITUTE OF TECHNOLOGY Fall Test I

CSE 401 Midterm Exam 11/5/10

Programming Languages

Last time. What are compilers? Phases of a compiler. Scanner. Parser. Semantic Routines. Optimizer. Code Generation. Sunday, August 29, 2010

Last Time. What do we want? When do we want it? An AST. Now!

Syntax Analysis. Amitabha Sanyal. ( as) Department of Computer Science and Engineering, Indian Institute of Technology, Bombay

CS 4240: Compilers and Interpreters Project Phase 1: Scanner and Parser Due Date: October 4 th 2015 (11:59 pm) (via T-square)

CSCE 531 Spring 2009 Final Exam

Semantic Analysis Attribute Grammars

MIT Top-Down Parsing. Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology

COP4020 Programming Assignment 2 - Fall 2016

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

CS422 - Programming Language Design

Context-sensitive Analysis

CSE 340 Fall 2014 Project 4

Object-oriented Compiler Construction

Context-sensitive Analysis Part II

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

Language to Specify Syntax-Guided Synthesis Problems

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

7. Introduction to Denotational Semantics. Oscar Nierstrasz

Parsing a primer. Ralf Lämmel Software Languages Team University of Koblenz-Landau

CS415 Compilers Context-Sensitive Analysis Type checking Symbol tables

Some Basic Definitions. Some Basic Definitions. Some Basic Definitions. Language Processing Systems. Syntax Analysis (Parsing) Prof.

Course Overview. Introduction (Chapter 1) Compiler Frontend: Today. Compiler Backend:

Using an LALR(1) Parser Generator

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

Transcription:

Attribute Grammars An attribute grammar is a context-free grammar that has been extended to provide contextsensitive information by appending attributes to some of its nonterminals. Each distinct symbol in the grammar has associated with it a finite, possibly empty, set of attributes. Each attribute has a domain of possible values. An attribute may be assigned values from its domain during parsing. Attributes can be evaluated in assignments or conditions. Two Classes of Attributes Synthesized attribute: An attribute that gets its values from the attributes attached to the children of its nonterminal. Inherited attribute: An attribute that gets its values from the attributes attached to the parent (or siblings) of its nonterminal. An Example Recall the context-sensitive language from Chapter 1: L = { a n b n c n n!1 } Important result from computation theory: No context-free grammar recognizes L. An attempt: <string> ::= <a seq> <b seq> <c seq> <a seq> ::= a <a seq> a <b seq> ::= b <b seq> b <c seq> ::= c <c seq> c This context-free grammar recognizes the language a + b + c + = { a k b m c n k!1, m!1, n!1 } Chapter 3 1 Chapter 3 2 Using an Attribute Grammar Attach a synthesized attribute, Size, to each of the nonterminals: <a seq>, <b seq>, and <c seq>. Domain of Positive Integers Impose a condition on the first production. <string> ::= <a seq> <b seq> <c seq> Size(<a seq>)=size(<b seq>)=size(<c seq>) <a seq> ::= a Size(<a seq>)! 1 <a seq> 2 a Size(<a seq>)! Size(<a seq> 2 )+1 <b seq> ::= b Size(<b seq>)! 1 <b seq> 2 b Size(<b seq>)! Size(<b seq> 2 )+1 <c seq> ::= c Size(<c seq>)! 1 <c seq> 2 c Size(<c seq>)!size(<c seq> 2 )+1 <string> Size (<a seq>) = Size (<b seq>) = Size (<c seq>) <b seq> <c seq> <a seq> <a seq> a <b seq> b <c seq> c <a seq> a <b seq> b <c seq> c <c seq> c c <b seq> b b <a seq> a a Chapter 3 3 Chapter 3 4

a <a seq> a b <string> <b seq> <c seq> b c c Using an Inherited Attribute <string> Size (<a seq>) = Size (<b seq>) = Size (<c seq>) <b seq> <c seq> <a seq> <a seq> a <b seq> b <c seq> c b c <a seq> a a Attach a synthesized attribute Size to <a seq> and inherited attributes InSize to <b seq> and <c seq>. <string> ::= <a seq> <b seq> <c seq> InSize(<b seq>)! Size(<a seq>) InSize(<c seq>)! Size(<a seq>) <a seq> ::= a Size(<a seq>)! 1 <a seq> 2 a Size(<a seq>)! Size(<a seq> 2 )+1 <b seq> ::= b InSize(<b seq>) = 1 <b seq> 2 b InSize(<b seq> 2 )! InSize(<b seq>)-1 <c seq> ::= c InSize(<c seq>) = 1 <c seq> 2 c InSize(<c seq> 2 )! InSize(<c seq>)-1 Chapter 3 5 Chapter 3 6 Definition In In <a seq> <b seq> <c seq> In In In1 <a seq> a <b seq> b In1 In An attribute grammar is a context-free grammar augmented with attributes, semantic rules, and conditions. Let G = <N,",P,S> be a context-free grammar. Write a production p #P in the form: X 0 ::= X 1 X 2 X np where np! 1, X 0 # N, and X k # N $ " for 1 " k " np. A derivation tree for a sentence in a context-free language has the properties: a) Each of its leaf nodes is labeled with a symbol from ", and b) Each interior node t corresponds to a production p # P such that t is labeled with X 0 and t has np children labeled with X 1, X 2,, X in left-to-right order. np Chapter 3 7 Chapter 3 8

For each syntactic category X # N in the grammar, there are two finite disjoint sets: I(X) of inherited attributes, and S(X) of synthesized attributes. I(S) = % where S is the start symbol. Consider again a production p # P of the form: X 0 ::= X 1 X 2 X n p Derivation Tree: X 0 Let A(X) = I(X) $ S(X) be the set of attributes of X. X 1 X 2 X 3 X n p Each attribute Atb # A(X) takes a value from some semantic domain associated with that attribute e.g. integers, strings of characters, structures of some type The values of attributes are defined by semantic functions or semantic rules associated with the productions in P. Each synthesized attribute Atb # S(X 0 ) has its value defined in terms of the attributes in A(X 1 ) $ A(X 2 ) $ $ A(X n p ) $ I(X 0). Each inherited attribute Atb # I(X k ) for 1 " k " np has its value defined in terms of the attributes in A(X 0 ) $ S(X 1 ) $ $ S(X n p ). Chapter 3 9 Chapter 3 10 Each production may also have a set of conditions on the values of the attributes in A(X 0 ) $ A(X 1 ) $ $ A(X n p ) that further constrain an application of the production. The parse of a sentence in the attribute grammar is satisfied if only if the context-free grammar is satisfied and all conditions in the attribute grammar are true. The semantics of a nonterminal can be considered to be a distinguished attribute evaluated at the root node of the derivation tree of that nonterminal. Calculating Attribute Values for Binary Numerals Synthesized Inherited Nonterminals Attributes Attributes <binary numeral> Val --- <binary digits> Val Pos <fraction digits> Val, Len --- Val Pos The Attribute Grammar <binary numeral> ::= <binary digits>. <fraction digits> Val(<binary numeral>)! Val(<binary digits>)+val(<fraction digits>) Pos(<binary digits>)! 0 <binary digits> ::= <binary digits> 2 Val(<binary digits>)! Val(<binary digits> 2 ) + Val() Pos(<binary digits> 2 )! Pos(<binary digits>) + 1 Pos()! Pos(<binary digits>) Chapter 3 11 Chapter 3 12

<binary digits> ::= Val(<binary digits>)! Val() Pos()! Pos(<binary digits>) Binary Numeral Semantics: 11.1101 <fraction digits> ::= <fraction digits> 2 Val(<fraction digits>)! Val(<fraction digits> 2 ) + Val() Len(<fraction digits>)! Len(<fraction digits> 2 ) + 1 Pos()! Len(<fraction digits>) <fraction digits> ::= Val(<fraction digits>)! Val() Len(<fraction digits>)! 1 Pos()! 1 ::= 0 Val()! 0 ::= 1 Pos () Val()! 2 <binary numeral> <fraction digits> Len : <binary digits> <fraction digits> Len : <binary digits> 1 <fraction digits> Len : 1 0 <fraction digits> Len : 1 1 1 Observe the order of evaluation of attributes. Chapter 3 13 Chapter 3 14 Checking Context Constraints in Wren Augment the context-free grammar (concrete syntax) for Wren with attributes whose conditions check the context conditions of Wren. 1. The program name identifier may not be declared elsewhere in the program. 2. All identifiers that appear in a block must be declared in that block. 3. No identifier may be declared more than once in a block. 4. The identifier on the left side of an assignment command must be declared as a variable, and the expression on the right must be of the same type. 5. An identifier occurring as an (integer) element must be integer variable. 6. An identifier occurring as a boolean element must be boolean variable. 7. An identifier occurring in a read command must be integer variable. Chapter 3 15 Attribute Value Types Type Name Var-list synthesized for <type> { integer, boolean, program, undefined } inherited for <expr>, <int expr>, <term>, <element>, <bool expr>, <bool term>, and <bool element> String of letters or digits synthesized for <variable>, <identifier>, <letter>, and <digit> Sequence of Name values synthesized for <variable list> Symbol-table Set of pairs of the form [Name, Type] synthesized for <dec seq> and <dec> inherited for <block>, <cmd seq>, <cmd>, <expr>, <int expr>, <term>, <element>,<bool expr>, <bool term>, <bool element>, and <comparison> Chapter 3 16

Declarations var x,y : integer; <var list> ::= <variable> Var-list(<var list>)! cons(name(<variable>), empty-list) var <declaration> Symbol-table: S 1 = [['x',integer],['y', integer]] <variable> Name: 'x' <identifier> Name: 'x' <variable list> Var-list: ['x','y'] true, <variable list> Var-list: ['y'] <variable> Name: 'y' : <type> Type: integer integer ; <var list> ::= <variable>, <var list> 2 Var-list(<var list>)! cons(name(<variable>),var-list(<var list> 2 )) if Name(<variable>) is not a member of Var-list(<var list> 2 ) else error( Duplicate variable in declaration list ) <letter> Name: 'x' x <identifier> Name: 'y' <letter> Name: 'y' y Auxiliary Functions build-symbol-table(var-list, type) add-item(name, type, table) table-union(table1, table2) table-intersection(table1, table2) lookup-type(name, table) Chapter 3 17 Chapter 3 18 table-union(table1, table2) = if empty(table1) then table2 else if lookup-type(first-name(table1),table2) = undefined then cons(head(table1), table-union(tail(table1), table2)) else table-union(tail(table1), table2)). table-intersection(table1, table2) = if empty(table1) then empty else if lookup-type(first-name(table1),table2) # undefined then nonempty else table-intersection(tail(table1), table2). Declaration Sequences var x,y : integer; var a : boolean; <declaration sequence> Symbol-table: S 1! S 2 = [['x',integer],['y', integer],['a', boolean]] true <declaration> Symbol-table:! S 1 = [['x', integer],['y', integer]] <declaration sequence> Symbol-table:! S 2 = [['a',boolean]] <dec seq> ::= & Symbol-table(<dec seq>)! empty-table <dec seq> ::= <dec> <dec seq> 2 Symbol-table(<dec seq>)! table-union(symbol-table(<dec>), Symbol-table(<dec seq> 2 )) if table-intersection( Symbol-table(<dec>), Symbol-table(<dec seq> 2 )) = empty else error( Duplicate declaration of an identifier ) Chapter 3 19 Chapter 3 20

<declaration> ::= var <variable list> : <type>; Symbol-table(<declaration>)! build-symbol-table( Var-list(<var list>),type(<type>)). Passing Context from Declarations to Commands <program> ::= program <identifier> is <block> Symbol-table(<block>)! add-item( (Name(<identifier>), program), empty-table) <block> ::= <dec seq> begin <cmd seq> end Symbol-table(<cmd seq>)! table-union( Symbol-table(<block>), Symbol-table(<dec seq>)) if table-intersection( Symbol-table(<block>), Symbol-table(<dec seq>)) = empty else error( Program name used as a variable ) Commands <cmd> ::= <variable> := <expr> Symbol-table(<expr>)! Symbol-table(<cmd>) Type(<expr>)! lookup-type(name(<variable>), Symbol-table(<cmd>)) case lookup-type(name(<variable>), Symbol-table(<cmd>)) is integer, boolean : error( ) undefined : error( Target variable not declared ) program : error( Target variable same as program name ) <cmd> ::= read <variable> case lookup-type(name(<variable>), Symbol-table(<cmd>)) is integer : error( ) undefined : error( Variable not declared ) boolean, program : error( Integer var expected for read ) Chapter 3 21 Chapter 3 22 <command> ::= write <expr> Symbol-table(<expr>)! Type(<expr>)! integer <command> ::= while <boolean expr> do <command$sequence> end while Symbol-table(<boolean expr>)! Symbol-table(<command$sequence>)! Type(<boolean expr>)!boolean <command> ::= if <boolean expr> then <command$sequence>1 else <command$sequence>2 end if Symbol-table(<boolean expr>)! Symbol-table(<command$sequence>1)! Symbol-table(<command$sequence>2)! Type(<boolean expr>)!boolean Chapter 3 23 Chapter 3 24

Expressions Symbol-table is inherited down into the derivation trees for expressions. Need to check <variable> when expecting an integer expression or a boolean expression. <bool expr> ::= <bool term> Symbol-table(<bool term>)! Symbol-table(<bool expr>) Type(<bool term>)! Type(<bool expr>) <expr> ::= <int expr> Symbol-table(<int expr>)! Symbol-table(<expr>) Type(<int expr>)! Type(<expr>) Type(<expr>) ' { boolean } <expr> ::= <bool expr> Symbol-table(<boolean expr>)! Symbol-table(<expr>) Type(<bool expr>)! Type(<expr>) Type(<expr>) ' { integer } <bool expr> ::= <bool expr>2 or <bool term> Symbol-table(<bool expr>2)! Symbol-table(<bool expr>) Symbol-table(<bool term>)! Symbol-table(<bool expr>) Type(<bool expr>2)! Type(<bool expr>) Type(<bool term>)! Type(<bool expr>) Chapter 3 25 Chapter 3 26 <bool term> ::= <bool elem> Symbol-table(<bool elem>)! Symbol-table(<bool term>) Type(<bool elem>)! Type(<bool term>) <bool term> ::= <bool term>2 and <bool elem> Symbol-table(<bool term>2)! Symbol-table(<bool term>) Symbol-table(<bool elem>)! Symbol-table(<bool term>) Type(<bool term>2)! Type(<bool term>) Type(<bool elem>)! Type(<bool term>) <bool elem> ::= true <bool elem> ::= false <bool elem> ::= <variable> case lookup-type(name(<variable>), Symbol-table(<bool elem>)) is boolean : error( ) undefined : error( Variable not declared ) integer, program : if Type(<bool elem>) = undefined else error( Bool variable expected ) <bool elem> ::= ( <bool expr> ) Symbol-table(<bool expr>)! Symbol-table(<bool elem>) Type(<bool expr>)! Type(<bool elem>) Chapter 3 27 Chapter 3 28

<bool elem> ::= not( <bool expr> ) Symbol-table(<bool expr>)! Symbol-table(<bool elem>) Type(<bool expr>)! Type(<bool elem>) <comparison> ::= <integer expr>1 <relation> <integer expr>2 Symbol-table(<integer expr>1)! Symbol-table(<comparison>) Symbol-table(<integer expr>2)! Symbol-table(<comparison>) Type(<integer expr>1)! integer Type(<integer expr>2)! integer Implementing Attribute Grammars Parser produces a modified token list, not an abstract syntax tree. Program <program> ::= program <identifier> is <block> Symbol-table(<block>)! add-item((name(<identifier>), program), empty-table) program(tokenlist) --> [program],[ide(i)],[is], { additem(i,program,[ ],InitialSymbolTable) }, block(block, InitialSymbolTable), { flattenplus([program, ide(i), is, Block], TokenList) }. Chapter 3 29 Chapter 3 30 Block <block> ::= <dec seq> begin <cmd seq> end Symbol-table(<cmd seq>)! table-union(symbol-table(<block>), Symbol-table(<dec seq>)) if table-intersection(symbol-table(<block>), Symbol-table(<dec seq>)) = empty else error( Program name used as a var ) block([errormsg, Decs, begin, Cmds, end], InitialSymbolTable) --> decs(decs,decssymboltable), { tableintersection(initialsymboltable, DecsSymbolTable,Result), tableunion(initialsymboltable, DecsSymbolTable, SymbolTable), ( Result=nonEmpty, ErrorMsg='ERROR: Program name used as variable' ; Result=empty, ErrorMsg=noError) }, [begin], cmds(cmds,symboltable), [end]. Command Sequence <cmd seq> ::= <command> Symbol-table(<cmd>)! Symbol-table(<cmd seq>) <cmd seq> ::= <command> ; <cmd seq> 2 Symbol-table(<cmd>)! Symbol-table(<cmd seq>) Symbol-table(<cmd seq> 2 )! Symbol-table(<cmd seq>) cmds(cmds,symboltable) --> command(cmd,symboltable), restcmds(cmd,cmds,symboltable). restcmds(cmd, [Cmd, semicolon Cmds], SymbolTable) --> [semicolon], cmds(cmds,symboltable). restcmds(cmd,[cmd],symboltable) --> [ ]. Chapter 3 31 Chapter 3 32

Write Command Read Command <cmd> ::= read <variable> case lookup-type(name(<variable>), Symbol-table(<cmd>)) is integer : error( ) undefined : error( Variable not declared ) boolean, program : error( Integer var expected for read ) command([read, ide(v), ErrorMsg], SymbolTable) --> [read], [ide(v)], { lookuptype(v,symboltable,vartype), (VarType = integer, ErrorMsg=noError ; VarType = undefined, ErrorMsg='ERROR: Variable not delcared' ; (VarType = boolean ; VarType = program), ErrorMsg='ERROR: Integer variable expected for read') }. <command> ::= write <expr> Symbol-table(<expr>)! Type(<expr>)!integer command([write,e],symboltable) --> [write], expr(e,symboltable,integer). While Command <command> ::= while <boolean expr> do <command$sequence> end while Symbol-table(<boolean expr>)! Symbol-table(<command$sequence>)! Type(<boolean expr>)!boolean command([while,test,do,body,end,while], SymbolTable) --> [while], boolexpr(test,symboltable,boolean), [do], cmds(body,symboltable), [end], [while]. Chapter 3 33 Chapter 3 34 Assignment Command <command> ::= <variable> := <expr> Symbol-table(<expr>)! Symbol-table(<cmd>) Type(<expr>)! lookup-type(name(<variable>), Symbol-table(<cmd>)) case lookup-type(name(<variable>), Symbol-table(<cmd>)) is integer, boolean : error( ) undefined : error( Target variable not declared ) program : error( Target variable same as program name ) command([ide(v),assign,e,errormsg], Symtab) --> [ide(v)], [assign], { lookuptype(v, Symtab, VarType) }, ({ VarType = integer }, (expr(e,symtab,integer), { ErrorMsg=noError } ; expr(e,symtab,boolean), { ErrorMsg='ERROR: Int expr expected' }) ; { VarType = boolean }, (expr(e,symtab,boolean), { ErrorMsg=noError } ; expr(e,symtab,integer), { ErrorMsg='ERROR: Bool expr expected' }) ; { VarType = undefined, ErrorMsg='ERR: Target of asgn not decd' ; VarType = program, ErrorMsg='ERR: Prog name used as var' } expr(e,symtab,undefined)). Chapter 3 35 Chapter 3 36

Expressions <expr> ::= <integer expr> Symbol-table(<int expr>)! Symbol-table(<expr>) Type(<int expr>)! Type(<expr>) Type(<expr>) ' { boolean } <expr> ::= <boolean expr> Symbol-table(<bool expr>)! Symbol-table(<expr>) Type(<int expr>)! Type(<expr>) Type(<expr>) ' { integer } expr(e,symboltable,integer) --> intexpr(e,symboltable,integer). expr(e,symboltable,boolean) --> boolexpr(e,symboltable,boolean). expr(e,symboltable,undefined) --> intexpr(e,symboltable,undefined). expr(e,symboltable,undefined) --> boolexpr(e,symboltable,undefined). Integer Expressions <int expr> ::= <term> Symbol-table(<term>)! Symbol-table(<int expr>) Type(<term>)! Type(<int expr>) <int expr> ::= <int expr> 2 <weak op> <term> Symbol-table(<int expr> 2 )! Symbol-table(<int expr>) Symbol-table(<term>)! Symbol-table(<int expr>) Type(<int expr> 2 )! Type(<int expr>) Type(<term>)! Type(<int expr>) intexpr(e,symboltable,type) --> term(t,symboltable,type), restintexpr(t,e,symboltable,type). restintexpr(t,e,symboltable,type) --> weakop(op), term(t1, SymbolTable,Type), restintexpr([t,op,t1], E, SymbolTable,Type). restintexpr(e,e,symboltable,type) --> [ ]. Chapter 3 37 Chapter 3 38 Terms <term> ::= <element> Symbol-table(<element>)! Symbol-table(<term>) Type(<element>)! Type(<term>) <term> ::= <term> 2 <strong op> <element> Symbol-table(<term> 2 )! Symbol-table(<term>) Symbol-table(<element>)! Symbol-table(<term>) Type(<term> 2 )! Type(<term>) Type(<element>)! Type(<term>) term(t,symboltable,type) --> element(el,symboltable,type), restterm(el,t,symboltable,type). restterm(el,t,symboltable,type) --> strongop(op), element(el1, SymbolTable,Type), restterm([el,op,el1], T, SymbolTable,Type). restterm(t,t,symboltable,type) --> [ ]. Element <element> ::= <numeral> <element> ::= <variable> case lookup-type (Name(<variable>), Symbol-table(<element>)) is integer : error( ) undefined : error( Var not declared ) boolean, program : if Type(<element>) = undefined else error( Int var expected ) <element> ::= ( <expr> ) Symbol-table(<expr>)! Symbol-table(<element>) Type(<expr>)! Type(<element>) <element> ::= - <element> 2 Symbol-table(<element> 2 )! Symbol-table(<element>) Type(<element> 2 )! Type(<element>) Chapter 3 39 Chapter 3 40

element([num(n)],symtab,type) --> [num(n)]. element([ide(i),errormsg],symtab,type) --> [ide(i)], { lookuptype(i,symtab,vartype), (VarType = int, Type = int, ErrorMsg=noError ; VarType = undefined, ErrorMsg= 'ERROR: Variable not declared' ; Type = undefined, ErrorMsg=noError ; (VarType = boolean ; VarType = program), ErrorMsg='ERROR: Int var expected') }. element([lparen, E, rparen], Symtab,Type) --> [lparen], intexpr(e,symtab,type), [rparen]. element([minus E],Symtab,Type) --> [minus], element(e,symtab,type). Try It cp ~slonnegr/public/plf/context. Chapter 3 41