Homework 4 Solutions


  1. Rewrite production 1 in a way that it could be recognized using bison:
    (1) stmt -> directive?
    (2) directive -> left | right
    
    Any of the following three solutions is correct, with my preference being for the first one, because it most closely captures the spirit of an optional non-terminal:
    1. stmt -> ε | directive
      directive -> left | right
      
    2. stmt -> ε | left | right
      
    3. stmt -> directive
      directive -> ε | left | right
      
  2. Rewrite production 1 in a way that it could be recognized using bison:
    (1) stmt -> directive+
    (2) directive -> left | right
    
    stmt -> directiveList
    directiveList -> directiveList directive
          | directive
    
  3. Rewrite production 1 in a way that it could be recognized using bison:
    (1) stmt -> directive*
    (2) directive -> left | right
    
    stmt -> directiveList
    directiveList -> directiveList directive
          | ε
    
  4. Rewrite production 1 in a way that it could be recognized using bison:
    (1) stmt -> directive number (, directive number)*
    (2) directive -> left | right
    
    stmt -> command commandList
    commandList -> commandList , command
           | ε
    command -> directive number
    
    Another way to write the solution, without introducing the command non-terminal, is:
    stmt -> directive number commandList
    commandList -> commandList , directive number
          | ε
    
  5. Take a look at the bison specification in exp.yacc. It contains a Shift/Reduce conflict which you will be debugging in this problem.
    1. Look at the output file produced by the -v flag. In which state does the Shift/Reduce conflict occur?
      State 5
    2. What token is causing the Shift/Reduce conflict?
      PLUS
    3. Which production can be potentially reduced?
      exp -> exp PLUS exp
    4. Which production can be potentially recognized in the future if we shift the token?
      exp -> exp PLUS exp
    5. What directive can we add to the bison specification to eliminate the conflict?
      The shift reduce conflict is being caused by ambiguity about the associativity of the plus operator, which can be resolved by using the following directive to specify the operator as left associative:
      %left PLUS

  6. Take a look at the bison specification in sections.yacc. It contains a Shift/Reduce conflict which you will be debugging in this problem. Compile this file using the command:
    bison -v sections.yacc
    
    1. Look at the output file produced by the -v flag. In which state does the Shift/Reduce conflict occur?
      State 2
    2. What token is causing the Shift/Reduce conflict?
      ID
    3. Which production can be potentially reduced?
      edgelist -> ε
    4. Which production can be potentially recognized in the future if we shift the token?
      assignmentList -> assignmentList assignment
      If you were not sure which of the two productions might be recognized if there is a shift, then notice that the shift action is to go to state 4. If you look at state 4, you can see that an assignment production is being recognized, which means that a shift operation would potentially recognize the assignmentList production.

    5. The problem with the grammar as it is written is that both the assignments and edges are optional. If I allow you to add a requirement that there be at least one assignment and one edge, then you can rewrite the grammar to eliminate the Shift/Reduce conflict. Show me the rewritten grammar.
      The productions that were causing the Shift/Reduce conflict are the ones for assignmentList and edgeList that allow them to be potentially empty. Here are the offending productions in the original grammar:
      assignmentList : assignmentList assignment
          | 
      ;
      
      edgeList : edgeList edge
          |
      ;
      
      I allowed you to add a requirement that there be at least one assignment and one edge, so I can rewrite these productions as follows to require that there be at least one of each:
      assignmentList : assignmentList assignment
          | assignment 
      ;
      edgeList : edgeList edge
          | edge
      ;
      

  7. In the previous problem, I allowed you to add a requirement that there be at least one assignment statement and one edge statement. Suppose though that I really wanted to allow both assignments and edges to be optional. Now I cannot rewrite the grammar to reduce the shift/reduce conflict. What could I instead add to the grammar in order to eliminate the shift/reduce conflict? Describe informally what you would do and then write the one production that you would change. You only need to add something to one production in order for the grammar to become unambiguous.

    I must add some type of delimiter between the assignment and edge statements, so that the parser will know unambiguously when one section has ended and the next is to begin. The delimiter should be added to the top level production:

    stmt : assignmentList edges edgeList
    
    It is good to use a delimiter that your potential users can easily remember. In this case, the user is starting to enumerate the edges, so a good delimiter name is edges. However, I accepted any answer that had some sort of distinguishing delimiter.

  8. The bison parser for:

    1. The yacc and lex specification for the simplified "edges" grammar.
    2. The yacc and lex specification for the full graph grammar.