|Thomas W. Christopher|| Consulting in High Performance Computing.
Training in Concurrency, Networking, and Parallelism, especially in Python and Java.
[ Internet Explorer may havea problem with the Applet. If so, you will need to download and install j2re Java plug-in from http://java.sun.com/ .]
This "calculator" inserts action symbols into an input expression. In a real calculator, the action symbols would drive a semantics object which is performing the calculations. The input consists of either expressions or assignments followed by semicolons. Try typing into the "input line," followed by ENTER:
The original grammar is:
start=L. L = e EXPRSTMT! DOPENDINGACTIONS! ";" STMT! L | a ";" STMT! L | ";" NULLSTMT! L | . a = id "=" e ASGN! DOPENDINGACTIONS! . e = e "+" t ADD! | e "-" t SUB! | t. t = f "*" t MPY! | f "/" t DIV! | f "%" t MOD! | f. f = num CVTNUM! | id LOOKUPID! | "-" f NEG! | "(" e ")" PARENS! . fiducials: ";".
The grammar is rewritten by the parser generator to put it in LL(1) form, which introduces new symbols like "t:102".
The identifiers followed by exclamation points are "action symbols," which tell the semantics phase of a translator what action to take. DOPENDINGACTIONS! tells the parser to stop queueing up tokens and actions and to write them out. This is to let the semantics code perform its operations before reading the next input token. This is needed in interactive systems.
The "fiducials" declaration tells the parser at which symbol(s) to try to resume parsing if it encounters an error. It inserts replacement text up to the fiducial.
The best explanation of how to coordinate the parsing and semantics is in my
book, Python Programming Patterns, published by Prentice Hall PTR.