CS 3040, Exam 2 Review, 2022
The exam will be closed-book, closed-note. You can bring a single page (up
to 8.5 by 11) of notes, front and back.
Review questions (for reference only - the exam may include other topics!):
- Review answers for the matrix programming language grammar.
- Define a Haskell type for
- Full names (first, last, middle)
- A course roster, including the major (eg: "SE" or "CS"), the course
number, and all students, where each student is specified by their full name
- Give two primary reasons why program input needs to be parsed
(remembering a compiler is just a program!).
- Using BNL, give a parse tree for "10.01"
- Why not use written languages (Mandarin, English, French, etc.) to
define the syntax of programming languages?
- Give another example of a metalanguage besides BNF or EBNF.
- Create a grammar (a CFG) for the language captured by the regular expression
(0|1)*1(0|1)*. Specify the grammar formally using a quadruple (〈...〉)
- Extend the "classic expression grammar" (approximately slide 10 in
note 3) to
include calling functions with multiple arguments.
- A CFG is formally described as a quadruple with the fourth item being
the start non-terminal. Why can't we just assume the first non-terminal
is the start symbol?
- Using the expression grammar in the notes, give a derivation sequence
for 3 + 4 * 5.
- Give a CFG (formally defined) for anbn.
- Give a railroad diagram for anbn.
- Give an ambiguous grammar, written in BNF, for 1*.
- Give a left-recursive grammar for a*, then rewrite it as a
right-recursive grammar.
- Give a proof that any regular expression (using just sequence, |, and
*) can be written as a context free grammar written using just BNF (that
is, productions without regular expression notation like * and |).
- In two sentences, explain how to write a recursive descent parser.
- Explain in two sentences how a bottom-up parser works (assuming the
reader knows what a bottom-up parser is).
- Explain in two sentences how a top-down parser works (again, assuming
the reader knows what one is).
- Write a recursive descent parser for the CFG 〈{X}, {a}, {X
→ a X a, X → b}, X〉 assuming you have
a
next_token
method
that returns the next token (a character, in this case)
and advance
that advances to the following token. Write the
parser in C++.
- Is there a bound on the size of the stack
to_match
(z
in the notes) for a bottom-up parser?
- Write a Haskell function that uses pattern matching and recursion to
return whether a list has an even length. Do not use
length
.
- Why is
is_empty x = (length x) == 0
a bad idea?
- A restaurant has two menus, one for lunch and one for dinner. Each
menu is a list of food items. Create a Haskell type to track the two
types of menus, and use that type to write a Haskell function that takes
a list of menus and counts the number of ones for dinner.
- Using Haskell, write a recursive descent parser for the CFG 〈{X,
Y}, {a, b, c}, {X → aY, X →c, Y → bX}, X〉. The
function should take a list of characters (a string) such as "ababc" and
return
True
if the string is accepted by the grammar and
False
otherwise.
- Modify nats.hs
to include a subtraction operation so that
subst (Succ (Succ (Succ Zero))) (Succ (Succ Zero))
gives (Succ Zero)
(that is, 3 - 2 gives 1). If the second
argument is greater than the first, return Zero
.
- Select an ANTLR specification file and name all of the elements in
that file.
- Explain ad-hoc vs. operational semantics. Give an advantage of each.