You are on page 1of 9

Decaf Reference Grammar Draft Revised 2/07/08 Notation: Non-terminal symbols are in < > brackets.

. Terminal symbols are either in bold font or are enclosed in marks. (These are lexical token types or a combination of token type and value.) Square brackets [ ] denote 0 or 1 occurrences of the contents of the brackets. Braces { } are used to group things. * after something means 0 or more occurrences +, after something means 1 or more occurrences with , in-between for 2 or more. Original Grammar: <program> class <class-name> { <field-decl> * <method-decl> * }

<class-name> id <field-decl> <type> { id | { id [ intConstant ] }} +, ; | <type> id = <constant> ;

<method-decl> { <type> | void } id ( [ {<type> id }+, ] ) <block> <block> <var-decl> <type> <statement> { <var-decl> * <statement> * } <type> { id } +, ; int | bool | | | | | | | | <assign> ; <method-call> ; if ( <expr> ) <block> while ( <expr> ) <block> for ( { <assign> } +, ; <expr> ; { <assign> } +, ) <block> return [ <expr> ] ; break ; continue ; <block>

<assign>

<lvalue> = <expr>

<method-call> <method-name> ( [ { <expr> } +, ] ) | callout ( stringConstant [ { <callout-arg> } +, } ] ) <method-name> id

<callout-arg> <expr> | stringConstant <lvalue> <expr> id | id [ <expr> ] | | | | | <lvalue> <method-call> <constant> <expr> <bin-op> <expr> <unary-op> <expr> ( <expr> )

<unary-op> <bin-op> <arith-op> <rel-op> <eq-op> <cond-op> <constant>

- | ! <arith-op> | <rel-op> | <eq-op> | <cond-op> + | - | * | / | % < | > | <= | >= == | != && | || intConstant | charConstant | <bool-constant>

<bool-constant> true | false

Grammar with no Left Recursion: This grammar should be an equivalent grammar with left-recursion removed from the <expr> rules. <program> class <class-name> { <field-decl> * <method-decl> * }

<class-name> id <field-decl> <type> { id | { id [ intConstant ] }} +, ; | <type> id = <constant> ;

<method-decl> { <type> | void } id ( [ {<type> id }+, ] ) <block> <block> <var-decl> <type> <statement> { <var-decl> * <statement> * } <type> { id } +, ; int | bool | | | | | | | | <assign> ; <method-call> ; if ( <expr> ) <block> while ( <expr> ) <block> for ( { <assign> } +, ; <expr> ; { <assign> } +, ) <block> return [ <expr> ] ; break ; continue ; <block>

<assign>

<lvalue> = <expr>

<method-call> <method-name> ( [ { <expr> } +, ] ) | callout ( stringConstant [ { <callout-arg> } +, } ] ) <method-name> id <callout-arg> <expr> | stringConstant <lvalue> <expr> id | id [ <expr> ] | | | <lvalue> <expr-cont> <method-call> <expr-cont> <constant> <expr-cont> <unary-op> <expr> <expr-cont>

| ( <expr> ) <expr-cont> <expr-cont> <unary-op> <bin-op> <arith-op> <rel-op> <eq-op> <cond-op> <constant> | <bin-op> <expr> <expr-cont> - | ! <arith-op> | <rel-op> | <eq-op> | <cond-op> + | - | * | / | % < | > | <= | >= == | != && | || intConstant | charConstant | <bool-constant>

<bool-constant> true | false

Restricted Grammar for Top-Down Parsing: Based on a preliminary calculation of First and Follow sets, this grammar has been modified through the left-factoring technique to make sure that the grammar obeys the following restrictions: 1. If <phrase2> is an expression on the rhs of a rule that can be empty (occur 0 times), the First (<phrase2>) must be disjoint with Follow ( <phrase2>). 2. If there is a non-terminal with n rhs: <phrase1> E1 | E2 | E3 | . . . | En, then First(E1), First(E2), First(En) must all be disjoint. Before left factoring, some non-terminals need translation to a stricter context free notation to make the first set structure more obvious, and thus to reveal the places where left-factoring should occur. <declarations> <field-decl>* <method-decl>* Should be equivalent to: <declarations> | <onefielddecl> <declarations> | <onemethoddecl> <method-declarations> <method-declarations> | <onemethoddecl> <method-declarations> Now we elaborate the choices for one field declaration and one method declaration in order to expose the left factoring required: <declarations> | <type> id = <constant> ; <declarations> | <type> id ; <declarations> | <type> id , <id-array-list> ; <declarations> | <type> id [ intConstant ] ; <declarations> | <type> id [ intConstant ] , <id-array-list> ; <declarations> | <type> id ( [ { <type> id }+, ] ) <block> <method-declarations> | void id ( [ { <type> id }+, ] ) <block> <method-declarations> <id-array-list> id | id [ intConstant ] | id , <id-array-list> | id [ intConstant ] , <id-array-list> <method-declarations> | <type> id ( [ { <type> id }+, ] ) <block> <method-declarations> | void id ( [ { <type> id }+, ] ) <block> <method-declarations>

