Jingling Xue - UNSW Engineering

57
J. Xue COMP3131/9102: Programming Languages and Compilers Jingling Xue School of Computer Science and Engineering The University of New South Wales Sydney, NSW 2052, Australia http://www.cse.unsw.edu.au/~cs3131 http://www.cse.unsw.edu.au/~cs9102 Copyright @2018, Jingling Xue COMP3131/9102 Page 353 April 16, 2018

Transcript of Jingling Xue - UNSW Engineering

Page 1: Jingling Xue - UNSW Engineering

J. Xue✬

COMP3131/9102: Programming Languages and Compilers

Jingling Xue

School of Computer Science and Engineering

The University of New South Wales

Sydney, NSW 2052, Australia

http://www.cse.unsw.edu.au/~cs3131

http://www.cse.unsw.edu.au/~cs9102

Copyright @2018, Jingling Xue

COMP3131/9102 Page 353 April 16, 2018

Page 2: Jingling Xue - UNSW Engineering

J. Xue✬

Lecture 7: Attribute Grammars

1. Attribute grammars (D. E. Knuth (1968))

• S-attributed grammars

• L-attributed grammars

2. Attributes (synthesised and inherited)

3. Semantic rules (or functions)

4. The computation of attributes

• tree walkers in one or multiple passes – evaluation order

determined at compile time

• rule-based – evaluation order fixed at compiler-construction time

– can be used in the presence of a tree

– parsing and checking in one-pass without using a tree

5. Visitor design pattern

COMP3131/9102 Page 354 April 16, 2018

Page 3: Jingling Xue - UNSW Engineering

J. Xue✬

Examples

• Example 1:

– Attribute grammars

– Synthesised and inherited attributes

– Attribute evaluation

• Example 2: L-attributed

• Example 3: S-attributed (revisited from Lecture 6)

COMP3131/9102 Page 355 April 16, 2018

Page 4: Jingling Xue - UNSW Engineering

J. Xue✬

Compiler Front End

After scanning and parsing:

• Semantic analysis enforces static semantics:

– Identification (symbol table)

– Type checking

• Context-sensitive static semantics cannot be specified by a

context-free grammar (CFG) (Lecture 3)

• An attribute grammar augments a CFG to complete the

specification of what legal programs should look like

COMP3131/9102 Page 356 April 16, 2018

Page 5: Jingling Xue - UNSW Engineering

J. Xue✬

Context-Sensitive Restrictions (Static Semantics)

• Is x a variable, method, array, class or package?

• Is x declared before used?

• Which declaration of x does this reference (identification)?

• Is an expression type-consistent?

• Does the dimension of an array match with the declaration?

• Is an array reference in bounds?

• Is a method called with the right number and types of args?

• Is break or continue enclosed in a loop construct?

• etc.

These cannot be specified using a CFG!

COMP3131/9102 Page 357 April 16, 2018

Page 6: Jingling Xue - UNSW Engineering

J. Xue✬

Examples: VC Programs

Program 1: ‘‘a’’ used but not declared

void main() {a = 3;

}Program 2: ‘‘f’’ called with the wrong number of arguments

int f(int i) { }void main() {

f(1, 2);

}Program 3: incompatible operands

void main() {int i;

i = true + 1;

}

COMP3131/9102 Page 358 April 16, 2018

Page 7: Jingling Xue - UNSW Engineering

J. Xue✬

Context-Sensitive Analysis (Semantic Analysis)

• Ad hoc techniques

– Symbol table and codes

– “Action routines” in parser generators

• Formal methods:

– Attribute grammars (or other variants)

– Type systems and checking algorithms

• Our approach for VC:

– Static semantics specified

∗ in English (the VC Language Specification), and

∗ by an attribute grammar in part

– Build a semantic analyser by hand

COMP3131/9102 Page 359 April 16, 2018

Page 8: Jingling Xue - UNSW Engineering

J. Xue✬

Automatic Construction of the Front End

regular expressions

or grammars

Scanner Generator

