LOGO2PYTHON COMPILER This program is fairly portable. It builds and runs correctly on MacOS X, OpenBSD, and Linux. This was originally written for CPSC441 (Compiler Construction I), and many of the design decisions are based on requirements from the assignment specification. The use of C was also specified by the assignment, as was the prohibition on lex/yacc. I ignore stdin but don't close the file descriptor because it's possible to use stdin by making the input filename "/dev/stdin". Closing the file descriptor prevents that from working. The parser forks off a process for input scanning, and tokens are sent to the parser via a pipe, one per line, in the format: "lineno:error:tokenstring" This made the implementation easier because the scanner didn't have to be a complex state machine, and and is also in accordance with the requirement that the scanner and parser be loosely coupled. Provided in the Makefile are the targets "scanner" and "parser". If these are made, binaries "scanner" and "parser" are (respectively) made. Thus, the output of the scanner can be made available to the user, and the user can provide arbitrary input to the parser. These use stdin and stdout. The assignment specified a recursive descent parser. My implementation originally recursed down the keywords array (see keywords.h), but I changed this to a binary search. The recursion was little more than a sequential search, and a more efficient search is not importantly different. My parser detects _some_ cases where a variable is not defined. For example, if a variable is defined in a loop that never executes, the error can slip past my parser. There is no practical way to detect all undefined variables at compile time, so I merely make a best effort in this case. This program can handle input of a very large but not unlimited size. The internal representation of the line numbers is 64-bit, so it's not a problem if the input comes from a filesystem, but input frm a pipe could potentially exceed this limitation. The variable table also places a limit on program size. This is limited by available memory on the machine. Instead of defining variables directly inside Python, I use a dictionary called "variable". This is because there is the possibility of collisions with names already used in Python. The generated Python program detects undefined variables and exits gracefully.