Corso di Raku / Appendice 🆕 / Tipi e macchine per il testo / Espressioni regolari e grammatiche / Exercises / Una grammatica che somma
Soluzione: Una grammatica che somma
Ecco una possibile soluzione del compito.
Codice
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;🦋 Trova il programma nel file grammar-sum.raku.
Output
12Commenti
<number>+ % '+'riconosce uno o più numeri separati da segni+— il modificatore%descrive il separatore fra le ripetizioni.Il metodo di azione gira quando
TOPcorrisponde.makevi attacca un valore calcolato — la somma dei numeri — che.maderilegge dopo l’analisi.Un
tokennon salta mai gli spazi, quindi questa grammatica è severa sul proprio input:'3+4+5'viene analizzato,'3 + 4 + 5'no (.parserestituisceNil). Per accettare spazi attorno ai segni più, rendiTOPunarule— e stacca il quantificatore dal suo atomo:grammar Sum { rule TOP { <number> + % '+' } token number { \d+ } }
In una
rule, lo spazio bianco nello schema sta per una chiamata implicita a<.ws>. Scritto come<number> + % '+', con uno spazio prima del quantificatore+, quello spazio sottinteso copre l’intera ripetizione — separatori compresi — quindi vengono analizzati sia'3+4+5'sia'3 + 4 + 5', e la somma è12in entrambi i casi. (Se preferisci restare con untoken, scrivi per esteso gli spazi nel separatore:<number>+ % [ \s* '+' \s* ].)