(JLex, JavaCC)scanner

CFGs (BNF, EBNF

or other variants)

Parser Generator

(JavaCup, JavaCC)parser

attribute

grammars

Semantic Analyser

Generator

semantic

analyser

There are no widely acceptable semantic analysers.

COMP3131/9102 Page 360 April 16, 2018

Page 9: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Grammars: Informal Definition

• Attribute grammars:

– Generalisation of CFGs

– Each attribute associated with a grammar symbol

– Each semantic rule associated with a production

defining attributes

– High-level spec, independent of any evaluation order

• Dependences between attributes

– Attributes computed from other attributes

– Synthesised attributes: computed from children

– Inherited attributes: computed from parent and siblings

COMP3131/9102 Page 361 April 16, 2018

Page 10: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Grammars: Formal Definition

An attribute grammar is a triple:

A = (G, V, F )

where

• G is a CFG,

• V is a finite set of distinct attributes, and

• F is a finite set of semantic rules about the attributes.

Note:

• Each attribute is associated with a grammar symbol

• Each semantic rule is associated with a production that makes

reference only to the attributes associated with the symbols in the

production (the effect of a rule is localised within the production)

COMP3131/9102 Page 362 April 16, 2018

Page 11: Jingling Xue - UNSW Engineering

J. Xue✬

Attributes Associated with a Grammar Symbol

• A attribute can represent anything we choose:

– a string

– a number

– a type

– a memory location

– a piece of code

– etc.

• Each attribute has a name and a type

COMP3131/9102 Page 363 April 16, 2018

Page 12: Jingling Xue - UNSW Engineering

J. Xue✬

Example 1: (Simplified) Expression Grammar

• The grammar:

〈S〉 → 〈expr〉〈expr〉 → 〈expr〉 / 〈expr〉〈expr〉 → num〈expr〉 → num . num

• The grammar is ambiguous but can be used to specify the static

semantics if the parse or syntax tree has been built using an

unambiguous grammar (Lecture 6)!

• Assume that

• ”/” is left-associative, and

• Mixed expressions are promoted to float-point ones throughout

(Example: 5/2/2.0 evaluated to 1.25 not 1.00)

• Give an attribute grammar for the value of an expression

COMP3131/9102 Page 364 April 16, 2018

Page 13: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Grammar for Example 1

Production Semantic Rules

〈S〉 → 〈expr〉 〈expr.type〉 = if 〈expr.isFloat〉 then float else int

〈S.val〉 = 〈expr.val〉

〈expr1〉 → 〈expr2〉 / 〈expr3〉 〈expr1.isFloat〉 = 〈expr2.isFloat〉 or 〈expr3.isFloat〉

〈expr2.type〉 = 〈expr1.type〉

〈expr3.type〉 = 〈expr1.type〉

〈expr1.val〉 = if (〈expr1.type〉 == int)

then 〈expr2.val〉 div 〈expr3.val〉

else 〈expr2.val〉 / 〈expr3.val〉

〈expr〉 → num 〈expr.isFloat〉 = false

〈expr.val〉 = if (〈expr.type〉 == int)

then num.val else Float(num.val)

〈expr〉 → num . num 〈expr.isFloat〉 = true

〈expr.val〉 = num.num.val

COMP3131/9102 Page 365 April 16, 2018

Page 14: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Grammar for Example 1

Production Semantic Rules

〈S〉 → 〈expr〉

〈expr1〉 → 〈expr2〉 / 〈expr3〉 〈expr1.isFloat〉 = 〈expr2.isFloat〉 or 〈expr3.isFloat〉

〈expr〉 → num 〈expr.isFloat〉 = false

〈expr〉 → num . num 〈expr.isFloat〉 = true

COMP3131/9102 Page 366 April 16, 2018

Page 15: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Grammar for Example 1

Production Semantic Rules

〈S〉 → 〈expr〉 〈expr.type〉 = if 〈expr.isFloat〉 then float else int

〈S.val〉 = 〈expr.val〉

