Skip to content

Commit

Permalink
Handle semicolon after colon (#13)
Browse files Browse the repository at this point in the history
Many cases are handled, but not yet:
- coloned list ending with a '.' (at the end of an ingredient listing)
- list having a both coloned list ending with ';', and one ending with ','
- ';'-separated lists (instead of regular coma-separated lists)
  • Loading branch information
wvengen committed Jun 19, 2024
1 parent ff21275 commit a4ca35c
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 3 deletions.
6 changes: 6 additions & 0 deletions data/test-cases
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rode tomaat, groene komkommer
saus (tomaat, zout)
saus [tomaat, zout]
saus: [tomaat, zout]
tomaat, kruiden: peterselie, basicilum; zout
saus (tomaat, zout), water
saus (tomaat, zout) en water
saus (tomaat, zout) en pasta, water
Expand All @@ -34,6 +35,11 @@ o, p: a/b, q: c
o, p: a/b//d
o, p: a(r)
o, p: a/b (r)
o, p: a,b;
o, p: a,b; q
o, p: a,b; q: c,d;
o, p: a,b; q, r: c,d;
o, p: a,b; q, r: c,d; s, t
o, p: e123-E124a
o, p: E123/E124
p\na, b\n\nq\nc
Expand Down
1 change: 1 addition & 0 deletions data/test-samples-parsed
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ Water, champignon˄1 12%, schouderham˄2 2,5%, plantaardige olie, TARWEBLOEM, ge
Tomaat~ 84% (tomaat, tomatenpuree), wortel, ui, ROOM, suiker, Italiaanse KAAS (Parmigiano Reggiano BOB◊ 1,1%, Grana Padano BOB◊ 0,8% (bevat lysozym van EI)), extra olijfolie verkregen bij de eerste persing, rijstzetmeel, basilicum, peterselie, knoflook, maïszetmeel, tijm, MELKWEI, aroma, zwarte peper, zuurteregelaar: citroenzuur, tomat~ 84% (tomaat, tomatenpuree) , wortel, ui, ROOM, suiker, italiaanse KAAS (Parmigiano Reggiano BOB◊ 1,1%, Grana Padano BOB◊ 0,8% (bevat lysozym van EI)), ~ op duurzame wijze geteeld., ◊ Beschermde Oorsprongsbenaming.
Wraphapje mozzarella-tomaat: 36% tomatenwrap , 29% half zongedroogde tomaat (27% tomaat, zonnebloemolie, knoflook, zout, oregano, marjolein, peterselie), 20% mozzarella , 15% groene pesto . , Wraphapje geitenkaas-beenham: 41% geitenkaas , 33% wrap , 22% beenham , 4% honing. Allergie-informatie: bevat tarwe (gluten), lactose, melkeiwit, ei, cashewnoot, geitenmelkeiwit. Gemaakt in een bedrijf waar ook pinda's en andere noten worden verwerkt.
Wheat Flour [with Calcium, Iron, Niacin (B3) and Thiamin (B1)] and Wholemeal Wheat Flour, Water, Yeast, Vegetable Oils (Sunflower, Rapeseed and Sustainable Palm in varying proportions), Salt, Wheat Gluten, Malted Barley Flour, Emulsifiers: E471, E472e, Soya Flour, Preservative: Calcium Propionate, Flavouring, Flour Treatment Agent: Ascorbic Acid (Vitamin C)
glucosesiroop, suiker, water, gemodificeerd zetmeel, gelatine (rund), vitamine A, vitamine C, vitamine D3, vitamine E, vitamine B6, foliumzuur, vitamine B12, biotine, pantotheenzuur, kaliumjodide, zinkcitraat, magnesiumoxide, zuurteregelaar: citroenzuur; kleurstoffen: curcumine, anthocyanen (vlierbes); natuurlijke aroma’s: sinaasappel, kers, citroen; glansmiddel: carnaubawas; plantaardige olie: kokosnootolie (Cocos nucifera L.); emulgatoren: mono- en diglyceriden van vetzuren, citroenzuuresters van mono- en diglyceriden van vetzuren; maltodextrine.
6 changes: 4 additions & 2 deletions data/test-samples-with-issues
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ Zoetstof: Maltitolen. chocolade 15% (cacaomassa. zoetstof: maltitolen. cacaobote
Suiker; slagroom 20% (melk); magere melk; scharrelei; tarwebloem; plantaardige oliën (raapzaad, palm, palmpit, geheel geharde palmpit, koolzaad, zonnebloem); framboos; glucosestroop; hazelnoot; dextrose; cacaoboter; volle melkpoeder; water; tarwezetmeel; emulgatoren: zonnebloemlecithine, sojalecithine, E433 (plantaardig), E471 (plantaardig), E472a (plantaardig) en E477 (plantaardig); palmvet; rode bessen; cacaomassa; gemodificeerd tarwezetmeel; magere melkpoeder; weipoeder (melk); karamelsuiker; zuurteregelaars: citroenzuur en E331; sojazetmeel; geleermiddel: pectinen; conserveermiddel: E202; lactose (melk); aroma's (hazelnoot); stabilisator: E407; scharreleigeel; verdikkingsmiddelen: E412, arabische gom en E415; kleurstoffen: carotenen, karamel, E171 en E172; natuurlijk vanille-aroma; rijstzetmeel; zout; E= door de EU goedgekeurde hulpstof.
# everything after the first dot is parsed as a note instead of ingredients (todo)
4% volle YOGHURT, suiker, 6% aarbei, 2% sinaasappelsap, gemodificeerd maïszetmeel, natuurlijk aroma, bietensapconcentraat, wortelsapconcentraat. Gekleurde chocopastilles: suiker, cacaoboter, WEIpoeder, magere cacaopoeder, volle MELKpoeder, emulgator (SOJAlecithine), glansmiddel (arabische gom, bijenwas, carnaubawas), kleurstof (caroteen, bietenrood, E101, E120, E141, E163, E171, E172).
# "alc. 11% vol" and "L(+)-wijnsteenzuur" now pass, but the mix of comma's and semicolons is not recognized by the strict parser (todo)
Ingrediënten: wijn (alc. 11% vol) (89,2%), gecertificeerde geconcentreerde druivenmost (5,4%), wijnalcohol (alc. 96% vol) (5,4%), conserveermiddel: kaliumwaterstofsulfiet; voedingszuur: L(+)-wijnsteenzuur; kleustof: sulfiet-ammoniakkaramel.
# "L. rhamnosus Gurbach" parses, but the bracketed expression in the middle isn't recognized (todo)
YOGHURT (0,9% vet) met L. rhamnosus Gorbach & Goldin, suiker, oligofructose, fructose, 1% perziksap, voedingszuur: citroenzuur, aroma, vitamine B11 en D.
# semicolon after colon
Expand All @@ -24,3 +22,7 @@ Ingredienten: Natuurlijk mineraalwater, sappen uit geconcentreerde sappen uit: 9
Mix voor Lasagnesaus ; groenten (knoflook, ui, tomaat, paprika), 39% zeezout, specerijen (peper, chilies), kruiden (peterselie, basilicum, majoraan, 1% tijm, 1% oregano). Mix voor bechamesaus ; tarwezetmeel, melkpoeder, cacaoboter, tarwebloem, 8% zout, ui, natuurlijk aroma, specerijen (0,4% peper, 0,4% nootmuskaat).
# comma in coloned nesting
Mini bamiballetjes, bamihapjes: 54% gekookte mie (water, TARWEGRIES), water, TARWEBLOEM, gedroogde groenten (ui, aardappel, prei, rode peper, wortel, rode paprika, tomaat, kool, knoflook), suiker, zout, TARWEZETMEEL, gemodificeerd zetmeel, gedroogde glucosestroop, plantaardige oliën (gedeeltelijk geharde palm, zonnebloem), sojasaus (water, SOJABONEN, TARWE, zout, maltodextrine), SOJABLOEM, specerijen, aroma, gistextract, gelatine, azijn, kleurstoffen: E150d- E160b, stabilisatoren: E412- E461- E466- E415, gehard palmvet, gist, glucose, geleermiddelen: E450- E401- E516, smaakversterkers: E621, voedingszuren: E330, glucosestroop (bevat TARWE), MELKEIWIT. Kipvariantjes, kip- en kalkoenvleeshapjes: pluimveevlees (30% kalkoenvlees, 6% mechanisch gesepareerd kippenvlees, 4% kippenvlees), TARWEBLOEM, water, raapzaadolie, dierlijk vet (kip), SOJA EIWIT, TARWEZETMEEL, gehydroliseerd SOJA EIWIT, MELKEIWIT, zout, bindweefsel (kip), verdikkingsmiddelen: E464- E461- E414, specerijen, smaakversterkers: E621- E631- E627, emulgatoren: E450- E452, gist, gemodificeerd zetmeel, aroma, glucosestroop, lactose (MELK), EI (kip). Bitterballen, rundvlees bitterballen: water, TARWEBLOEM, 9% gekookt rundvlees, plantaardige oliën (palm, raapzaad), zetmeel (bevat TARWE), ui, zout, stabilisatoren: E461- E451- E450, gelatine (rund), smaakversterkers: E621, kruiden en specerijen (bevat SELDERIJ), sojasaus (water, SOJABONEN, zetmeel (bevat TARWE), zout), LUPINEMEEL, gistextract, glucose (TARWE), geconcentreerd rund bouillon, gist, KIPPENEI EIWIT, gehydroliseerd plantaardig eiwit (TARWE), gedroogde groenten (ui, knoflook), aroma, verdikkingsmiddelen: E412- E407, dierlijk vet (rund), voedingszuren: E270, plantaardig eiwit, gistextract, glucosestroop, antioxidanten: E301, groente extract. Borrelfrikandellen, mini frikandellen: 26% Varkensvlees, 19% rundvlees, 19% kippenseparatorvlees, water, varkenspek, paneermeel (bevat TARWE), TARWEZETMEEL, varkenscollageen, zout, SOJA EIWIT, kruiden en specerijen (bevat MOSTERD, SELDERIJ), uienpoeder, aroma (bevat SOJA), stabilisatoren: E450- E451, smaakversterker: E621. Rempengballetjes, pittige gehaktballetjes: vlees (20% varkensvlees, 15% rundvlees), water, 16% kipseparatorvlees, TARWEZETMEEL, SOJA EIWIT, dierlijk vet (varken, rund), kruiden en specerijen, TARWEBLOEM, zout, gedroogde groenten, bindweefsel (rund), voedingsvezel (TARWE), MELKBESTANDDELEN, emulgatoren: E450- E452, stabilisatoren: E412, smaakversterkers: E621, gist, antioxidanten: E316, GEHYDROLISEERD TARWE EIWIT, raapzaadolie, aroma. Mini cheddarhapjes, mini cheddarkaas hapjes: 50% smeltkaas (37% Cheddar kaas (MELK), 28% kaas (MELK), water, boter (MELK), MELKEIWIT, zetmeel, smeltzouten: E452- E339- E331, zout, kleurstoffen: E160a- E160c), TARWEBLOEM, water, raapzaadolie, gedroogde aardappelreepjes, zout, gist, kleurstoffen: E160b. Mini nasihapjes, mini basisnacks: 59% gekookte rijst, tarwebloem, water, plantaardige oliën (gedeeltelijk geharde palm, zonnebloem), SUIKER, ui, gemodificeerd zetmeel, TARWEZETMEEL, gedroogde groenten (prei, wortel, rode paprika, paprika, knoflook), zout, gehydroliseerd plantaardig eiwit (SOJA, TARWE, maïs), sojasaus (water, SOJABONEN, zout, TARWE), gehard palmvet, SOJABLOEM, smaakversterkers: E621, gistextract, kruiden en specerijen (bevat SELDERIJ), aroma, gedroogde glucosestroop (bevat TARWE), gist, azijn, kleurstoffen: E150d- E100, stabilisatoren: E466- E412, MELKBESTANDDELEN. Kipnuggets, kip- en kalkoenvleeshapjes: pluimveevlees (32% kalkoenvlees, 6% mechanisch gesepareerd kippenvlees, 4% kippenvlees), water, bloem (TARWE, maïs, rijst), raapzaadolie, dierlijk vet (kip), SOJA EIWIT, zetmeel (bevat TARWE), gehydroliseerd SOJA EIWIT, zout, MELKEIWIT, bindweefsel (kip), voedingsvezel (erwt), specerijen, verdikkingsmiddelen: E464- E461- E414, smaakversterkers: E621- E631- E627, gist, emulgatoren: E450- E452, gemodificeerd zetmeel, suiker, aroma, TARWEGLUTEN, glucosestroop, lactose (MELK), EI (kip), stabilisatoren: E466- E500. Mini rundvleeskroketten, rundvleeskroketjes: water, TARWEBLOEM, 9% gekookt rundvlees, plantaardige oliën (palm, raapzaad), zetmeel (bevat TARWE), ui, zout, stabilisatoren: E461- E451- E450, gelatine (rund), smaakversterkers: E621, kruiden en specerijen (bevat SELDERIJ), sojasaus (water, SOJABONEN, zetmeel (bevat TARWE), zout), LUPINEMEEL, gistextract, glucose (TARWE), geconcentreerd rund bouillon, gist, KIPPENEI EIWIT, gehydroliseerd TARWE EIWIT, gedroogde groenten (ui, knoflook), aroma, verdikkingsmiddelen: E412- E407, dierlijk vet (rund), voedingszuren: E270, plantaardig eiwit, gistextract, glucosestroop, antioxidanten: E301, groente extract.
# '.' instead of ';' after last ingredient coloned
Ingrediënten: wijn (alc. 11% vol) (89,2%), gecertificeerde geconcentreerde druivenmost (5,4%), wijnalcohol (alc. 96% vol) (5,4%), conserveermiddel: kaliumwaterstofsulfiet; voedingszuur: L(+)-wijnsteenzuur; kleustof: sulfiet-ammoniakkaramel.
# mix of coloned ingredients with and without closing semicolon; also '.' instead of ';' after last ingredient coloned
Ingrediënten: mineraalwater, suiker, citroensap uit concentraat, aardbeiensap uit concentraat, smaakversterker: erythritol, natuurlijk aroma, zoetstof: steviolglycosiden; vitaminen: Vitamine B6, Vitamine B12.
8 changes: 8 additions & 0 deletions lib/food_ingredient_parser/strict/grammar/ingredient.treetop
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,13 @@ module FoodIngredientParser::Strict::Grammar
)
end

rule ingredient_nocol
ws*
(
ingredient_nested ( ws* and ws+ ingredient )? /
ingredient_simple_with_amount
)
end

end
end
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ module FoodIngredientParser::Strict::Grammar
contains:( ingredient_coloned_simple_with_amount_and_nest ( ws* '/'+ ws* ingredient_coloned_simple_with_amount_and_nest )* ) <ListNode>
end

rule ingredient_coloned_semicol
ing:ingredient_simple ws* ':' post:( ws* '}' )? ws* contains:( ingredient_coloned_semicol_inner_list ) ';' <NestedIngredientNode>
end

rule ingredient_coloned_semicol_inner_list
contains:( ingredient_coloned_simple_with_amount_and_nest ( ws* ',' ws* ingredient_coloned_simple_with_amount_and_nest )* ) <ListNode>
end

# @see IngredientSimple#ingredient_simple
rule ingredient_coloned_simple
name:( ingredient_coloned_word ( ws+ !amount ingredient_coloned_word )* ) ws? mark:mark <IngredientNode> /
Expand Down
10 changes: 10 additions & 0 deletions lib/food_ingredient_parser/strict/grammar/list.treetop
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ module FoodIngredientParser::Strict::Grammar
grammar List
include Common
include Ingredient
include IngredientColoned

rule list
list_coloned_semicol /
contains:(ingredient ( ws* '|' ws* ingredient )+ ( ws+ and ws+ ingredient )? ) <ListNode> /
contains:(ingredient ( ws* ';' ws* ingredient )+ ( ws+ and ws+ ingredient )? ) <ListNode> /
contains:(ingredient ( ws* ',' ws* ingredient )+ ( ws+ and ws+ ingredient )? ) <ListNode> /
Expand All @@ -12,5 +14,13 @@ module FoodIngredientParser::Strict::Grammar
contains:(ingredient_simple_e_number ( ws* dash ws* ingredient_simple_e_number )+ ) <ListNode> /
contains:(ingredient ( ws+ and ws+ ingredient )? ) <ListNode>
end

rule list_coloned_semicol
contains:(
( (ingredient_nocol ws* ',' ws*)* ws* ingredient_coloned_semicol )+
( ws* ingredient_nocol (ws* ',' ws* ingredient_nocol)* )?
( ws+ and ws+ ingredient_nocol )?
) <ListNode>
end
end
end
2 changes: 1 addition & 1 deletion lib/food_ingredient_parser/strict/grammar/root.treetop
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module FoodIngredientParser::Strict::Grammar
rule root
'"'?
root_prefix? ws*
contains:( list_newlined / list_coloned / list )
contains:( list_newlined / list_coloned_semicol / list_coloned / list )
notes:(
root_mark_sentences_in_list? ws*
( ( [.;] ws* newline* / [.;]? ws* newline+ ) ws* root_sentences? ws* )?
Expand Down

0 comments on commit a4ca35c

Please sign in to comment.