Support Grammar
Support Grammar
Page 1
Page 2
= FIRST(<primitiveDatatype> ) FIRST(<constructedDatatype>)
= {TK_INT, TK_REAL, TK_RECORD}
8. <dataType>===> <primitiveDatatype> |<constructedDatatype>
FIRST(<primitiveDatatype> ) FIRST(<constructedDatatype>)
= {TK_INT, TK_REAL} { TK_RECORD}
=
Since there is no nullable production for <dataType>, there is no need for computing FOLLOW(<dataType>).
9. <primitiveDatatype>===> TK_INT | TK_REAL
FIRST(TK_INT) FIRST(TK_REAL) = {TK_INT} {TK_REAL} =
Hence the rules for <primitiveDataType> are LL(1) compatible.
FIRST(<primitiveDatatype>) = {TK_INT, TK_REAL}
10. <constructedDatatype>===>TK_RECORD TK_RECORDID
FIRST(<constructedDatatype>) = {TK_RECORD}
11. <remaining_list>===>TK_COMMA <parameter_list> | eps
There exist a nullable production for the non-terminal <remaining_list>. The RHS (right hand side) of the other production is such that the null
string eps (epsilon) is not derivable from it.
Also
FIRST(TK_COMMA <parameter_list>) FOLLOW(<remaining_list>) should be empty.
FIRST(TK_COMMA <parameter_list>) = {TK_COMMA}
and
FOLLOW(<remaining_list>) = FOLLOW(parameter_list)
.....from (7)
= {TK_SQR}
Hence,
Page 3
Page 4
.....using 15 & 14
FIRST(<fieldDefinition><moreFields>) FOLLOW(<moreFields>)
= {TK_TYPE} {TK_ENDRECORD}
=
Hence, the above two rules for the non terminal <moreFields> are LL(1) compatible.
Page 5
.........using 24
Page 7
Page 8
The two rules (29) and (30) for the nonterminal <conditionalStmt> need modifications as they originally form ambigous grammar. We need to
perform the left factoring as follows
<conditionalStmt>===> TK_IF TK_OP <booleanExpression> TK_CL TK_THEN <stmt><otherStmts> <elsePart>
.....number rule as 29
<elsePart>===>TK_ELSE <stmt><otherStmts> TK_ENDIF | TK_ENDIF
.....number rules as 30
Notice that I also added TK_OP and TK_CL in new rule 29 to enclose boolean expression . These two tokens were missing earlier.
Also I am putting a constraint of atleast one statement within else part.
Now there is a single rule for <conditionalStmt> which is non nullable and its first set is {TK_IF}
But the newly introduced nonterminal <elsePart> has two non nullable productions and their corrsponding FIRST sets are disjoint.
FIRST(TK_ELSE <otherStmts> TK_ENDIF) FIRST(TK_ENDIF) = {TK_ELSE} {TK_ENDIF} =
Therefore the new set of rules for <elsePart> is also LL(1) compatible.
And,
FIRST(<conditionalStmt>) = {TK_IF}
FIRST(<elsePart>) = {TK_ELSE, TK_ENDIF}
31. <ioStmt>===>TK_READ TK_OP <allVar> TK_CL TK_SEM | TK_WRITE TK_OP <allVar> TK_CL TK_SEM
This rule needs a minor modification. The identifier and record identifier are the only arguments of the read operation.
<ioStmt>===> TK_READ TK_OP <singleOrRecId> TK_CL TK_SEM
Also the write statement is not expected to take as argument a record id. Any number, real number, identifier or constructed record identifier can be
the arguments of write statement.
<ioStmt> ===> TK_WRITE TK_OP <allVar> TK_CL TK_SEM
Both the above productions are non nullable.
and,
Vandana, CSIS, BITS PILANI
Page 9
FIRST(TK_READ TK_OP <singleOrRecId > TK_CL TK_SEM ) FIRST(TK_WRITE TK_OP <allVar> TK_CL TK_SEM)
= {TK_READ} {TK_WRITE} =
Therefore, the above productions are LL(1) compatible.
and,
FIRST(<ioStmt>) = {TK_READ, TK_WRITE}
Notice that the arguments for a write may be a number, real number, id, or a constructed record id variable. A record identifier is not the argument of
WRITE directly. This is relaxed here to simplify the code generation equivalent of printing all field values of the record type variable.
32. <allVar>===><var>| TK_RECORDID TK_DOT TK_FIELDID
Trivially, the two non nullable productions above conform to LL(1) and
FIRST(<allVar>) = FIRST(<var>) {TK_RECORDID}
= {TK_NUM, TK_RNUM, TK_ID, TK_RECORDID}
33. <arithmeticExpression>===><arithmeticExpression> <operator> <arithmeticExpression>
I had left a major correction for you to do in the arithmetic expression grammar. You were required to impose precedence of operators and the
operations on record variables.
34. <arithmeticExpression> ====>TK_OP <arithmeticExpression> TK_CL | <var>
A replacement of <var> with a new nonterminal <all> is required to incorporate the record addition and subtraction
<arithmeticExpression> ====>TK_OP <arithmeticExpression> TK_CL | <all>
where <all>===> TK_ID | TK_NUM| TK_RNUM | TK_RECORDID <temp>
and <temp>===> eps | TK_DOT TK_FIELD
An arithmetic expression is expected to take as argument an identifier, statically available number, real number, a record identifier and a record id
(constructed by expanding the name using dot with a field name)
Now we reformulate the rules 33, 34(a) and 35 to impose precedence.
Vandana, CSIS, BITS PILANI
Page 10
.....(A1)
.....(A2)
.....(A3)
.....(A4)
......(A5)
.......(A6)
.......(A7)
[Note : I have given new numbers for referring to the rules, but you can have your own numbering scheme for the rules]
Now let us verify the rules A1-7 for the nonterminals <arithmeticExpression>, <term>, <factor>, <lowPrecedenceOperators>,
<highPrecedenceOperators>, <all> and <temp>
The rule A1 needs left recursion elimination and the new set of productions are obtained by introducing new nonterminal, say <expPrime>
<arithmeticExpression> ===> <term> <expPrime>
<expPrime> ===> <lowPrecedenceOperators> <term> <expPrime> | eps
Similarly rule A2 also needs left recursion elimination. The new set of productions are obtained by introducing new nonterminal, say, <termPrime>
<term>===> <factor> <termPrime>
<termPrime> ===> <highPrecedenceOperators><factor> <termPrime> | eps
Now we have two more nonterminals <expPrime> and <termPrime>. The complete set of non left recursive, unambigous arithmetic expression
grammar then becomes with new numbers A1-A9.
A1)
A2)
A3)
A4)
Page 11
A5)
A6)
A7)
A8)
A9)
<temp>===> eps | TK_DOT TK_FIELDID
Analysis of A1: As there is only single rule available for the nonterminal <arithmeticExpression>, we must see that is not nullable
FIRST(<arithmeticExpression>) = FIRST(<term>) = FIRST(<factor> ) = {TK_ID, TK_NUM, TK_RNUM, TK_RECORDIID, TK_OP}
There is no need to go further to check LL(1) compatibility. The grammar for <arithmeticExpression> is LL(1) compatible.
Analysis of A2: One of the productions for the nonterminal <expPrime> is nullable.
Let us verify FIRST(<lowPrecedenceOperators> <term> <expPrime>) and FOLLOW(<expPrime>) are disjoint.
FIRST(<lowPrecedenceOperators> <term> <expPrime>)
and,
FOLLOW(<expPrime>)
= FIRST(<lowPrecedenceOperators>)
= {TK_PLUS, TK_MINUS}
= FOLLOW(<arithmeticExpression>)
= {TK_SEM}
......using analysis of A7
.....using A1
.....using 23
Page 12
= FIRST(<factor> )
= {TK_ID, TK_NUM, TK_RNUM, TK_RECORDIID, TK_OP}
There is no need to go further to check LL(1) compatibility. The grammar for <term> is LL(1) compatible.
.......using analysis of A5
Analysis of A4:
One of the productions for the nonterminal <termPrime> is nullable.
Let us verify FIRST(<highPrecedenceOperators><factor> <termPrime>) and FOLLOW(<termPrime>) are disjoint.
FIRST(<highPrecedenceOperators><factor> <termPrime>) = FIRST(<highPrecedenceOperators>)
={ TK_MUL, TK_DIV}
.....using analysis of A6
And,
FOLLOW(<termPrime>)
= FOLLOW(<term>)
= FIRST(<expPrime>) FOLLOW(<expPrime>)
= FIRST(<lowPrecedenceOperators>) FOLLOW(<expPrime>)
= {TK_PLUS, TK_MINUS} FOLLOW(<expPrime>)
= {TK_PLUS, TK_MINUS} FOLLOW(<arithmeticExpression>)
= {TK_PLUS, TK_MINUS} {TK_SEM}
= {TK_PLUS, TK_MINUS, TK_SEM}
Therefore,
FIRST(<highPrecedenceOperators><factor> <termPrime>) FOLLOW(<termPrime>)
=
{ TK_MUL, TK_DIV} {TK_PLUS, TK_MINUS, TK_SEM}
=
.....using A3
.....using A2
.....using A2
.....using analysis of A7
....using A1
....using 23
Page 13
Analysis of A5: There are two productions for the non terminal <factor>.
FIRST( TK_OP <arithmeticExpression> TK_CL) = {TK_OP}
and,
FIRST(<all>) = {TK_ID, TK_NUM, TK_RNUM, TK_RECORDIID}
It is now obvious that no production for <factor> is a nullable production and,
FIRST( TK_OP <arithmeticExpression> TK_CL) FIRST(<all>) =
Therefore the grammar for <factor> is LL(1) compatible.
and,
FIRST(<factor>) = {TK_ID, TK_NUM, TK_RNUM, TK_RECORDIID, TK_OP}
Analysis of A6: The two productions of the nonterminal <highPrecedenceOperators> are trivially LL(1) compatible
FIRST(<highPrecedenceOperators>) = { TK_MUL, TK_DIV}
Analysis of A7: The two productions of the nonterminal <lowPrecedenceOperators> are also trivially LL(1) compatible
FIRST(<lowPrecedenceOperators>) = { TK_PLUS, TK_MINUS}
Analysis of A8: The two productions of the nonterminal <all> are also trivially LL(1) compatible.
FIRST(<all>) = { TK_NUM, TK_RNUM, TK_ID, TK_RECORDID}
Analysis of A9: There is an epsilon production for the nonterminal <temp> and it is essential to check that
FIRST(TK_DOT TK_FIELDID) FOLLOW(<temp> ) is empty.
Now computing FOLLOW(<temp>),
FOLLOW(<temp>)
= FOLLOW(<all>)
= FOLLOW(<factor>)
= FIRST(<termPrime>) FOLLOW(<termPrime>)
= FIRST(<highPrecedenceOperators>) FOLLOW(<termPrime>)
= {TK_MUL, TK_DIV} FOLLOW(<termPrime>)
Vandana, CSIS, BITS PILANI
.....using A8
.....using A5
.....using A4
.....using A4
.....using analysis of A6
Page 14
.....using A3
.....using A2
.....using A2
.....using analysis of A7
....using A1
....using 23
Therefore,
FIRST(TK_DOT TK_FIELDID) FOLLOW(<temp> )
= {TK_DOT} {TK_MUL, TK_DIV, TK_PLUS, TK_MINUS, TK_SEM}
=
This proves that the rules defined in A9 are LL(1) compatible. [I again insist that I am avoiding proving every rule to be unambiguous. This is left to be
proved by you.]
Page 15
Page 16
.......using 44
.......using 43
Vandana
Page 17