Please answer all questions in the spaces provided (two sides). Max 30
This test is intended to check your ability to write simple scanners and parsers. Textbooks may not be used.
1. I have really lost it this week. I cannot even remember the question! But what is the answer?
(Hint: it is not "42" even if you know that joke)
2. Suppose we have a grammar which included the PRODUCTIONS
PRODUCTIONS A = [ B ] '(' number { '+' number | B } ')' . B = '-' number '.' | '.' .
Assuming that you have Accept() and Abort() methods like those you used last week, and a scanner GetSym() that can recognise tokens that might be described by the enumeration
EOFSym, noSym, plusSym, minusSym, numSym, lparenSym, rparenSym, periodSym;
how would you complete the parser routines below? Note: the grammar might have other productions, some of which might have right sides that include the non-terminals A and B. [11]
static void A () { // A = [ B ] '(' number { '+' number | B } ')' . } static void B () { // B = '-' number '.' | '.' . }
3. Suppose we wanted to write a scanner to match the specification of numbers like those in the assembler grammar, which can be expressed in Cocol as follows (only three kinds of tokens are valid!) [18]
CHARACTERS digit = "0123456789" . binDigit = "01" . hexDigit = digit + "ABCDEF" . eol = CHR(10) . COMMENTS FROM "{" TO "}" IGNORE CHR(1) .. CHR(32) /* character handler returns CHR(0) as EOF */ TOKENS decNumber = digit { digit } . /* digits only */ binNumber = binDigit { binDigit } "%" . /* trailing % */ hexNumber = digit { hexDigit } "H" . /* trailing H */
The routine must assign either decSym or binSym or hexSym to symKind before leaving the routine (or assign the value of noSym if it comes across an invalid token, or eofSym at the end of file). Complete the skeleton code below to show how this might be done. Assume that you have access to Boolean methods like IsHexDigit(ch) and IsBinDigit(ch) that can test their argument in the obvious way:
static void GetSym() { // Scans for next sym StringBuilder symLex = new StringBuilder(); int symKind = noSym; // assume the worst! while (ch > EOF && ch <= ' ') GetChar(); // whitespace // deal with comments if (Char.IsDigit(ch) { // deal with numbers sym = new Token(symKind, symLex.ToString()); }