Here you find the grammar for Ordeal::Model::Parser. Hopefully.

I didn’t write the grammar anywhere for documentation purposes - my bad actually, so let’s pay this technical debt now. Ehr yes… by reverse engineering the code 😅

The entry point in the grammar is expression:

expression: addend ( addop addend )*
addend: ( positive_int multop )* atom ( multop positive_int )*
atom: ( identifier | sub_expression ) unaryop* 
sub_expression: '(' expression ')'

addop:  '-' | '+'
multop: '*' | 'x'
unaryop: shuffler | simple_slicer | slicer | sorter
shuffler: '@'
simple_slicer: int
slicer: '[' int_item_list ']'
sorter: '!'

int: simple_int | random_int
simple_int: /0|-?[1-9][0-9]*/
random_int: '{' int_item_list '}'

int_item_list: int_item ( ',' int_item )* (',')?
int_item: int_simple_range | int_range | int
int_simple_range: '#' positive_int
int_range: int '..' int

identifier: token | quoted_string
token: /[a-zA-Z][a-zA-Z0-9_]*/
quoted_string: /"([^\\"]|\\.)"/

positive_int: ...

I hope I didn’t get the symbols wrong:

  • whitespacey stuff is not explicitly indicated to make stuff more readable
  • quoted stuff is just what appears inside
  • stuff between slashes are regular expressions (Backus and Naur will hopefully forgive me)
  • the | character separates alternatives
  • the * character means “zero or more of this”
  • the ‘?’ character means “zero or one of this”
  • parentheses group stuff
  • stuff in a sequence must appear in that sequence
  • a positive_int is just like an int where all actual integers inside are constrained to be strictly positive (it could be expanded in the grammar but it would be more boring than it already is!)

As anticipated, not too much of a grammar!

The whole series

Want to look at the other parts of this series? Here’s a list of them: