5. A portable and efficient LALR(1) parser generator for Scheme -- The grammar format |
|
5.1 The syntaxThe grammar is specified by first giving the list of terminals and the list of non-terminal definitions. Each non-terminal definition is a list where the first element is the non-terminal and the other elements are the right-hand sides (lists of grammar symbols). In addition to this, each rhs can be followed by a semantic action. For example, consider the following (yacc) grammar for a very simple expression language:
e : e '+' t
| e '-' t
| t
;
t : t '*' f
: t '/' f
| f
;
f : ID
;
The same grammar, written for the scheme parser generator, would look like this (with semantic actions)
(define expr-parser
(lalr-parser
; Terminal symbols
(ID + - * /)
; Productions
(e (e + t) : (+ $1 $3)
(e - t) : (- $1 $3)
(t) : $1)
(t (t * f) : (* $1 $3)
(t / f) : (/ $1 $3)
(f) : $1)
(f (ID) : $1)))</pre>
In semantic actions, the symbol 5.2 Operator precedence and associativityThe above grammar implicitly handles operator precedences. It is also possible to explicitly assign precedences and associativity to terminal symbols and productions à la Yacc. Here is a modified (and augmented) version of the grammar:
(define expr-parser
(lalr-parser
; Terminal symbols
(ID
(left: + -)
(left: * /)
(nonassoc: uminus))
(e (e + e) : (+ $1 $3)
(e - e) : (- $1 $3)
(e * e) : (* $1 $3)
(e / e) : (/ $1 $3)
(- e (prec: uminus)) : (- $2)
(ID) : $1)))
The 5.3 OptionsThe following options are available.
5.4 Error recovery
(rulename
...
(error TERMINAL) : action-code
)
(There can be several such productions for a single rulename.) This will cause the parser to skip all the tokens produced by the lexer that are different than the given TERMINAL. For a C-like language, one can synchronize on semicolons and closing curly brackets by writing error rules like these:
(stmt
(expression SEMICOLON) : ...
(LBRACKET stmt RBRACKET) : ...
(error SEMICOLON)
(error RBRACKET))
5.5 A final note on conflict resolutionConflicts in the grammar are handled in a conventional way. In the absence of precedence directives, Shift/Reduce conflicts are resolved by shifting, and Reduce/Reduce conflicts are resolved by choosing the rule listed first in the grammar definition. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This Html page has been produced by
Skribe.
Last update Sun Dec 3 20:16:43 2006.