CS 210 Example Midterm Examination

Answer all problems. This is a closed book exam. There are 5 problems. Manage your time.

Note: this is an example midterm, edited, from a previous semester of CS 210. It is meant to illustrate the type of questions that tend to appear on a Jeffery-CS210 midterm, not the scope of your exam. For your midterm, you should study lecture notes, Lisp, and flex per the in-class midterm exam review.

1. (10 points) Regular Expressions. Define regular expressions and give a short description of their meaning.

Dr. J's commentary: this question asks you to have memorized the syntax and semantics of regular expressions. A potential open-ended part of this question was whether it must include all of Flex's extended regular expression language, or would be sufficient to list the core regular expressions. I generally might want you to tell me all that you know, but this is only a 10 point question. Most of the extended regular expressions are just "shorthand" for the core regular expressions. You might get 10 points for a correct and complete description of the core regular expressions.

2. (40 points) Flex. Write a flex specification for the YACC/Bison context-free grammar language. This is the section of a Bison file in between the first %% and the second %%. Include tokens for %%, symbols (sequences of alphabetic characters), and Bison-style operators necessary for the context-free grammar section. You do not have to handle the semantic actions (which are arbitrary C code).

Write supporting C semantic actions that cause these token types to return integer codes starting from 257. Assign to a global variable named yylval.tok a structure of the form

struct token {
   int category;     /* 257, 258, … */
   char text;          /* saved copy of actual chars matched */
   int lineno;         /* line number */
}; 

This is a fairly hard problem, worth a lot of points. It tests whether you have working knowledge of Flex, which you hopefully learned well doing a homework. It also asks you if you remember basic Bison punctuation rules. You need to write a few regular expressions for this, but no hard ones. Your midterm could ask you for more difficult regular expressions than this.
%%
"%%"		{ return tok(257); /* section separator */ }
[a-zA-Z0-9]+	{ return tok(258); /* symbol (terminal or nonterminal) */ }
":"		{ return tok(259); /* separates left from right in rule */ }
";"		{ return tok(260); /* ends a rule */ }
"|"		{ return tok(261); /* starts another rule for same nonterm */ }
%%
int tok(int cat)
{
   yylval.tok.category = cat;
   yylval.tok.text = strdup(yytext);
   yylval.tok.lineno = yylineno;
   return 25;
}

3. (20 points) Context Free Grammars. Write a context free grammar for a subset of Common Lisp that consists only of symbols, numbers, and lists. Give appropriate syntax checks for defun, car, cdr, cons, if, and eq.

This is a big enough problem that it should possibly be worth more points. If class hasn't covered, e.g. Lisp's "if" expressions, it would not be fair game to ask you to know what they look like. "Appropriate syntax checks" is a bit of a pain, otherwise Lisp syntax is trivial.

Terminals could be given as SYMBOLNAMES or for single-character symbols, you could use C character literals in single-quotes. The terminals for Lisp include the ones mentioned, plus the all-important left- and right- parenthesis characters. You could give your answer in classic (arrow) or Bison (colon ... semi-colon) syntax. I give it in Bison-style here since I have no drawing tool with me. The key is to introduce appropriate basis case (terminal symbols) and induction step (non-terminals, probably recursive).

program : expressions ;
expressions: expression expressions | /* epsilon */ ;
expression : atom | codelist ;
atom : NUMBER | SYMBOL | nil;
codelist : defun | car | cdr | cons | if | eq ;
nil : '(' ')' | NIL ;
defun : '(' DEFUN SYMBOL '(' arglist ')' expressions ')' ;
car : '(' CAR expression ')' ;
cdr : '(' CDR expression ')' ;
cons : '(' CONS expression expression ')' ;
if : '(' IF expression expression ')' ;
if : '(' IF expression expression expression ')' ;
eq : '(' EQ expression expression ')' ;

4. (40 points) Bison. Write a Bison specification for the context free grammar you define in #3. Include a C main() procedure that performs a syntax check of a named Lisp .l file command line argument. Extra credit if you eval or print (this problem is a Lisp read operation).

This question tests whether you've learned enough Bison to know how to call it from main(), and how to write the header section. Substantial details could be different in the main() procedure.
%token NUMBER SYMBOL NIL DEFUN CAR CDR CONS IF EQ

%%
 insert solution to #3 here 

%%

int main(int argc, char *argv[])
{
   FILE *yyin = fopen(argv[1],"r");
   if (yyin == NULL) { printf("can't open ", argv[1]); exit(-1);}
   if (yyparse()==0) printf("No errors\n");
   else printf("There were syntax errors\n");
   return 0;
}
More example questions, from Lisp:

5. (20 points) Explain the difference between ordinary functions and special forms in Lisp. Give an example of each.

6. (20 points) Give as precise and formal a definition of Lisp lists as you can.

7. (40 points) Write a Lisp function (flatten L) that takes an arbitrary list L that may contain sublists, and sublists within sublists, and so on, and returns a flat list that contains all the atom elements that occur within L. You may write helper functions.

Sample solution:
(defun flatten (L)
   (if (null L) nil
      (if (consp L) (append (flatten (car L)) (flatten (cdr L)))
         (cons L nil)
      )
   )
)

8. (20 points) Draw a diagram (using rectangles to depict cons cells, and arrow-lines to depict pointers) of the Lisp list: ((( a b c ) d (e)) ((f) g))