〈expr1〉 → 〈expr2〉 / 〈expr3〉

〈expr2.type〉 = 〈expr1.type〉

〈expr3.type〉 = 〈expr1.type〉

〈expr〉 → num

〈expr〉 → num . num

COMP3131/9102 Page 367 April 16, 2018

Page 16: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Grammar for Example 1

Production Semantic Rules

〈S〉 → 〈expr〉

〈S.val〉 = 〈expr.val〉

〈expr1〉 → 〈expr2〉 / 〈expr3〉

〈expr1.val〉 = if (〈expr1.type〉 == int)

then 〈expr2.val〉 div 〈expr3.val〉

else 〈expr2.val〉 / 〈expr3.val〉

〈expr〉 → num〈expr.val〉 = if (〈expr.type〉 == int)

then num.val else Float(num.val)

〈expr〉 → num . num〈expr.val〉 = num.num.val

COMP3131/9102 Page 368 April 16, 2018

Page 17: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Grammar for Example 1 (Cont’d)

• div: integer division

• /: floating-point division

• Float: a function converting an integer to a float value

• num.val and num.num.val

• computed by the scanner before semantic analysis

begins

• known as (intrinsic) synthesised attributes

COMP3131/9102 Page 369 April 16, 2018

Page 18: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Grammar for Example 1 (Cont’d)

• Synthesised attribute isFloat over {true, false} – indicating

if any part of a subexpression has a floating-point value

• Inherited attribute type over {int, float} – giving the type

of each subexpression

• Synthesised attribute val of the type int – giving the value

of each subexpression

• Dependences between the attributes:

isFloat −→ type −→ val

I.e., val depends on type, which depends on isFloat

COMP3131/9102 Page 370 April 16, 2018

Page 19: Jingling Xue - UNSW Engineering

J. Xue✬

Parse Tree for 5/2/2.0

〈S〉

〈expr〉

〈expr〉

〈expr〉

num

5

/ 〈expr〉

num

2

/ 〈expr〉

num.num

2.0

• “/” is assumed to be left-associative

• The other tree (making “/” right-associative) not used

COMP3131/9102 Page 371 April 16, 2018

Page 20: Jingling Xue - UNSW Engineering

J. Xue✬

Decorated (Annotated Parse Tree)

〈 S.val = 1.25 〉

type=float

val = 2.5/2.0 = 1.25

isFloat=true

type=float

val = 5.0/2.0 = 2.5

isFloat=false

type=float

val = Float(5) = 5.0

isFloat=false

num.val=5

/ 〈

type=float

val = Float(2) = 2.0

isFloat=false

num.val=2

/ 〈

type=float

val = 2.0

isFloat=true

num.num.val=2.0

〈expr.〉 omitted

COMP3131/9102 Page 372 April 16, 2018

Page 21: Jingling Xue - UNSW Engineering

J. Xue✬

The flow of Synthesised Attribute isFloat

〈S〉

〈expr.isFloat=true〉

〈expr.isFloat=false〉

〈expr.isFloat=false〉

num5

/ 〈expr.isFloat=false〉

num2

/ 〈expr.isFloat=true〉

num.num2.0

The synthesised attributes flow bottom-up

COMP3131/9102 Page 373 April 16, 2018

Page 22: Jingling Xue - UNSW Engineering

J. Xue✬

The flow of Inherited Attribute type

〈S〉

〈expr.type=float〉

〈expr.type=float〉

〈expr.type=float〉

num5

/ 〈expr.type=float〉

num2

/ 〈expr.type=float〉

num.num2.0

The inherited attributes flow top-down (or left-to-right or right-to-left)

COMP3131/9102 Page 374 April 16, 2018

Page 23: Jingling Xue - UNSW Engineering

J. Xue✬

The flow of Synthesised Attribute val

〈S.val=1.25〉

〈expr.val=1.25〉

〈expr.val=2.5〉

〈expr.val=5.0〉

num5

/ 〈expr.val=2.0〉

num2

/ 〈expr.val=2.0〉

