Top-Down Parsing/Example 1: Difference between revisions

From Wiki**3

Root (talk | contribs)
Root (talk | contribs)
No edit summary
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Problem ==
== Problem ==


Consider the following grammar:
Consider the following grammar with the following set of terminal symbols '''<tt>{+,-,*,/,(,),id}</tt>''':


   E -> E + T | E - T | T
   E -> E + T | E - T | T
Line 10: Line 10:
# Compute the FIRST and FOLLOW sets for the non-terminal symbols.
# Compute the FIRST and FOLLOW sets for the non-terminal symbols.
# Build the parse table for the predictive parser.
# Build the parse table for the predictive parser.
# Process the input phrase '''a*(b+c)''' detailing the contents of the stack, the input and each action performed by the parser.
# Process the input phrase '''<tt>a*(b+c)</tt>''' detailing the contents of the stack, the input and each action performed by the parser.


== Solution ==
== Solution ==
Line 21: Line 21:


   E  -> T E'
   E  -> T E'
   E' -> + T E' | - T E' | ε
   E' -> + T E' | - T E' | ε
   T  -> F T'
   T  -> F T'
   T' -> * F T' | / F T' | ε
   T' -> * F T' | / F T' | ε
   F  -> ( E ) | id
   F  -> ( E ) | id


The new grammar still has left corners, but a cursory inspection shows that they are not problematic (we will leave them as they are for simplicity). Eliminating these left corners would mean replacing the definitions of F in T and of T in E.
The new grammar still has left corners, but a cursory inspection shows that they are not problematic. Nevertheless, they should be eliminated:


   FIRST(E)  = FIRST(T E') = FIRST(T) = {(, id}
  E  -> ( E ) T' E' | id T' E'
   FIRST(E') = FIRST(+ T E') ∪ FIRST(- T E') ∪ {ε} = {+, -, ε}
  E' -> + T E' | - T E' | ε
   FIRST(T)  = FIRST(F T') = FIRST(F) = {(, id}
  T  -> ( E ) T' | id T'
   FIRST(T') = FIRST(* F T') ∪ FIRST(/ F T') ∪ {ε} = {*, /, ε}
  T' -> * F T' | / F T' | ε
   FIRST(F)  = FIRST(( E )) ∪ FIRST(id) = {(, id}
  F  -> ( E ) | id
 
   FIRST(E)  = FIRST(( E ) T' E') FIRST(id T' E') = {(, id}
   FIRST(E') = FIRST(+ T E') FIRST(- T E') {ε} = {+, -, ε}
   FIRST(T)  = FIRST(( E ) T') FIRST(id T') = {(, id}
   FIRST(T') = FIRST(* F T') FIRST(/ F T') {ε} = {*, /, ε}
   FIRST(F)  = FIRST(( E )) FIRST(id) = {(, id}


   FOLLOW(E)  = {$} ∪ {)} = {), $}
   FOLLOW(E)  = {$} {)} = {), $}
   FOLLOW(E') = FOLLOW(E) = {), $}
   FOLLOW(E') = FOLLOW(E) = {), $}
   FOLLOW(T)  = FIRST(E')\{ε} ∪ FOLLOW(E) ∪ FOLLOW(E') = {+, -, ), $}
   FOLLOW(T)  = FIRST(E')\{ε} FOLLOW(E') = {+, -, ), $}
   FOLLOW(T') = FOLLOW(T) = {+, -, ), $}
   FOLLOW(T') = FOLLOW(T) = {+, -, ), $}
   FOLLOW(F)  = FIRST(T')\{ε} ∪ FOLLOW(T) ∪ FOLLOW(T') = {*, /, +, -, ), $}
   FOLLOW(F)  = FIRST(T')\{ε} FOLLOW(T') = {*, /, +, -, ), $}


For building the parse table, we will consider the FIRST and FOLLOW sets above.
For building the parse table, we will consider the FIRST and FOLLOW sets above.
Line 57: Line 63:
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| E  -> T E'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| E  -> id T' E'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| E  -> T E'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| E  -> ( E ) T' E'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|
Line 69: Line 75:
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| E' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| E' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| E' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| E' -> ε
|-
|-
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; background: wheat;" | T
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; background: wheat;" | T
Line 77: Line 83:
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T  -> F T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T  -> id T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T  -> F T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T  -> ( E ) T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|
|-
|-
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; background: wheat;" | T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; background: wheat;" | T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> * F T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> * F T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> / F T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> / F T'
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"|  
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> ε
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; font-weight: normal; align: center; background: #ffffcc;"| T' -> ε
|-
|-
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; background: wheat;" | F
! style="border-style: solid; border-width: 1px; border-color: black; padding-left: 10px; padding-right: 10px; background: wheat;" | F
Line 113: Line 119:
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">E$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">E$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">a*(b+c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">a*(b+c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace"> E -&gt; T E'</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace"> E -&gt; id T' E'</font></td>
    </tr>
    <tr>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">TE'$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">a*(b+c)$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace"> T -&gt; F T'</font></td>
    </tr>
    <tr>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">FT'E'$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">a*(b+c)$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace"> F -&gt; id</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">idT'E'$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">idT'E'$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">a*(b+c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">a*(b+c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">-&gt; id ≡ a</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">-&gt; id a</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
Line 173: Line 169:
  face="Courier New, Courier, monospace">b+c)$</font></td>
  face="Courier New, Courier, monospace">b+c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
  face="Courier New, Courier, monospace"> E -&gt; T E'</font></td>
  face="Courier New, Courier, monospace"> E -&gt; id T' E'</font></td>
    </tr>
    <tr>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font
face="Courier New, Courier, monospace">TE'</font><font
face="Courier New, Courier, monospace">)T'E'$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font
face="Courier New, Courier, monospace">b+c)$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
face="Courier New, Courier, monospace"> T -&gt; F T'</font></td>
    </tr>
    <tr>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">FT'E')T'E'$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">b+c)$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace"> F -&gt; id</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">idT'E')T'E'$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">idT'E')T'E'$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">b+c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">b+c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">-&gt; id ≡ b</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font face="Courier New, Courier, monospace">-&gt; id b</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
Line 202: Line 184:
  face="Courier New, Courier, monospace">+c)$</font></td>
  face="Courier New, Courier, monospace">+c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
  face="Courier New, Courier, monospace"> T' -&gt; ε</font></td>
  face="Courier New, Courier, monospace"> T' -&gt; ε</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
Line 230: Line 212:
  face="Courier New, Courier, monospace">c)$</font></td>
  face="Courier New, Courier, monospace">c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
  face="Courier New, Courier, monospace"> T -&gt; F T'</font></td>
  face="Courier New, Courier, monospace"> T -&gt; id T'</font></td>
    </tr>
    <tr>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font
face="Courier New, Courier, monospace">FT'</font><font
face="Courier New, Courier, monospace">E'</font><font
face="Courier New, Courier, monospace">)T'E'$</font></td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="right" bgcolor="#ffffcc" valign="top"><font
face="Courier New, Courier, monospace">c)$</font>
      </td>
      <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
