Грамматики прецедента SMIE просто присваивают каждому токену пару прецедентов: левый прецедент и правый прецедент. Мы говорим, что
T1 < T2 если правый прецедент токена T1 меньше левого прецедента токена T2. Хороший способ прочитать этот
< — как своего рода скобка: если мы находим ... T1 что-то T2 ..., то это должно быть разобрано как ... T1 (что-то T2 ..., а не как ... T1 что-то) T2 .... Последняя интерпретация была бы верна, если бы у нас было T1 > T2. Если у нас есть
T1 = T2, это означает, что токен T2 следует за токеном T1 в той же синтаксической конструкции, поэтому обычно у нас есть "begin" = "end".
Такие пары прецедентов достаточны для выражения левой или правой ассоциативности бинарных операторов, вложенности токенов, таких как скобки, и многих других случаев.
Эта функция принимает грамматику prec2 table и возвращает alist, подходящий для использования в smie-setup. prec2
table сама по себе должна быть построена одной из функций ниже.
Эта функция принимает несколько prec2 tables и объединяет их в новую таблицу prec2.
Эта функция строит таблицу prec2 из таблицы прецедентов precs. precs должна быть списком, отсортированным по прецеденту (например, "+" будет идти перед "*"), элементов вида
(assoc op ...), где каждый op — это токен, который действует как оператор; assoc — это его ассоциативность, которая может быть либо left, либо right, либо assoc, либо nonassoc.
Все операторы в заданном элементе имеют одинаковый уровень прецедента и ассоциативность.
Эта функция позволяет вам указать грамматику с использованием нотации BNF. Она принимает описание грамматики bnf вместе с набором правил разрешения конфликтов resolvers и возвращает таблицу prec2.
bnf — это список определений нетерминалов вида
(nonterm rhs1 rhs2 ...), где каждый rhs
— это (непустой) список терминалов (также токенов) или нетерминалов.
Не все грамматики принимаются:
Кроме того, могут возникать конфликты:
opener (что-то похожее на открывающую скобку),
closer (как закрывающая скобка) или neither (ни то, ни другое
(например, бинарный оператор или внутренний токен, такой как "else")).
Конфликты прецедента могут быть разрешены с помощью resolvers, который
является списком таблиц precs (см. smie-precs->prec2): для каждого
конфликта прецедента, если эти таблицы precs
указывают на определенное ограничение, то конфликт разрешается с использованием
этого ограничения, иначе сообщается о конфликте, и одно из конфликтующих ограничений
выбирается произвольно, а остальные просто игнорируются.