num.num2.0

The synthesised attributes flow bottom-up

COMP3131/9102 Page 375 April 16, 2018

Page 24: Jingling Xue - UNSW Engineering

J. Xue✬

Formal Definitions of Synthesised and Inherited Attributes

Let

• X0 → X1X2 · · ·Xn be a production, and

• A(X) be the set of attributes associated with a grammar symbol X

Then

• A synthesised attribute, syn, of X0 is computed by:

X0.syn = f(A(X1), A(X2), . . . , A(Xn))

syn on a tree node depends on those on its children

• An inherited attribute, inh, of Xi, where 1 6 i 6 n, is computed by:

Xi.inh = g(A(X0), A(X1), . . . , A(Xn))

– inh on a tree node depends on those on its parent and/or siblings

– Xi.inh can depend on the other attributes in A(Xi)

COMP3131/9102 Page 376 April 16, 2018

Page 25: Jingling Xue - UNSW Engineering

J. Xue✬

Attribute Evaluators

• Tree Walkers: Traverse the parse or syntax tree in one pass or multiple

passes at compile time

– Capable of evaluating any noncircular attribute grammar

– An attribute grammar is circular if an attribute depends on itself

– Can decide the circularity in exponential time

– Too complex to be used in practice

• Rule-Based Methods: The compiler writer analyses the attribute

grammar and fixes an evaluation order at compiler-construction time

– Trees can still be used for attribute evaluation

– Almost all reasonable grammars can be handled this way

– Used practically in all compilers

COMP3131/9102 Page 377 April 16, 2018

Page 26: Jingling Xue - UNSW Engineering

J. Xue✬

A Non-Circular Attribute Grammar Evaluator

while ( attributes remain to be evaluated ) {visitNode(S) // S is the start symbol

}void visitNode (AST N) { // i.e., ProcessNode(AST N)

if ( N is a nonterminal ) { // N -> X1 X2 ... Xmfor (i = 1; i <= m; i++) {

if ( Xi is nonterminal ) {Evaluate all possible inherited attributes of XivisitNode(Xi)

}}

}Evaluate all possible synthesised attributes of N

}• Pre-order visits: propagate inherited attributes downwards

• Post-order visits: propagate synthesised attributes upwards

• At least one attribute will be evaluated in one pass. The worst-case time complexity

is O(n2), where n is #nodes (assuming that the number of attributes is O(n).)

COMP3131/9102 Page 378 April 16, 2018

Page 27: Jingling Xue - UNSW Engineering

J. Xue✬

A Trace of visitNode on Example 1

• Pass 1: the computation of 〈isFloat〉

• Pass 2: the computation of 〈type〉 and 〈val〉

• Two passes required for evaluating all three attributes

COMP3131/9102 Page 379 April 16, 2018

Page 28: Jingling Xue - UNSW Engineering

J. Xue✬

A Trace of visitNode on Example 1

〈 S.val = 〉

type=

val =

isFloat=

type=

val =

isFloat=

type=

val =

isFloat=

num.val=5

/ 〈

type=

val =

isFloat=

num.val=2

/ 〈

type=

val =

isFloat=

num.num.val=2.0

COMP3131/9102 Page 380 April 16, 2018

Page 29: Jingling Xue - UNSW Engineering

J. Xue✬

Rule-Based Method for Example 1: the Main Method

• Slides 382 – Slide 388: writing a parser

• Slides 389 – Slide 395: writing a rule-based evaluator

using the visitor design pattern

COMP3131/9102 Page 381 April 16, 2018

Page 30: Jingling Xue - UNSW Engineering

J. Xue✬

An Unambiguous Grammar for Parsing

• Left-recursive:

〈S〉 → 〈expr〉

〈expr〉 → 〈expr〉 / 〈factor〉

〈expr〉 → 〈factor〉

〈factor〉 → num

〈factor〉 → num . num

• Non-left-recursive for top-down parsing:

〈S〉 → 〈expr〉

〈expr〉 → 〈factor〉 (/ 〈factor〉)∗

