diff --git a/data/test-cases b/data/test-cases index 361ef18..3c3735f 100644 --- a/data/test-cases +++ b/data/test-cases @@ -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 @@ -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 diff --git a/data/test-samples-parsed b/data/test-samples-parsed index d31e44b..0a5c2c0 100644 --- a/data/test-samples-parsed +++ b/data/test-samples-parsed @@ -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. diff --git a/data/test-samples-with-issues b/data/test-samples-with-issues index 1c3ef11..412de81 100644 --- a/data/test-samples-with-issues +++ b/data/test-samples-with-issues @@ -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 @@ -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. diff --git a/lib/food_ingredient_parser/strict/grammar/ingredient.treetop b/lib/food_ingredient_parser/strict/grammar/ingredient.treetop index cf9bccd..1ee4706 100644 --- a/lib/food_ingredient_parser/strict/grammar/ingredient.treetop +++ b/lib/food_ingredient_parser/strict/grammar/ingredient.treetop @@ -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 diff --git a/lib/food_ingredient_parser/strict/grammar/ingredient_coloned.treetop b/lib/food_ingredient_parser/strict/grammar/ingredient_coloned.treetop index 3d98c82..aa0f751 100644 --- a/lib/food_ingredient_parser/strict/grammar/ingredient_coloned.treetop +++ b/lib/food_ingredient_parser/strict/grammar/ingredient_coloned.treetop @@ -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 )* ) end + rule ingredient_coloned_semicol + ing:ingredient_simple ws* ':' post:( ws* '}' )? ws* contains:( ingredient_coloned_semicol_inner_list ) ';' + end + + rule ingredient_coloned_semicol_inner_list + contains:( ingredient_coloned_simple_with_amount_and_nest ( ws* ',' ws* ingredient_coloned_simple_with_amount_and_nest )* ) + end + # @see IngredientSimple#ingredient_simple rule ingredient_coloned_simple name:( ingredient_coloned_word ( ws+ !amount ingredient_coloned_word )* ) ws? mark:mark / diff --git a/lib/food_ingredient_parser/strict/grammar/list.treetop b/lib/food_ingredient_parser/strict/grammar/list.treetop index 6e82bc8..249a511 100644 --- a/lib/food_ingredient_parser/strict/grammar/list.treetop +++ b/lib/food_ingredient_parser/strict/grammar/list.treetop @@ -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 )? ) / contains:(ingredient ( ws* ';' ws* ingredient )+ ( ws+ and ws+ ingredient )? ) / contains:(ingredient ( ws* ',' ws* ingredient )+ ( ws+ and ws+ ingredient )? ) / @@ -12,5 +14,13 @@ module FoodIngredientParser::Strict::Grammar contains:(ingredient_simple_e_number ( ws* dash ws* ingredient_simple_e_number )+ ) / contains:(ingredient ( ws+ and ws+ ingredient )? ) 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 )? + ) + end end end diff --git a/lib/food_ingredient_parser/strict/grammar/root.treetop b/lib/food_ingredient_parser/strict/grammar/root.treetop index 64004ab..b15ba58 100644 --- a/lib/food_ingredient_parser/strict/grammar/root.treetop +++ b/lib/food_ingredient_parser/strict/grammar/root.treetop @@ -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* )?