CS3723, Exam, 21 Oct 2013

ANSWERS
 

  1. (20) Consider the following grammar and the sentence to the right of it.

    1. (2) Is this grammar ambiguous? (Just Yes or No.)
    2. (8) Write out a leftmost derivation for the sentence. See below..
    3. (8) Draw a parse tree for the sentence. See below..
    4. (2) 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


  2. (20) Consider the NFA below. It comes from the regular expression /a(a|b)*b/.
     

    Use the subset algorithm from class to construct a DFA that accepts the same language. For full credit you must show the subsets. Don't forget to include the empty set. (Only the pink table below is required, and not the red diagram.)

    Subset Algorithm (Tables)
    NFA, /a(a|b)*b/
    Stateab
      0 (start)1
      111,2
      2
     
    DFA
    Statesab
      {0} (start) {1}Ø
      {1} {1}{1,2}
      {1,2} (term) {1}{1,2}
      Ø ØØ


  3. (35) Consider the grammar on the left and the corresponding parse table for shift-reduce parsing on the right below. Below those two is the start of the shift-reduce parse of the sentence: $ id + id ^ id * id $ . You are to complete this parse, as we did in the course, step-by-step. In case of an r, give the grammar rule used. [Be careful: the standard mistake is to not reduce the longest matching right-hand-side.]

    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
    


  4. (20) Consider the NFA with epsilon moves show below. (Recall the we sometimes use @ in place of ε.)
    1. (6) Give the regular expression that this NFA is derived from, if one uses the main construction that was presented in the course. /(ab)*c/
    2. (4) Give three distinct strings accepted by this NFA. (No reason or justification needed.) c, abc, ababc, ...
    3. (6) Give the epsilon-closure({4}). cl({4}) = {0,4,5,6} (You can construct it intuitively just by following arrows.) (4) What is the significance of this particular set of states? This is the start state for the DFA constructed from the above NFA with epsilon-moves (What is it used for? Short answer.)

      DFA from NFA, /(ab)*c/
      Statesabc
        cl({4}) =
      {0,4,5,6} (start)
      {cl({1}) =
      {1,2}
      Ø cl({7}) =
      {7}
        cl({1}) =
      {1,2}
      Øcl({3}) =
      {0,3,5,6}
      Ø
        cl({7}) =
      {7} (term)
      ØØØ
        cl({3}) =
      {0,3,5,6}
      cl({1}) =
      {1,2}
      Ø cl({7}) =
      {7}


  5. (20) In the grammar for the Tiny language used in class, the rule for an assignment statement is:

      A  −−>  lower-case  '='  E  ';'

    1. (16) With as much detail as you can provide, give your actual code (in Java or in C) for the function that represents this non-terminal as part of a recursive-descent parser. (The details of the language syntax are not as important as knowing what the function will do.) Just code from the "bare" parser, and just this one function. However, your code should also check for errors.
    2. (4) How does your program decide when to call this function? (How does the program recognize that it's found an assignment statement?)

      Parser in Java Parser in C
      private void A() {
         if (Character.isLowerCase(next)) {
            scan();
         }
         else error(9);
         if (next == '=') scan();
         else error(10);
         E();
         if (next == ';') scan();
         else error(11);
      }
      void A(void) {
         if (islower(next)) {
            scan();
         }
         else error(9);
         if (next == '=') scan();
         else error(10);
         E();
         if (next == ';') scan();
         else error(11);
      }

      The assignment statement begins with a lower-case letter, and it is the only statement that does. The above code is from my own program. Inside the function S, I check for a lower-case letter, and without scanning, call A. In A, I check again for a lower-case letter, though there is no need for this. Then I finally scan past the letter.

      Just for the parser we could scan past the letter just before calling A. Later, in translating an assignment to MIPS, the function A will need to know what letter the assignment started with, and it's more convenient to let A have access to the letter before scanning. (We could instead pass the letter to A as a parameter.)

      There many other ways to write the function A.