Я делаю парсер для DSL на Haskell, используя Alex + Happy. Мой DSL использует броски костей как часть возможных выражений.
Иногда у меня есть выражение, которое я хочу проанализировать, которое выглядит так:
[some code...] 3D6 [... rest of the code]
Что должно примерно переводиться как:
TokenInt {... value = 3}, TokenD, TokenInt {... value = 6}
Мой DSL также использует переменные (в основном строки), поэтому у меня есть специальный токен, который обрабатывает имена переменных. Итак, с этими токенами:
"D" { \pos str -> TokenD pos }
$alpha [$alpha $digit \_ \']* { \pos str -> TokenName pos str}
$digit+ { \pos str -> TokenInt pos (read str) }
Результат, который я получаю при использовании моего синтаксического анализа сейчас:
TokenInt {... value = 3}, TokenName { ... , name = "D6"}
Это означает, что мой лексер считывает целое число и переменную с именем D6.
Я пробовал много вещей, например, я изменил токен D на:
$digit "D" $digit { \pos str -> TokenD pos }
Но это просто потребляет цифры :(
- Могу ли я разобрать бросок костей с числами?
- Или хотя бы парсить TokenInt-TokenD-TokenInt?
PS: я использую PosN в качестве оболочки, не уверен, что это актуально.
Dn
как постфиксный оператор, который повторяетn
-сторонний бросок кубика по своему операнду; или даже разобратьD
как оператор infix со счетчиком кубиков слева и значением кубика справа. Тогда бросок не ограничивается фиксированными кубиками, и вы можете разрешить динамические выражения, такие какx D y
(или стилизованные, например, какx D(y)
) ≅replicateM x (rollD y)
- person Jon Purdy   schedule 13.07.2020