Как создать контекстно-свободную грамматику для ролевой игры - PullRequest
1 голос
/ 10 июля 2020

Я пытаюсь создать программу, которая может вычислять цепочки бросков костей (используя формат n d n , поэтому 2d8 будет бросать две 8-сторонние кости и суммировать их ). Я работаю в Java, но это не имеет значения для этого вопроса. У меня нет большого опыта работы с контекстно-независимыми грамматиками, и у меня есть несколько вопросов о том, как их создать.

Я знаю, что мне нужны элементы (токены):

  • Числа
  • Операторы сложения (+, -)
  • Операторы умножения (*, /)
  • оператор «игральных костей» (d)
  • Модификаторы броска (kh, kl, dh, dl)

Модификаторы броска:

  • kh: сохранение наивысшего n кубика. 4d6kh1 сохранит наивысший бросок, 4d6kh2 сохранит два самых высоких броска и т. Д.
  • kl: оставить наивысший n dice
  • dh: выпадать наивысший n dice
  • dl: drop младший n dice

Эти модификаторы состоят из двух символов каждый, которым предшествует последовательность оператора кости (число d) и затем число (количество оставшихся рулонов).

Возможные значения:

  • 4d4
  • 3d6 + 2d4
  • 2 * (1d6 + 8)
  • 4 * 1d20 + 2
  • 2d20dl1
  • 4d20kh2 + 3d8

Моя попытка создать грамматику ( EBNF):

expr = term (addop factor)*
term = factor (mulop factor)*
diceop = <number> 'd' <number>
dicemod = diceop dmod <number>
factor = <number> | ( expr ) | diceop
dmod = kl | kh | dl | dh
addop = + | -
mulop = * | /

где <number> - любое число

У меня есть несколько вопросов по этому поводу:

  1. Это сделано / заказано каким-либо образом возможно реализовать?
  2. как мне указать, что в dicemod число должно быть меньше или равно первому числу в члене diceop? Я просто делаю это в коде?
  3. нужно ли мне правило выше expr (что означает, что первый токен на любом входе имеет тип expr) или мне нужно что-то выше этого?

Если это поможет, то вот как у меня есть классы для пакета AST на данный момент:

[abstract class] Node, extended by:
    [abstract class] Expr, extended by:
         [class] Number (0-9)
         [class] BinOp (+, -, *, /)
    [class] DiceOp (Number 'd' Number)
    [class] DiceMod (dl, dh, kl, kh)

Где DiceOp должен предшествовать токен Number за которым следует маркер Number; и DiceMod должен предшествовать токен DiceOp, за которым следует токен Number, который является <= первым <code>Number токеном, удерживаемым токеном DiceOp (как дочерний элемент токена).

Я новичок в грамматике и переводчиках в целом, поэтому приветствую любую помощь.

...