SMIE’s precedence grammars simply give to each token a pair of
precedences: the left-precedence and the right-precedence. We say
T1 < T2 if the right-precedence of token
T1 is less than
the left-precedence of token
T2. A good way to read this
< is as a kind of parenthesis: if we find
... T1 something
T2 ... then that should be parsed as
... T1 (something T2 ...
rather than as
... T1 something) T2 .... The latter
interpretation would be the case if we had
T1 > T2. If we have
T1 = T2, it means that token T2 follows token T1 in the same
syntactic construction, so typically we have
"begin" = "end".
Such pairs of precedences are sufficient to express left-associativity
or right-associativity of infix operators, nesting of tokens like
parentheses and many other cases.
This function takes a prec2 grammar table and returns an
alist suitable for use in
smie-setup. The prec2
table is itself meant to be built by one of the functions below.
This function takes several prec2 tables and merges them into a new prec2 table.
This function builds a prec2 table from a table of precedences
precs. precs should be a list, sorted by precedence (for
"+" will come before
"*"), of elements of the form
(assoc op ...), where each op is a token that
acts as an operator; assoc is their associativity, which can be
All operators in a given element share the same precedence level
This function lets you specify the grammar using a BNF notation. It accepts a bnf description of the grammar along with a set of conflict resolution rules resolvers, and returns a prec2 table.
bnf is a list of nonterminal definitions of the form
(nonterm rhs1 rhs2 ...) where each rhs
is a (non-empty) list of terminals (aka tokens) or non-terminals.
Not all grammars are accepted:
Additionally, conflicts can occur:
opener(something similar to an open-paren), a
closer(like a close-paren), or
neitherof the two (e.g., an infix operator, or an inner token like
Precedence conflicts can be resolved via resolvers, which
is a list of precs tables (see
each precedence conflict, if those
specify a particular constraint, then the conflict is resolved by using
this constraint instead, else a conflict is reported and one of the
conflicting constraints is picked arbitrarily and the others are