2015-03-20 4 views

ответ

5

Вот определение Rule:

class Rule[-I <: HList, +O <: HList] 

Документация вы связаны дает больше объяснений, но, по существу I является входным Правилу и O является выход правила. Обозначение двоеточия может быть немного запутанным. parboiled2 использует стек для управления состоянием. Просто помните, что типы в списках двоеточия (HList) создаются/сдвигаются слева направо и потребляются/появляются справа налево. В HListA:B:C, C - это вершина стека, и ее необходимо использовать в первую очередь.

~ запускает одно правило, а затем следующее. Таким образом, в первом примере a типа Rule[, A] ничего не потребляет и «производит» A, а b типа Rule[,B] ничего не потребляет и «производит» B. Тогда имеет смысл, что если вы запустили a, а затем b, вы должны были бы создать A, а затем B. Итоговый тип: Rule[, A:B].

Когда вы добавляете входы, ситуация становится намного сложнее. Вы должны убедиться, что типы, созданные a (или независимо от первого правила), являются типами, которые будут потреблять b. ~ как раз как функция состав. Ff мы хотим составить g и f, чтобы получить g . f, мы должны быть уверены, что вывод f - это тот же самый тип, что и вход g.

Давайте рассмотрим третий пример в таблице.

  • a имеет тип Rule[A, B:C]
  • b имеет тип Rule[D:B:C, E:F]

Когда мы запускаем aA потребляется из стека, B добавляется в стек, а C добавляется к стек. Затем запускается b, сначала он потребляет C, затем B, затем он потребляет D со стека. Чтобы быть в нужном месте в нужное время, D должен быть под A, который потреблял a. b затем произведет E, а затем F.

В общей сложности мы потребляли D и A. B и C не учитываются, потому что они были произведены и использованы внутри правила. После потребления D и A, мы оставляем E и F на стеке. Таким образом, тип a ~ b - Rule[D:A, E:F].

Четвертый пример в README дает пример, где a производит неправильные типы для b, чтобы потреблять. В этом случае a ~ b является незаконным.