〈factor〉 → num

〈factor〉 → num . num

COMP3131/9102 Page 382 April 16, 2018

Page 31: Jingling Xue - UNSW Engineering

J. Xue✬

AST Classes Used for Building ASTs for Example 1

+ AST

= S

+ Expr

= BinaryExpr

= IntExpr

= FloatExpr

+ Terminal

= IntLiteral

= FloatLiteral

= Operator

These are the same as those in VC.ASTs except S and Expr.

COMP3131/9102 Page 383 April 16, 2018

Page 32: Jingling Xue - UNSW Engineering

J. Xue✬

S.java

package VC.ASTs;

import VC.Scanner.SourcePosition;

public class S extends AST {public Expr E;

public String val;

public S(Expr eAST, SourcePosition position) {super (position);

E = eAST;

}public Object visit(Visitor v, Object o) {

return v.visitS(this, o);

}}

COMP3131/9102 Page 384 April 16, 2018

Page 33: Jingling Xue - UNSW Engineering

J. Xue✬

Expr.java

package VC.ASTs;

import VC.Scanner.SourcePosition;

public abstract class Expr extends AST {// attributes

public boolean isFloat;

public String type;

public String val;

public Expr (SourcePosition Position) {super (Position);

type = null;

}}

COMP3131/9102 Page 385 April 16, 2018

Page 34: Jingling Xue - UNSW Engineering

J. Xue✬

AST-Building Parser (Written as Per Lecture 6)public class Parser {

private Scanner scanner;

private ErrorReporter errorReporter;

private Token currentToken;

public Parser (Scanner lexer, ErrorReporter reporter) {

scanner = lexer;

errorReporter = reporter;

currentToken = scanner.getToken();

}

void accept() {

currentToken = scanner.getToken();

}

void syntacticError(String messageTemplate, String tokenQuoted) {

SourcePosition pos = currentToken.position;

errorReporter.reportError(messageTemplate, tokenQuoted, pos);

}

public S parseS() {

S sAST = null;

SourcePosition dummyPos = new SourcePosition();

try {

Expr eAST = parseExpr();

sAST = new S(eAST, dummyPos);

if (currentToken.kind != Token.EOF)

syntacticError("\"%\" invalid expression", currentToken.spelling);

} catch (SyntaxError e) { return null; }

return sAST;

}

Expr parseExpr() throws SyntaxError {

Expr exprAST = null;

SourcePosition dummyPos = new SourcePosition();

COMP3131/9102 Page 386 April 16, 2018

Page 35: Jingling Xue - UNSW Engineering

J. Xue✬

exprAST = parseFactor();

while (currentToken.kind == Token.DIV) {

Operator opAST = new Operator(currentToken.spelling, dummyPos);

accept();

Expr e2AST = parseFactor();

exprAST = new BinaryExpr(exprAST, opAST, e2AST, dummyPos);

}

return exprAST;

}

Expr parseFactor() throws SyntaxError {

Expr eAST = null;

SourcePosition dummyPos = new SourcePosition();

switch (currentToken.kind) {

case Token.INTLITERAL:

eAST = new IntExpr(new IntLiteral(currentToken.spelling, dummyPos), dummyPos);

accept();

break;

case Token.FLOATLITERAL:

eAST = new FloatExpr(new FloatLiteral(currentToken.spelling, dummyPos), dummyPos);

accept();

break;

default:

syntacticError("\"%\" cannot start Factor", currentToken.spelling);

break;

}

return eAST;

}

}

COMP3131/9102 Page 387 April 16, 2018

Page 36: Jingling Xue - UNSW Engineering

J. Xue✬

The AST for 5/2/2.0

COMP3131/9102 Page 388 April 16, 2018

Page 37: Jingling Xue - UNSW Engineering

J. Xue✬

Visitor.java/*

* Visitor.java

*/

package VC.ASTs;