face="Courier New, Courier, monospace"> F -&gt; id</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
Line 251: Line 222:
  face="Courier New, Courier, monospace">c)$</font></td>
  face="Courier New, Courier, monospace">c)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
  face="Courier New, Courier, monospace">-&gt; id ≡ c<br>
  face="Courier New, Courier, monospace">-&gt; id c<br>
       </font></td>
       </font></td>
     </tr>
     </tr>
Line 262: Line 233:
  face="Courier New, Courier, monospace">)$</font></td>
  face="Courier New, Courier, monospace">)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
  face="Courier New, Courier, monospace"> T' -&gt; ε</font></td>
  face="Courier New, Courier, monospace"> T' -&gt; ε</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
Line 271: Line 242:
  face="Courier New, Courier, monospace">)$</font></td>
  face="Courier New, Courier, monospace">)$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
  face="Courier New, Courier, monospace"> E' -&gt; ε</font></td>
  face="Courier New, Courier, monospace"> E' -&gt; ε</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
Line 287: Line 258:
  face="Courier New, Courier, monospace">$</font></td>
  face="Courier New, Courier, monospace">$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
  face="Courier New, Courier, monospace"> T' -&gt; ε</font></td>
  face="Courier New, Courier, monospace"> T' -&gt; ε</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
Line 295: Line 266:
  face="Courier New, Courier, monospace">$</font></td>
  face="Courier New, Courier, monospace">$</font></td>
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
       <td style="border-style: solid; border-width: 1px; border-color: black;" align="center" bgcolor="#ffffcc" valign="top"><font
  face="Courier New, Courier, monospace"> E' -&gt; ε</font></td>
  face="Courier New, Courier, monospace"> E' -&gt; ε</font></td>
     </tr>
     </tr>
     <tr>
     <tr>
