diff --git a/app/hlds/__init__.py b/app/hlds/__init__.py new file mode 100755 index 0000000..a45361d --- /dev/null +++ b/app/hlds/__init__.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +from os import path +from tatsu import parse as tatsu_parse + + +# TODO Use proper way to get resources, see https://stackoverflow.com/a/10935674 +with open(path.join(path.dirname(__file__), "hlds.tatsu")) as fh: + GRAMMAR = fh.read() + + +def parse(menu): + return tatsu_parse(GRAMMAR, menu) + + +def main(filename): + import json + from tatsu.util import asjson + + with open(filename) as fh: + ast = parse(fh.read()) + print(json.dumps(asjson(ast), indent="\t")) + + +if __name__ == "__main__": + import sys + main(*sys.argv[1:]) diff --git a/app/hlds/hlds.tatsu b/app/hlds/hlds.tatsu new file mode 100644 index 0000000..cb39a2b --- /dev/null +++ b/app/hlds/hlds.tatsu @@ -0,0 +1,87 @@ +# 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 base 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 ' ' value:string + ; + +location = >location_header items:{ block } ; + + +attributes = + name:/[^\n]*?(?= +-- | +:: | +€ |\n)/ + [ s '--' ~ s description:/[^\n]*?(?= +:: | +€ |\n)/ ] + [ s '::' {s ('{' tags+:identifier '}')} ] + [ [ s '::' ~ ] s price:price ] + ; + + +block = + | base_block + | choice_block + ; + +base_block = + kind:'base' 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 = + kind:`choice_declaration` + id:identifier ':' s >attributes entries:{ noindent_choice_entry } + n + ; + +# Appears in a base 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:`reference` id:identifier [ s price:price ] + | kind:`declaration` id:identifier ':' ~ s >attributes entries:{ indent_choice_entry } + ) + n + ; + + +s = / +/ ; +n = '\n' {{'\t'} '\n'} ; + +@name +identifier = /[a-z0-9_-]+/ ; +string = /[^\n]+/ ; +choice_type = 'single_choice' | 'multi_choice' ; + +number = /[0-9]+(\.[0-9]+)?/ ; + +currency = '€' ; +price = currency:currency s value:number ; diff --git a/app/hlds/testfrituur.hlds b/app/hlds/testfrituur.hlds new file mode 100644 index 0000000..826822a --- /dev/null +++ b/app/hlds/testfrituur.hlds @@ -0,0 +1,26 @@ +============================ +testfrituur: Testfrituur + osm https://www.openstreetmap.org/node/4935648725 +============================ + +sauce: Saus + ketchup: Ketchup -- Een tomatensaus met veel suiker € 0.8 + mayo: Mayonaise -- Eierdooier en olie € 0.8 + curry: Currysaus € 0.8 + stoofvlees: Stoofvleessaus € 1.4 + +base veggieburger: Veggieburger € 4.2 + +base friet: Friet -- Een pakje friet :: {has_meat} {has_gluten} + + single_choice size: Grootte + small: Small € 2 + medium: Medium € 2.5 + large: Large € 3 + xlarge: Extra large -- Je hebt een auto nodig om dit te vervoeren € 50 + + multi_choice sauce + +base vleeskroket: Vleeskroket -- Een vlezige kroket :: {has_meat} € 4.2 +base vleeskroket: Vleeskroket :: {has_meat} € 4.2 +base vleeskroket: Vleeskroket -- Een vlezige kroket diff --git a/data/fritoloog.hlds b/data/fritoloog.hlds new file mode 100644 index 0000000..74b909d --- /dev/null +++ b/data/fritoloog.hlds @@ -0,0 +1,85 @@ +============================ +fritoloog: Fritoloog + osm https://www.openstreetmap.org/node/5813542646 +============================ + +base fries: Frietjes :: {has_meat} + # Gebakken in rundsvet dus {has_meat} + + single_choice size: Formaat + extra_small: Extra small € 1.8 + small: Small € 2 + medium: Medium € 2.5 + large: Large € 3.3 + + multi_choice sauce € 1.4 + +base standalone_sauce: Saus in potje € 0.8 + single_choice sauce + +sauce: Saus + ketchup: Ketchup + mayo: Mayonaise + bicky: Bickysaus + stew: Stoofvleessaus :: {has_meat} € 0.5 + other: Andere (in commentaar) + +extra_cheese: Extra kaas € 0.2 + # FIXME extra kaas waarop? + +base chicken_fingers: Kippenvingers :: {has_meat} € 3 +base nuggiz: Nuggiz :: {has_meat} € 3 +base mammoth_sausage: Mammoetworst :: {has_meat} € 2.1 +base taco: Taco :: {has_meat} € 2.5 +base ragoezi: Ragoezi :: {has_meat} € 2 +base gypsy_stick: Zigeunerstick :: {has_meat} € 2 +base frikandel: Frikandel :: {has_meat} € 1.5 +base frikandel_special: Frikandel special :: {has_meat} € 2.2 +base frikandel_xxl: XXL Frikandel :: {has_meat} € 3 +base viandel: Viandel :: {has_meat} € 1.8 +base viandel_spicy: Spicy-viandel :: {has_meat} € 1.8 +base chicken_corn: Kipcorn :: {has_meat} € 1.8 +base sito: Sito :: {has_meat} € 2.7 +base horse_garlic_sausage: Paardenlookworst :: {has_meat} € 2.4 +base garlic_sausage: Lookworst :: {has_meat} € 2.4 +base bitterbal: Bitterbal :: {has_meat} € 1.5 +base boulet: Boulet :: {has_meat} € 1.8 +base chicken_spring_roll: Kippenloempia :: {has_meat} € 3 +base meat_croquette: Vleeskroket :: {has_meat} € 1.8 +base chicken_drumsticks: Kippenboutjes :: {has_meat} € 3.2 +base fire_breather: Vuurvreter :: {has_meat} € 2 +base mexicano: Mexicano :: {has_meat} € 2.4 +base ardeens_satay: Ardeense saté :: {has_meat} € 2.5 +base satay: Saté :: {has_meat} € 2.7 +base grisley: Grisley :: {has_meat} € 2.7 +base flemish_stew: Stoofvlees :: {has_meat} € 4.5 +base meatballs_tomato_sauce: Balletjes in tomatensaus :: {has_meat} € 4.5 +base hamburger: Hamburger :: {has_meat} € 2.6 +base cheeseburger: Cheeseburger :: {has_meat} € 2.9 +base chicken_burger: Chickenburger :: {has_meat} € 3.2 +base bicky_burger: Bickyburger :: {has_meat} € 2.9 +base bicky_rib: Bicky Rib :: {has_meat} € 3.5 +base bicky_royal: Bicky Royal :: {has_meat} € 4.3 +base bicky_chicken: Bicky Chicken :: {has_meat} € 3.2 +base bicky_wrap: Bicky Wrap :: {has_meat} € 3 +base assortment: Twijfelaar :: {has_meat} € 3 + +base chili_cheese: Chili cheese :: {has_meat} € 2.7 + # FIXME zit hier vlees in? + +base fish_burger: Fishburger :: {has_fish} € 3 +base cod_stick: Kabeljauwstick :: {has_fish} € 2.5 +base shrimp_croquette: Garnaalkroket :: {has_fish} € 2 + +base mozarella_sticks: Mozarellasticks € 3 +base cheese_croquette: Kaaskroket € 1.5 +base veggi_burger: Veggieburger € 3.2 +base cheese_souflesse: Kaassouflesse € 1.5 + # https://www.vangeloven.com/merk/souflesse +base bonita: Bonita € 2 + # https://www.devriesvanoers.nl/assortiment/specialiteiten/vegetarisch-groentesnack-vries-bonita/ +base sajoera: Sajoera € 2 + # https://www.devriesvanoers.nl/assortiment/specialiteiten/vegetarisch-groentekroket-vries-sajoera/ +base veg_cheese_disc: Groenten-kaasschijf € 2.4 +base mini_spring_rolls: Mini-loempia's € 3 +base bami: Bami € 2 diff --git a/data/oceangarden.hlds b/data/oceangarden.hlds new file mode 100644 index 0000000..cd7b8b3 --- /dev/null +++ b/data/oceangarden.hlds @@ -0,0 +1,66 @@ +============================================= +og: Ocean Garden + # Openingsuren, website, telefoonnummer, adres enz. worden uit OpenStreetMap gehaald + osm https://www.openstreetmap.org/node/2275105003 +============================================= + +bami_nasi: Bami of nasi + bami: Bami -- Tarwenoedels + nasi: Nasi -- Rijst + +bami_mihoen: Bami of mihoen + bami: Bami -- Tarwenoedels + mihoen: Mihoen -- Dunne, Chinese noedels, gemaakt van rijstbloem + +carbs: Koolhydraten + bami: Bami -- Tarwenoedels + nasi: Nasi -- Rijst + mihoen: Mihoen -- Dunne, Chinese noedels, gemaakt van rijstbloem + + # FIXME De balletjes mogen enkel bij gerechten waar je "sweetsour" kán kiezen, en worden enkel + # geactiveerd als "sweetsour" ook effectief gekozen is – idealiter staat bij een niet-actieve + # keuze ook de reden erbij + balls: Gepaneerde balletjes € 2.5 + #requires sweetsour + +sauce: Saus + bali: Bali -- Indonesische saus + yusiang: Yu-siang -- Chinese saus met chili, pijpajuin, gember en look + gonboa: Gon-boa -- Pikante kruidensaus uit het westen van China + curry: Curry + sweetsour: Zoetzuur + oyster: Oester :: {has_fish} + pepper: Pepersaus + mushroom: Champignon + malaysian: A la Maleisië -- Licht pikante saus + +meat: Vlees :: {has_meat} + chicken: Kip + pork: Varken + duck: Eend + +meat_no_duck: Vlees :: {has_meat} + chicken: Kip + pork: Varken + +maybe_meat_no_duck: Vlees + chicken: Kip :: {has_meat} + pork: Varken :: {has_meat} + no_meat: Geen vlees + + +# Studentenwok 1 en 4 zijn eigenlijk hetzelfde +base wok1_4: Studentenwok met saus € 6 + single_choice bamimihoen + single_choice maybe_meat_no_duck + +base wok2: Studentenwok kip/varken bami/mihoen zonder saus € 6 + single_choice bamimihoen + single_choice meat_no_duck + +base wok3: Studentenwok kip bami/nasi zonder saus :: {has_meat} € 6 + single_choice baminasi + +base wok5: Studentenwok Babi Pangang -- Geroosterd varkensvlees :: {has_meat} € 6 + single_choice baminasi + single_choice sauce diff --git a/data/oceangarden_future_syntax.hlds b/data/oceangarden_future_syntax.hlds new file mode 100644 index 0000000..b62be7c --- /dev/null +++ b/data/oceangarden_future_syntax.hlds @@ -0,0 +1,88 @@ +# Syntaxprimer: +# • Bestanden kunnen geconcateneerd worden, de syntax “== label: Naam” opent een nieuwe locatie. +# • Alle labels binnen een locatie moeten uniek zijn. +# • “single_choice” is een keyword dat betekent: optiegroep met verplicht 1 keuze. “multi_choice” +# betekent: keuzegroep met 0..∞ keuzes. +# • Dubbelepunt leidt de naam in, dubbele hyphen de beschrijving. Bij basisgerechten en opties kan +# ook een prijs gegeven worden. Alles kan ook tags krijgen, ik dacht aan allergiën of diëten: +# {has_meat} en {has_fish} markeren dingen als niet-vegetarisch. Volgorde is altijd +# “label: Naam -- Beschrijving :: {tag1} {tag2} €prijs”. +# • *label (mix-in) voegt alle entries in in het huidige blok. Bruikbaar in basisgerechten en in +# opties. +# • Attributen propageren van optiegroep naar de opties erin. Daarmee bedoel ik dat de {has_meat} +# op “meat” op de “pork” zal plakken, zodat “wok1_4” {has_meat} krijgt als je “pork” bij kiest. + +============================================= +og: Ocean Garden + # Openingsuren, website, telefoonnummer, adres enz. worden uit OpenStreetMap gehaald + osm https://www.openstreetmap.org/node/2275105003 +============================================= + +carbs: Koolhydraten + bami: Bami -- Noedels + nasi: Nasi -- Rijst + mihoen: Mihoen -- Wtf is dit + + # De balletjes worden enkel getoond bij gerechten waar je "sweetsour" kán kiezen, en worden enkel + # geactiveerd als "sweetsour" ook effectief gekozen is – idealiter staat bij een niet-actieve + # keuze ook de reden erbij + balls: Gepaneerde balletjes € 2.5 + requires sweetsour + +baminasi: Bami of nasi + single_choice baminasi + only bami, nasi + +sauce: Saus + bali: Bali -- Indonesische saus + yusiang: Yu-siang -- Chinese saus met chili, pijpajuin, gember en look + gonboa: Gon-boa -- Pikante kruidensaus uit het westen van China + curry: Curry -- Iedereen kent het maar niemand weet wat het is + sweetsour: Zoetzuur + oyster: Oester :: {has_fish} + pepper: Pepersaus + mushroom: Champignon -- Wist je dat champignons geen groenten zijn? + malaysian: A la Maleisië -- Licht pikante saus + +meat: Vlees :: {has_meat} + chicken: Kip + pork: Varken + duck: Eend + +maybe_meat: Vlees + *meat + no_meat: Geen vlees + + +# Studentenwok 1 en 4 zijn eigenlijk hetzelfde +base wok1_4: Studentenwok met saus € 6 + single_choice carbs + except nasi + single_choice maybe_meat + except duck + +base wok2: Studentenwok kip/varken bami/mihoen zonder saus € 6 + single_choice carbs + except nasi + single_choice meat + only chicken, pork + +base wok3: Studentenwok kip bami/nasi zonder saus € 6 + single_choice baminasi + single_choice meat + only chicken + +base wok5: Studentenwok Babi Pangang -- Geroosterd varkensvlees :: {has_meat} € 6 + single_choice baminasi + single_choice sauce + +base veggie: VEGETARISCH-PURISTISCH demo-entry waarbij je ENKEL VEGGIE kan kiezen = LETTERLIJIK HET BESTE € 6 + single_choice baminasi + single_choice sauce + except {has_fish} + except {has_meat} + + +preset bbp: Bami Babi Pangang + wok5 + bami diff --git a/requirements.in b/requirements.in index 32b31b7..d9a175f 100644 --- a/requirements.in +++ b/requirements.in @@ -11,3 +11,4 @@ Flask-Migrate Flask-Script black pymysql +tatsu