public interface Visitor {

public abstract Object visitS(S ast, Object o);

public abstract Object visitBinaryExpr(BinaryExpr ast, Object o);

public abstract Object visitIntExpr(IntExpr ast, Object o);

public abstract Object visitFloatExpr(FloatExpr ast, Object o);

public abstract Object visitIntLiteral(IntLiteral ast, Object o);

public abstract Object visitFloatLiteral(FloatLiteral ast, Object o);

public abstract Object visitOperator(Operator ast, Object o);

}

• o: pass some inherited attributes top-down

• returned object: pass synthesised attributes bottom-up

COMP3131/9102 Page 389 April 16, 2018

Page 38: Jingling Xue - UNSW Engineering

J. Xue✬

The Visitor Design Patternpublic class BinaryExpr extends Expr { // for defining BinaryExpr nodes

...

public Object visit(Visitor v, Object o) {return v.visitBinaryExpr(this, o); // this: the node

}}public class IntExpr extends Expr { // for defining IntExpr nodes

...

public Object visit(Visitor v, Object o) {return v.visitIntExpr(this, o); // this: the node

}}public xyzVisitor implements Visitor {Object visitBinaryExpr(BinaryExpr ast, Object o) {

ast.E1.visit(this, o) // this: the visitor

ast.E2.visit(this, o)

// do some thing on this BinaryExpr node "ast"

return something

}...

}

COMP3131/9102 Page 390 April 16, 2018

Page 39: Jingling Xue - UNSW Engineering

J. Xue✬

The Visitor Design Pattern

• The visitor contains operations that operate on data defined by other

classes (e.g., the nodes in the AST)

• Can design different visitors that do different things on the same data

• Simple to implement

• Useful for writing an interpreter, type checker, code generator, ...

• Less useful at development stage since one needs to add a new

abstract class to the visitor interface every time when one adds new

classes (say, for new AST nodes) which must be visited

• http://en.wikipedia.org/wiki/Visitor_pattern

http://java.dzone.com/articles/design-patterns-visitor

http://sourcemaking.com/design_patterns/visitor/java/1

COMP3131/9102 Page 391 April 16, 2018

Page 40: Jingling Xue - UNSW Engineering

J. Xue✬

Rule-Based Method for Example 1

...

theAST = parser.parseS();

visitor1 = new FloatVisitor();

visitor1.evalFloat(theAST, null);

visitor2 = new TypeValVisitor();

visitor2.evalTypeVal(theAST, null);

System.out.println("The value is: " + theAST.val);

...

COMP3131/9102 Page 392 April 16, 2018

Page 41: Jingling Xue - UNSW Engineering

J. Xue✬

Pass 1: Computing isFloat (Post-Order Traversal)

// FloatVisitor.java -- o and returned results not used

import VC.ASTs.*;

public class FloatVisitor implements Visitor {

public void evalFloat(S ast, Object o) {

ast.visit(this, o);

}

public Object visitS(S ast, Object o) {

ast.E.visit(this, o);

return null;

}

public Object visitBinaryExpr(BinaryExpr ast, Object o) {

ast.E1.visit(this, o);

ast.E2.visit(this, o);

ast.isFloat = ast.E1.isFloat || ast.E2.isFloat;

return null;

}

public Object visitIntExpr(IntExpr ast, Object o) {

ast.isFloat = false;

return null;

}

public Object visitFloatExpr(FloatExpr ast, Object o) {

ast.isFloat = true;

return null;

}

// not called

COMP3131/9102 Page 393 April 16, 2018

Page 42: Jingling Xue - UNSW Engineering

J. Xue✬

public Object visitIntLiteral(IntLiteral ast, Object o) {

return null;

}

// not called

public Object visitFloatLiteral(FloatLiteral ast, Object o) {

return null;

}

// not called

public Object visitOperator(Operator ast, Object o) {

return null;

}

}

By using the visitor pattern, each visit method at a node knows which

particular visitor method to call. For example, IntExpr’s visit method

knows that this is an IntExpr object and calls v.visitIntExpr, passing this

and o as arguments.

COMP3131/9102 Page 394 April 16, 2018

