(* l03 - expressions with constants and variables *) program = statement { ';' statement } '.' . statement = [ id ( '=' number | ':=' expression ) | '!' expression ] . expression = [ '+' | '-' ] term { ( '+' | '-' ) term } . term = factor { ( '*' | '/' ) factor } . factor = number | id | '(' expression ')' . (* terminals: number id ! = ( * / + - ) ; . l03 = l01 + variables. How to distinguish between a declaration and an assignment, if something like "x=2;y:=3." should be correct? A (constant) declaration uses "=" while a (variable) assignment uses ":=". The first assignment of a variable is just its declaration. Allocation is done on stack before the expression is coded. Since the stack index is the same before and after an expression is processed (output included), a variable can be declared anywhere in the program, and no special declaration part is needed. 2010-04-15, v01: Stack divided into variable and argument space (Comp). While thinking on a register machine I found that the stack has been abused for expression evaluation. Actually, for that simple expressions, a stack of three suffices; the worst case is "x:=0+0*0.". So, now I have two stacks, one (small) for the expressions and another (bigger one) for the variables, where the "real" stack is the latter. This makes clear, that oNew isn't a real operation and thus put to the Opr() command only for convenience -- it takes no argument like "real" operations on a stack-only machine. 2010-04-26, v02: As "!1+2*(3*4)." shows: An argument stack of three is enough only without nesting (ouch). The required stack size s depends on the highest nesting level n. A first estimate yields s <= 3n, so unlimited nesting depths requires an unlimited stack. This recovery wouldn't have changed much in the code (other than increasing the stack size acMax) if I hadn't "finished" pl04v01 already. Now it definitely changes some of my terms: The "real" stack is the operand stack, and that's _the_only_ stack. What I formerly called "real stack" can be thought of RAM or even (indexed) registers. And it clearly shows that variables do not require allocation. The operation oNew has been used only for sharing a limited resource (memory); with distinct argument and variable space, it's pointless. 2010-05-04: Just noticed a missing pair of parentheses in the ebnf definition of "statement" :-(... Fixed. - Obviously, I didn't implement the parser mechanically :-p 2010-05-10: Still wrong, man! Fixed (finally?). *)