Add first version of the HLDS parser
This commit is contained in:
parent
c0936d5a45
commit
ca199f4a3b
7 changed files with 380 additions and 0 deletions
27
app/hlds/__init__.py
Executable file
27
app/hlds/__init__.py
Executable file
|
@ -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:])
|
87
app/hlds/hlds.tatsu
Normal file
87
app/hlds/hlds.tatsu
Normal file
|
@ -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 ;
|
26
app/hlds/testfrituur.hlds
Normal file
26
app/hlds/testfrituur.hlds
Normal file
|
@ -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
|
85
data/fritoloog.hlds
Normal file
85
data/fritoloog.hlds
Normal file
|
@ -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
|
66
data/oceangarden.hlds
Normal file
66
data/oceangarden.hlds
Normal file
|
@ -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
|
88
data/oceangarden_future_syntax.hlds
Normal file
88
data/oceangarden_future_syntax.hlds
Normal file
|
@ -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
|
|
@ -11,3 +11,4 @@ Flask-Migrate
|
||||||
Flask-Script
|
Flask-Script
|
||||||
black
|
black
|
||||||
pymysql
|
pymysql
|
||||||
|
tatsu
|
||||||
|
|
Loading…
Reference in a new issue