Page 43: Jingling Xue - UNSW Engineering

J. Xue✬

Pass 2: Computing type (Pre-order) and val (Post-Order) –

Combined// TypeValVisitor.java -- o and returned result not used.import VC.ASTs.*;public class TypeValVisitor implements Visitor {

public void evalTypeVal(S ast, Object o) {ast.visit(this, o);

}public Object visitS(S ast, Object o) {

if (ast.E.isFloat)ast.E.type = "float";

elseast.E.type = "int";

ast.E.visit(this, o);ast.val = ast.E.val;return null;

}public Object visitBinaryExpr(BinaryExpr ast, Object o) {

ast.E1.type = ast.type;ast.E2.type = ast.type;ast.E1.visit(this, o);ast.E2.visit(this, o);// "/" in Java overloaded for integer and floating-point divisionsif (ast.type.equals("float"))

ast.val = String.valueOf(Float.parseFloat(ast.E1.val) /Float.parseFloat(ast.E2.val));

elseast.val = String.valueOf(Integer.parseInt(ast.E1.val) /

Integer.parseInt(ast.E2.val));return null;

}public Object visitIntExpr(IntExpr ast, Object o) {

COMP3131/9102 Page 395 April 16, 2018

Page 44: Jingling Xue - UNSW Engineering

J. Xue✬

String num = (String) ast.IL.visit(this, o);if (ast.type.equals("float"))

ast.val = String.valueOf((float) Integer.parseInt(num));else

ast.val = num;return null;

}public Object visitFloatExpr(FloatExpr ast, Object o) {

ast.val = (String) ast.FL.visit(this, o);return null;

}public Object visitIntLiteral(IntLiteral ast, Object o) {

return ast.spelling;}public Object visitFloatLiteral(FloatLiteral ast, Object o) {

return ast.spelling;}// not calledpublic Object visitOperator(Operator ast, Object o) { return null; }

}

COMP3131/9102 Page 396 April 16, 2018

Page 45: Jingling Xue - UNSW Engineering

J. Xue✬

L-Attributed Grammars

• Motivation: parsing and semantic analysis in one pass in

top-down parsers (recursive descent and LL parsers)

• Definition: An attribute grammar is L-attributed if each

inherited attribute of Xi, 1 6 i 6 n, on the right-hand side

of X0→X1X2 · · ·Xm, depends only on:

• the attributes of the symbols X1, X2, · · · , Xi−1 to the

left of Xi in the production, and

• the inherited attributes of X0

• The L: the information flowing from left to right

• Example 1 grammar is not L-attributed (because in

〈S →expr〉, the inherited attribute 〈expr.type〉 depends on

the synthesised attribute 〈expr.isFloat〉)

COMP3131/9102 Page 397 April 16, 2018

Page 46: Jingling Xue - UNSW Engineering

J. Xue✬

Evaluation of L-attributed Grammars

void dfvisit (AST N) {

for ( each child M of N from left to right ) {

evaluate inherited attributes of M;

dfvisit(m);

}

evaluate synthesised attributes of N

}

• All attributes can be evaluated in one pass

• Parsing and semantic analysis can be done together (say,

in a recursive descent parser) without using a tree

COMP3131/9102 Page 398 April 16, 2018

Page 47: Jingling Xue - UNSW Engineering

J. Xue✬

Example 2: L-Attributed Grammar

• The grammar (EBNF):

D → T id(, id)∗

T → int

T → float

• The grammar (BNF):

D → TLT → int

T → float

L → id, LL → id

• Give an attribute grammar for constructing the AST.

COMP3131/9102 Page 399 April 16, 2018

Page 48: Jingling Xue - UNSW Engineering

J. Xue✬

Parse Tree for int i, j, k using the BNF Grammar

〈D〉

〈T 〉

int

〈L〉

id

i

, 〈L〉

id

j

, 〈L〉

id

k

COMP3131/9102 Page 400 April 16, 2018

Page 49: Jingling Xue - UNSW Engineering