Line 308: Line 279:
</table>
</table>


 
[[category:Compiladores]]
[[category:Compilers]]
[[category:Ensino]]
[[category:Teaching]]

Latest revision as of 14:40, 6 April 2015

Problem

Consider the following grammar with the following set of terminal symbols {+,-,*,/,(,),id}:

 E -> E + T | E - T | T
 T -> T * F | T / F | F
 F -> ( E ) | id
  1. Rewrite the grammar so that it can be analyzed by an LL(1) predictive parser.
  2. Compute the FIRST and FOLLOW sets for the non-terminal symbols.
  3. Build the parse table for the predictive parser.
  4. Process the input phrase a*(b+c) detailing the contents of the stack, the input and each action performed by the parser.

Solution

The grammar can be parsed by an LL(1) parser if it does not have left recursion and no ambiguity is present (i.e., the LOOKAHEADs for all productions of each non-terminal are disjoint).

A simple inspection of the grammar shows that left recursion is present in both E and T rules. Also, there are left corners that may hide ambiguity.

The first step, then, is to rewrite the grammar so that left recursion is eliminated:

 E  -> T E'
 E' -> + T E' | - T E' | ε
 T  -> F T'
 T' -> * F T' | / F T' | ε
 F  -> ( E ) | id

The new grammar still has left corners, but a cursory inspection shows that they are not problematic. Nevertheless, they should be eliminated:

 E  -> ( E ) T' E' | id T' E'
 E' -> + T E' | - T E' | ε
 T  -> ( E ) T' | id T'
 T' -> * F T' | / F T' | ε
 F  -> ( E ) | id
 FIRST(E)  = FIRST(( E ) T' E') ∪ FIRST(id T' E') = {(, id}
 FIRST(E') = FIRST(+ T E') ∪ FIRST(- T E') ∪ {ε} = {+, -, ε}
 FIRST(T)  = FIRST(( E ) T') ∪ FIRST(id T') = {(, id}
 FIRST(T') = FIRST(* F T') ∪ FIRST(/ F T') ∪ {ε} = {*, /, ε}
 FIRST(F)  = FIRST(( E )) ∪ FIRST(id) = {(, id}
 FOLLOW(E)  = {$} ∪ {)} = {), $}
 FOLLOW(E') = FOLLOW(E) = {), $}
 FOLLOW(T)  = FIRST(E')\{ε} ∪ FOLLOW(E') = {+, -, ), $}
 FOLLOW(T') = FOLLOW(T) = {+, -, ), $}
 FOLLOW(F)  = FIRST(T')\{ε} ∪ FOLLOW(T') = {*, /, +, -, ), $}

For building the parse table, we will consider the FIRST and FOLLOW sets above.

+ - * / id ( ) $
E E -> id T' E' E -> ( E ) T' E'
E' E' -> + T E' E' -> - T E' E' -> ε E' -> ε
T T -> id T' T -> ( E ) T'
T' T' -> ε T' -> ε T' -> * F T' T' -> / F T' T' -> ε T' -> ε
F F -> id F -> ( E )

The following table show the parsing of the a*(b+c) input sequence.

STACK INPUT ACTION
E$ a*(b+c)$ E -> id T' E'
idT'E'$ a*(b+c)$ -> id ≡ a
T'E'$
*(b+c)$ T' -> * F T'
*FT'E'$
*(b+c)$ -> *
FT'E'$ (b+c)$ F -> ( E )
(E)T'E'$
(b+c)$ -> (
E)T'E'$ b+c)$ E -> id T' E'
idT'E')T'E'$ b+c)$ -> id ≡ b
T'E')T'E'$ +c)$ T' -> ε
E')T'E'$ +c)$ E' -> + T E'
+TE')T'E'$ +c)$ -> +
TE')T'E'$ c)$ T -> id T'
idT'E')T'E'$ c)$ -> id ≡ c
T'E')T'E'$ )$ T' -> ε
E')T'E'$ )$ E' -> ε
)T'E'$ )$ -> )
T'E'$ $ T' -> ε
E'$ $ E' -> ε
$ $ ACCEPT