# This is a Tatsu file.
# Syntax is explained at
# https://tatsu.readthedocs.io/en/stable/syntax.html

@@grammar :: Hlds

# Don't ignore any whitespace
@@whitespace :: //

@@eol_comments :: /[ \t]*#.*?$/
@@keyword :: single_choice multi_choice dish preset  only requires except


start = [n] { @+:location } $ ;

location_header =
	/={3,}/ n ~
	id:identifier ':' s name:string
	attributes:{ location_attribute }
	[ n ]
	/={3,}\n+/
	;

location_attribute =
	n '\t' key:identifier s value:string
	;

location = >location_header items:{ block } ;


attributes =
	name:/[^\n#]*?(?= +-- |  | *\n| *#)/
	[ s '--' ~ s description:/[^\n#]*?(?=  | *\n| *#)/ ]
	[ / {2,}/ ~
		[ {[ s ] ('{' tags+:identifier '}')} / +|$/ ]
		[ price:price ]
	]
	;


block =
	| dish_block
	| choice_block
	;

dish_block =
	'dish' s ~
	id:identifier ':' s >attributes
	n
	choices:{ indent_choice_block }
	;


choice_entry = id:identifier ':' s >attributes ;

noindent_choice_entry = n '\t'   >choice_entry ;
indent_choice_entry   = n '\t\t' >choice_entry ;

# Toplevel choice definitions
choice_block =
	id:identifier ':' s >attributes entries:{ noindent_choice_entry }
	n
	;

# Appears in a dish block. One of:
# 1) reference to toplevel choice definition
# 2) inline choice declaration (as opposed to globally declared and referenced)
indent_choice_block =
	'\t' type:choice_type s
	(
		| kind:`declaration` id:identifier ':' ~ s >attributes entries:{ indent_choice_entry }
		| kind:`reference`   id:identifier [ s price:price ]
	)
	n
	;


s  = / +/ ;
n = '\n' {{'\t'} '\n'} ;

@name
identifier = /[a-z0-9_-]+/ ;
string = /[^\n#]+/ ;
choice_type = 'single_choice' | 'multi_choice' ;

int = /[0-9]+/ ;

currency = '€' ;
price = currency:currency s value_unit:int [ '.' value_cents:/[0-9]{,2}/ ] ;