J. Xue✬

An Attribute Grammar for Example 2

Production Semantic Rules

D → TL L.〈in〉 = T.〈type〉

D.〈ast〉 = L.〈ast〉

T → int T.〈type = int〉

T → float T.〈type = float〉

L → id, L1 L1.〈in〉 = L.〈in〉

L.ast = new DeclList( new VarDecl(L.in, ”id”), L1.ast)

L → id L.ast = new DeclList( new VarDecl(L.in, ”id”), null)

• type: synthesised attribute

• ast: synthesised attribute

• in: inherited attribute

Relevant to Assignment 3

COMP3131/9102 Page 401 April 16, 2018

Page 50: Jingling Xue - UNSW Engineering

J. Xue✬

Decorated Parse Tree

〈D.in = int〉

D.ast = int i → int j → int k

〈T.type = int〉

int

〈L.in = int〉

L.ast = int i → int j → int k

idi

,〈L.in = int〉

L.ast = int j → int k

idj

,〈L.in = int〉

L.ast = int k

idk

COMP3131/9102 Page 402 April 16, 2018

Page 51: Jingling Xue - UNSW Engineering

J. Xue✬

S-Attributed Grammars

• Motivation: parsing and semantic analysis in one pass in

bottom-up parsers

• Definition: An attribute grammar is S-attributed if it uses

synthesised attributes only

• The information always flow up in the tree

• Every S-attributed grammar is L-attributed

• Examples 1 and 2 are not S-attributed

COMP3131/9102 Page 403 April 16, 2018

Page 52: Jingling Xue - UNSW Engineering

J. Xue✬

Example 3: S-Attributed Grammar (Slide 341)

PRODUCTION SEMANTIC RULE

E → T [E.t = T.t]| E1”+” T [E.t = E1.t ‖ T.t ‖ ”+”]| E1 ”-” T [E.t = E1.t ‖ T.t ‖ ”-”]

T → F [T.t = F.t]| T1” ∗ ”F [T.t = T1.t ‖ F.t ‖ ”*”]| T1”/”F [T.t = T1.t ‖ F.t ‖ ”/”]

F → INT [F.t = int.string-value]F → ”(” E ”)” [F.t = E.t]

• Defines the translation of infix to postfix expressions

• A single string-valued synthesised attribute t

• ‖: string concatenation

COMP3131/9102 Page 404 April 16, 2018

Page 53: Jingling Xue - UNSW Engineering

J. Xue✬

Example 3: Understanding Example 3

E

E

T

F

INT

1

+ T

T

F

INT

2

* F

INT

3

E.t=123*+

E.t=1

T.t=1

F.t=1

INT

1

+ T.t=23*

T.t=2

F.t=2

INT

2

* F.t=3

INT

3

Parse Tree Decorated Parse Tree

• The value of the synthesised attribute t is propagated

upwards the tree

COMP3131/9102 Page 405 April 16, 2018

Page 54: Jingling Xue - UNSW Engineering

J. Xue✬

What You Should Know About Attribute Grammars?

• Write an attribute grammar for simple CFGs

• Apply Slide 378 to evaluate an attribute grammar

• Draw decorated parse or decorated syntax trees

• Evaluate the attributes

COMP3131/9102 Page 406 April 16, 2018

Page 55: Jingling Xue - UNSW Engineering

J. Xue✬

Reading

• Attribute grammars: Sections 2.3 and 5.1 – 5.4 (either

version)

• Understand the visitor design pattern:

• Read Slide 271

• Read TreeDrawer, TreePrinter and UnParser

Next Class: Static Semantics (Assignment 4)

COMP3131/9102 Page 407 April 16, 2018

Page 56: Jingling Xue - UNSW Engineering

J. Xue✬

Different Types of S’s Child

COMP3131/9102 Page 408 April 16, 2018

Page 57: Jingling Xue - UNSW Engineering

J. Xue✬

Different Types of the Left Child of a BinExpr Node

COMP3131/9102 Page 409 April 16, 2018