goal = <start_list> {expression <display 1> <add_to_list>}
This production sets the goal for the parser. It specifies that an expression program is made up of zero or more expressions. The parser will construct an Abstract Syntax Tree (AST) for each such expression and leave a list of these on the parse stack.
The production can be read as follows: <start_list> calls a the routine Build_start_list in custbld.slm. This creates a node, labeled list, with no children and pushes it onto the parse stack. Next, an expression is parsed, resulting in a corresponding AST to be pushed onto the stack. This is popped and made a child of a node labeled display. The resulting AST is pushed back onto the stack. Then, the routine Build_add_to_list in custbld.slm is called, which pops the node labeled display, as well as the node labeled list, off the stack, makes the display node the last child of the list node and pushes the modified list node onto the stack.
Thus, when there are no more expressions to parse, the stack contains a list of ASTs. These are then traversed by the Walk function in walker.slm.
expression = term {`+' term <plus 2> | `-' term <minus 2>}
This production will cause the parser to parse a term and push a corresponding AST onto the parse stack. Then, if the next token is a `+' or a `-' it will parse another term and push the corresponding AST onto the stack. The two ASTs are then popped off the stack, made the children of a node labelled plus or minus, respectively, and the new AST pushed onto the stack. In other words, the stack is reduced. Note that annotations in <> brackets are handled automatically when the number of items to be reduced are specified. If not, a routine which must be supplied by the language designer in module custbld.slm is called.
term = factor {`*' factor <multiply 2> | `/' factor <divide 2>}
This production is similar to the one for expression. Note that it causes multiplication and division to have a higher precedence than addition and subtraction.
factor = number | identifier <value 1> | `(' expression `)'
Note that identifiers are automatically evaluated when they appear in expressions. If we had assignments, the identifier on the left-hand side would not be evaluated.
identifier = (Up_let | Low_let) {Up_let | Low_let | Digit | `_' }
number = Digit{Digit}[`.'Digit{Digit}][`e'[`-']Digit{Digit}]
These productions specify how identifiers and numbers are to be scanned. Although scanner generators traditionally use regular expressions to specify token syntax, EBNF can just as easily be used. Note that Up_let, Low_let, and Digit are predefined terminal symbols that correspond to character classes in the scanner.
Tokens = identifier | number
This production tells the compiler generator that identifier and number are productions to be processed by the scanner generator and that they must be treated as tokens by the parser generator.
Ignorable = ` ' | Eol
This production tells the parser that the tokens corresponding to blanks and end-of-line characters should be ignored. Comments could be added to the syntax by specifying a suitable production and listing it as token as well as ignorable.