Midterm Exam

Lexical and Syntactic Analysis


810:155
Translation of Programming Languages


Introduction



Problems

  1. At a high level, we can characterize a compiler as a sequence of stages: lexical analysis, syntax analysis, semantic analysis, optimization, and code generation. Describe each stage in one phrase each.

  2. Why do we use regular expressions to model a programming language's concrete syntax and context-free grammars to model its abstract syntax?

  3. What are the relative advantages and disadvantages of writing a recursive descent parser and writing a table-driven parser.

  4. What do we mean when we say that a grammar is "ambiguous"? Show two techniques for eliminating ambiguity from a grammar.

  5. Write regular expressions that define the strings in each of the following languages:

  6. Give a non-deterministic finite state machine that corresponds to this regular expression:

    a(a|b)*b | b(a|b)*a

    Then give an equivalent deterministic finite state machine.



  7. Use this grammar for the next four problems:

        stmt := for identifier := expr to expr stmt
              | print expr
        expr := number
              | identifier
    




  8. Define the abstract syntax for this grammar.

  9. Define the FIRST and FOLLOW sets for the grammar.

  10. Use your FIRST and FOLLOW sets to create the top-down parsing table for this grammar.

  11. Use your parsing table to trace the operation of a table-driven parser as it recognizes this token stream:
    
         for i := 1 to n
             print n
    


Eugene Wallingford ..... wallingf@cs.uni.edu ..... March 24, 2009