CS3723, Exam 1, 18 Feb 2013       Your Name:                                                                                 
Last First

ANSWERS
  Directions: You may write on the exam or use extra paper or both. You should probably use a separate sheet for the answer to 4. You cannot expect the proctor to answer questions about this exam, so you should give the best answer you can that fully answers the question. You are not allowed to use anything except the exam sheets. (No crib sheets, no notes, no calculator, no cell phone. Um, writing instruments are OK.)


  1. (20) Show that the grammar below is ambiguous by finding a sentence that has two different parse trees or two different leftmost derivations. Write down the sentence, the two distinct parse trees, and the two distinct leftmost derivations.

       E  --->  E + E
       E  --->  E * E
       E  --->  ( E )
       E  --->  id
    1st:   E               2nd:   E
          /|\                    /|\ 
         E + E                  E * E
        /   /|\                /|\   \
       id  / * \              E + E  id
          id   id            /     \
                            id     id
    

    1st: E ==> E + E ==> id + E ==> id + E * E ==> id + id * E ==> id + id * id

    2nd: E ==> E * E ==> E + E * E ==> id + E * E ==> id + id * E ==> id + id * id


  2. (15) (a) Translate the following ordinary arithmetic expression into Reverse Polish Notation (RPN): (5+4)*2^3$. [You can use any method and can give the final answer without showing work, but the order of the digits in the answer should be the same as in the original. One method is to work from a small "skeleton" parse tree.]

                   E
                   |
                   T
                   |
          +--------+-----+
          |        |     |
          T        |     |
          |        |     |
          S        |     |
          |        |     |
          F        |     |
          |        |     |
    +-----+-----+  |     |
    |     |     |  |     |
    |     E     |  |     |
    |     |     |  |     |
    |  +--+--+  |  |     |
    |  |  |  |  |  |     |
    |  E  |  |  |  |     S
    |  |  |  |  |  |     |
    |  T  |  T  |  |  +--+--+
    |  |  |  |  |  |  |  |  |
    |  S  |  S  |  |  |  |  S
    |  |  |  |  |  |  |  |  |
    |  F  |  F  |  |  F  |  F
    |  |  |  |  |  |  |  |  |
    (  5  +  4  )  *  2  ^  3
    
                   E
                   |
                   T
                  /|\ 
                 / | \
                /  *  S           
               /     /|\ 
              T     / | \
              |    F  ^  S
              S    |     |
              |    2     F
              F          |
             /|\         3
            / | \
           (  E  )
             /|\ 
            / | \
           E  +  T
           |     |
           T     S
           |     |
           S     F
           |     |
           F     4
           |
           5
    
    Working our way up from the bottom,
    we would successively output:
    5 4 +   (followed by)
    2 3 ^   (followed by)
    *   (or altogether)
    5 4 + 2 3 ^ * $   (the answer)

    The most common error was to write:
    5 4 + 2 * 3 ^ $ which is a translation of
    ( ( 5 + 4 ) * 2 ) ^ 3 $

    (or else perhaps assuming that ^ has lower
    precedence than *, but in fact ^ has the highest precedence of these operators ).

    (b) Evaluate the following RPN expression and show your work, step-by-step (not just a final answer): 342+5**$. [Here "evaluate" means to find the final single integer value of the expression.]

    Evaluate 342+5**$ from left to right: push(3); push(4); push(2); 2=pop(); 4=pop(); push(4+2=6); push(5); 5=pop(); 6=pop(); push(6*5=30); 30=pop(); 3=pop(); push(3*30=90); stack contains only 90.


  3. (20) Consider the following grammar and the sentence to the right of it. Is this grammar ambiguous? (Just Yes or No.) Write out a leftmost derivation and a parse tree for this sentence. Is there more than one parse tree for the sentence? (Just Yes or No.)

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

    E ==> T ==> T * F ==> F * F ==> ( E ) * F ==> ( E + T ) * F ==> ( T + T ) * F ==>
    ( F + T ) * F ==> ( id + T ) * F ==> ( id + F ) * F ==> ( id + id ) * F ==> ( id + id ) * id


  4. (35) Consider the grammar on the left and the corresponding parse table for shift-reduce parsing on the right below. Use the table to carry out a shift-reduce parse of the sentence: $ id + id ^ id * id $ . [You must carry this out as we did in the course, step-by-step, showing the stack, current symbol, rest of the input, and action (if "r" give the grammar rule used).]

    Grammar: Arithmetic Expressions
    P  --->  E
    E  --->  E + T  |   E - T  |  T
    T  --->  T * S  |   T / S  |  S
    S  --->  F ^ S  |   F
    F  --->  ( E )  |  id
    

      
    Parser: Shift-Reduce Table
       | id| ^ | */| +-| ( | ) | $ |
    ---+---+---+---+---+---+---+---+
    P  |   |   |   |   |   |   |acc|
    E  |   |   |   | s |   | s | r |
    T  |   |   | s | r |   | r | r |
    S  |   | r | r | r |   | r | r |
    F  |   | s | r | r |   | r | r |
    id |   | r | r | r |   | r | r |
    ^  | s |   |   |   | s |   |   |
    */ | s |   |   |   | s |   |   |
    +- | s |   |   |   | s |   |   |
    (  | s |   |   |   | s |   |   |
    )  |   | r | r | r |   | r | r |
    $  | s |   |   |   | s |   |   |
    ---+---+---+---+---+---+---+---+
    

    Shift-Reduce Actions
    Stack               Curr    Rest of Input       Action
    (top at right)      Sym
    --------------------------------------------------------------------------
    $                   id      + id ^ id * id $    s
    $ id                +       id ^ id * id $      r: F --> id
    $ F                 +       id ^ id * id $      r: S --> F
    $ S                 +       id ^ id * id $      r: T --> S
    $ T                 +       id ^ id * id $      r: E --> T
    $ E                 +       id ^ id * id $      s
    $ E +               id      ^ id * id $         s
    $ E + id            ^       id * id $           r: F --> id
    $ E + F             ^       id * id $           s
    $ E + F ^           id      * id $              s
    $ E + F ^ id        *       id $                r: F --> id
    $ E + F ^ F         *       id $                r: S --> F
    $ E + F ^ S         *       id $                r: S --> F ^ S
    $ E + S             *       id $                r: T --> S
    $ E + T             *       id $                s
    $ E + T *           id      $                   s
    $ E + T * id        $       -                   r: F --> id
    $ E + T * F         $       -                   r: S --> F
    $ E + T * S         $       -                   r: T --> T * S
    $ E + T             $       -                   r: E --> E + T
    $ E                 $       -                   r: P --> E
    $ P                 $       -                   acc
    

    By far the most common mistake was not reducing the three items "F ^ S" together to "S" (shown in purple above) but instead reducing the "S" on top to "T". This mistake made it impossible to complete the parse properly.


  5. (10) With syntax-directed translation, one carries out semantic actions as the parse tree is traversed.

    1. Inheritance refers to passing information down the parse tree (from the root at the top). With a recursive-descent parser, how would you carry this out. Send information in parameters of the function called to go down the tree.

    2. Synthesis refers to moving information up the parse tree toward the root. Again with a recursive-descent parser, how would you carry this out? Use the return value of the function that went down to a node to send information back up.