After left factoring, <program> class <class-name> { <declarations> }

<class-name> id <declarations> | <type> id <declarations-cont1> | void id ( [ { <type> id }+, ] ) <block> <method-declarations> <declarations-cont1> = <constant> ; <declarations> | ; <declarations> | , <id-array-list> ; <declarations> | [ intConstant ] <declarations-cont2> | ( [ { <type> id }+, ] ) <block> <method-declarations> <declarations-cont2> ; <declarations> | , <id-array-list> ; <declarations> <id-array-list> id <id-array-list-cont1> <id-array-list-cont1> [ intConstant ] <id-array-list-cont2> | , <id-array-list> <id-array-list-cont2> | , <id-array-list> <method-declarations> | <type> id ( [ { <type> id }+, ] ) <block> <method-declarations> | void id ( [ { <type> id }+, ] ) <block> <method-declarations> <block> <var-decl> <type> <statement> { <var-decl> * <statement> * } <type> { id } +, ; int | bool id <statement-cont> | callout ( stringConstant [ { <callout-arg> } +, } ] ) | if ( <expr> ) <block> | while ( <expr> ) <block> | for ( { <assign> } +, ; <expr> ; { <assign> } +, ) <block> | return [ <expr> ] ; | break ; | continue ;

| <block> <statement-cont> = <expr> ; | <array-index-part> = <expr> ; | <method-param-part> ; <assign> <lvalue> = <expr> <lvalue> id <lvalue-cont> <lvalue-cont> | [ <expr> ] <method-call> <method-name> ( [ { <expr> } +, ] ) | callout ( stringConstant [ { <callout-arg> } +, } ] ) <method-param-part> ( [ { <expr> } +, ] ) <method-name> id <callout-arg> <expr> | stringConstant <array-index-part> [ <expr> ] <expr> | | | id <lval-or-method-cont> <constant> <expr-cont> <unary-op> <expr> <expr-cont> ( <expr> ) <expr-cont> // assign // assign // method call

<expr-cont>

| <bin-op> <expr> <expr-cont>

<lval-or-method-cont> <array-index-part> | <method-param-part> | <unary-op> <bin-op> <arith-op> <rel-op> <eq-op> <cond-op> <constant> - | ! <arith-op> | <rel-op> | <eq-op> | <cond-op> + | - | * | / | % < | > | <= | >= == | != && | || intConstant | charConstant | <bool-constant>

<bool-constant> true | false

First and Follow Sets (for non-terminals, instead of right-hand-sides) First(<program>) = { class } First(<class-name} = { id } First(<declarations> ) = { int , bool , void, }} First(<declarations-cont1>) = { ;, ,, [,=, ( } First(<declarations-cont2>) = { ;, , } First(<id-array-list>) = { id } First(<id-array-list-cont1>) = { [, ,} First(<id-array-list-cont2>) = { ,} First(<method-declarations>) = { int , bool, void } First(<block>) = { {} First(<var-decl>) ={ int , bool } First(<type>) ={ int , bool } First(<statement>) = {id , callout , if, while, for, return, break, continue, {} First(<statement-cont>) = { =, [, ( }First(<assign>) = {id} First(<method-call>) = { id, callout } First(<method-param-part> ) = { (} First(<method-name>) = { id } First(<callout-arg>) = First(<expr> ) + stringConstant First(<array-index-part>) { [ } First(<expr>) = { id, ( } + First(constant) + First(unary-op) First(<expr-cont>) = First(binop) + Follow(expr) First(<lval-or-method-cont>) = { [, ( } + Follow(expr) First(<unary-op>) = {- , !} First(<bin-op>) = { + , - , * , / , %, < , >, <= , >=, < , >, <= , >=, == , !=, && , || } First(<arith-op>) = { + , - , * , / , %} First(<rel-op>) = {< , >, <= , >=} First(<eq-op>)= {== , !=} First(<cond-op>) = { && , ||} First (<constant>) = { intConstant , charConstant , true , false } First(<bool-constant>) = {true , false } Follow(<declarations>) = {}} Follow(<id-array-list-cont2>) = { ; } Follow(<method-declarations>) = {}} Follow(<var-decl> ) = First(<var-decl>) + First( <statement>) Follow(<statement>) = First(<statement>) + } Follow(<expr>) = { ), First(<binop>), ], ;

You might also like