Formal Recipe Description Language GrammarΒΆ
The following peggie
PEG grammar formally defines the Recipe Grid
recipe description language.
Note
A still detailed, though less formal, description of the recipe description language is available in the Recipe Description Language Reference.
For a higher-level introduction, see the Recipe Grid Tutorial.
# Starting point for grammar; a series of statements.
recipe <- sp? stmt+ eof
# A statement (e.g. "100g cheese" or "sauce = boil(tomatoes, onion, spices)")
stmt <- (output_list hsp? r":?=" hsp?)? ltr_shorthand eol
output_list <- output (hsp? "," hsp? output)*
output <- string
expr <- step / reference / "(" sp? ltr_shorthand sp? ")"
# Left-to-right shorthand (e.g. "1kg potatoes, peeled, cubed")
ltr_shorthand <- expr (hsp? "," hsp? action)*
# Steps (e.g. "boil(tomatoes, spices)")
step <- action
hsp? "(" sp?
expr
(sp? "," sp? expr)*
(sp? ",")?
sp? ")"
action <- string
# References (e.g. "cheese", "1/2 of white sauce", "remaining pastry")
reference <- ((proportion / explicit_quantity / implicit_quantity) hsp?)?
ingredient
ingredient <- string
# Quantities
implicit_quantity <- number (hsp? known_unit (hsp preposition)?)?
explicit_quantity <- "{" hsp?
number (hsp? freeform_unit)?
hsp? "}"
(hsp preposition)?
# Proportions (e.g. "remaining" or "1/3 of" or "0.3 *")
proportion <- remainder (hsp preposition)?
/ number ( hsp preposition
/ hsp? "%" (hsp preposition)?
/ hsp? "*")
remainder <- r"(?i)(remaining|remainder|rest|left[ \t]*over)\\b"
# A preposition which might follow an ingredient/quantity
preposition <- r"(?i)of([ \t]+the)?\\b"
# Units (n.b. @KNOWN_UNITS@ is substituted for a regex matching all units
# supported by this software).
known_unit <- r"(?i)(@KNOWN_UNITS@)\\b"
freeform_unit <- static_string
# Strings
string <- (naked_string / s_quoted_string / d_quoted_string / bracketed_string)
(hsp? string)?
static_string <- (naked_string / s_quoted_string / d_quoted_string)
(hsp? static_string)?
naked_string <- r"[^\"',:=/(){}\s]([^\"',:=/(){}\n\r]*[^\"',:=/(){}\s])?"
d_quoted_string <- '"' ("\\" . / r'[^"\n\r]')* '"'
s_quoted_string <- "'" ("\\" . / r"[^'\n\r]")* "'"
bracketed_string <- "{" (interpolated_number / "\\" . / r"[^0-9{}\n\r]")* "}"
interpolated_number <- number
# Numbers
number <- fraction / decimal
fraction <- (r"[0-9]+" hsp)? r"[0-9]+" hsp? "/" hsp? r"[0-9]+"
decimal <- r"[0-9]+(\.[0-9]*)?"
# Whitespace
sp <- r"\s+"
hsp <- r"[ \t]+"
eol <- r"[ \t]*[\r\n]\s*" / r"[ \t]*" eof
eof <- !.
In the grammar above, the string @KNOWN_UNITS@
is substituted for a regular
expression which matches the following strings (with spaces here matching any
quantity of whitespace):
bag, bags, box, boxen, boxes, bulb, bulbs, can, cans, clove, cloves, cup, cups, g, gram, grams, kg, kilo, kilogram, kilograms, kilos, knob, knobs, l, lb, lbs, litre, mill, milliliter, milliliters, mills, ml, ounce, ounces, oz, ozs, pack, packet, packets, packs, pinch, pinches, pint, pints, pound, pounds, rasher, rashers, sachet, sachets, sack, sacks, strip, strips, table spoon, table spoons, tablespoon, tablespoons, tbsp, tbsps, tea spoon, tea spoons, teaspoon, teaspoons, tin, tins, tsp, tsps
Note
The above grammar is not able to distinguish between references and ingredients and so is written as if only references exist. The Recipe Grid compiler resolves this distinction in a later compilation stage.