Cursus Raku / Addendum 🆕 / Types en tekstmachines / Reguliere expressies en grammatica’s / Exercises / Een grammatica die optelt
Oplossing: Een grammatica die optelt
Hier is een mogelijke oplossing voor de taak.
Code
grammar Sum {
token TOP { <number>+ % '+' }
token number { \d+ }
}
class SumActions {
method TOP($/) { make [+] $<number>.map(*.Int) }
}
say Sum.parse('3+4+5', actions => SumActions).made;🦋 Je kunt de broncode vinden in het bestand grammar-sum.raku.
Uitvoer
12Opmerkingen
<number>+ % '+'matcht een of meer getallen gescheiden door plustekens — de modificator%beschrijft het scheidingsteken tussen de herhalingen.De actiemethode draait wanneer
TOPmatcht.makehangt er een berekende waarde aan — de som van de getallen — die.madena het ontleden terugleest.Een
tokenslaat nooit spaties over, dus is deze grammatica streng over haar invoer:'3+4+5'wordt ontleed, maar'3 + 4 + 5'niet (.parsegeeftNilterug). Om spaties rond de plustekens te accepteren, maak je vanTOPeenrule— en maak je de kwantor los van zijn atoom:grammar Sum { rule TOP { <number> + % '+' } token number { \d+ } }
In een
rulestaat witruimte in het patroon voor een impliciete aanroep van<.ws>. Als<number> + % '+'geschreven, met een spatie vóór de kwantor+, dekt die impliciete witruimte de hele herhaling — scheidingstekens inbegrepen — zodat zowel'3+4+5'als'3 + 4 + 5'ontleed wordt, en de som in beide gevallen12is. (Als je liever bij eentokenblijft, schrijf de spaties dan uit in het scheidingsteken:<number>+ % [ \s* '+' \s* ].)