# Pastebin rIp1MKmx #https://chatgpt.com/share/699499e6-1064-8009-9651-d55d5eb5bfb5 my $input = q:to/END/; invoice "INV-001" for "ACME Corp" item "Hosting" 100 x 3 item "Support" 50 x 2 tax 20% invoice "INV-002" for "Globex" item "Consulting" 200 x 5 discount 10% tax 21% END #use Grammar::Tracer; grammar InvoiceDSL { token TOP { ^ + % \n* $ } token invoice {
\n + } token header { 'invoice' \h+ \h+ 'for' \h+ } token line { \h**4 \n? } token entry { | | | } token item { 'item' \h+ \h+ \h+ 'x' \h+ } token tax { 'tax' \h+ '%' } token discount { 'discount' \h+ '%' } token string { \" <( <-["]>* )> \" } token num { \d+ [ '.' \d+ ]? } token int { \d+ } } class InvoiceActions { method TOP($/) { make $».made; } method invoice($/) { my %invoice = ( id => ~$
, client => ~$
, items => [], tax => 0, discount => 0, ); for $».made -> $entry { given $entry { when 'item' { %invoice.push($entry) } when 'tax' { %invoice = $entry } when 'discount' { %invoice = $entry } } } make %invoice; } method item($/) { make { type => 'item', data => { desc => ~$, price => +$, qty => +$, } }; } method tax($/) { make { type => 'tax', data => +$ }; } method discount($/) { make { type => 'discount', data => +$ }; } method line($/) { make $.made; } } my $res = InvoiceDSL.parse($input, :actions(InvoiceActions)); say $res[0]
; say $res[0][0] * 1.1; repl;