Scanner assignment
Description
Write the scanner, the first phase of your compiler. The scanner
converts an input program into tokens and rewrites the program with some
tokens modified. If the input program is a correct C program, the
output program should also be a correct program that has identical behavior.
The specific requirements for code generation are:
-
The scanner should recognize all the tokens of the input program. The
token definitions are here.
-
The scanner to add string "cs254" or "cs454" to the beginning of every
<identifier> token except the name of function "main".
-
The '#include' statements and C++ style comments are treated as special
tokens. They are defined as <meta statement> in our token language.
Your scanner should simply copy them to the generated program (each in
a separate line) without modification. Your future compiler will
be asked to do the same.
-
The scanner takes one arguement, which is the name of the input program,
and puts the generated program in a new file named with an extension "_gen".
So "foo.c" will become "foo_gen.c".
-
The output program does not need to be formatted in any way. The
scanner can write all statements in one line, except that the meta-statements
should be put in separate lines.
For example, the following program should be converted
as follows.
example program : foo.c
#include <stdio.h>
#define read(x) scanf("%d\n", &x)
#define write(x) printf("%d\n", x)
// function foo
void foo() {
int a;
read(a);
write(a);
}
int main() {
foo();
}
running your scanner:
% scanner foo.c
generated program (no formatting needed): foo_gen.c
#include <stdio.h>
#define read(x) scanf("%d\n", &x)
#define write(x) printf("%d\n", x)
// function foo
void cs254foo() { int cs254a; read(cs254a);
write(cs254a); } int main() { cs254foo(); }
Your scanner will be tested by whether the generated program gives the
same execution result as the input program.
Recommended implementation:
-
Encapsulate states and functions of tokens in token objects.
-
Encapsulate the scanning process in a scanner object that has the following
three functions:
-
A constructor that takes in the name of the input program
-
A test function that tells whether there is more token left in the input
program
-
A access function that returns the next token
With this interface, you can scan through and print a program as follows:
Scanner scanner("test1.c"); // Initialize the
scanner.
While (scanner.HasMoreTokens()) {
Token t = scanner.GetNextToken();
if (t.GetTokenType()==ID
&& t.GetTokenName()!="main")
... ... // print token with cs254 attached
else
t.Print();
}