{"body":"#https://chatgpt.com/share/699499e6-1064-8009-9651-d55d5eb5bfb5\n\nmy $input = q:to/END/;\ninvoice \"INV-001\" for \"ACME Corp\"\n    item \"Hosting\" 100 x 3\n    item \"Support\" 50 x 2\n    tax 20%\ninvoice \"INV-002\" for \"Globex\"\n    item \"Consulting\" 200 x 5\n    discount 10%\n    tax 21%\nEND\n\n#use Grammar::Tracer;\n\ngrammar InvoiceDSL {\n\n    token TOP {\n        ^ <invoice>+ % \\n* $\n    }\n\n    token invoice {\n        <header>\n        \\n\n        <line>+\n    }\n\n    token header {\n        'invoice' \\h+ <id=string> \\h+ 'for' \\h+ <client=string>\n    }\n\n    token line {\n        \\h**4 <entry> \\n?\n    }\n\n    token entry {\n        | <item>\n        | <tax>\n        | <discount>\n    }\n\n    token item {\n        'item' \\h+ <desc=string> \\h+ <price=num> \\h+ 'x' \\h+ <qty=int>\n    }\n\n    token tax {\n        'tax' \\h+ <percent=num> '%'\n    }\n\n    token discount {\n        'discount' \\h+ <percent=num> '%'\n    }\n\n    token string { \\\" <( <-[\"]>* )> \\\" }\n    token num    { \\d+ [ '.' \\d+ ]? }\n    token int    { \\d+ }\n}\n\nclass InvoiceActions {\n\n    method TOP($/) {\n        make $<invoice>».made;\n    }\n\n    method invoice($/) {\n        my %invoice = (\n            id     => ~$<header><id>,\n            client => ~$<header><client>,\n            items  => [],\n            tax    => 0,\n            discount => 0,\n        );\n\n        for $<line>».made -> $entry {\n            given $entry<type> {\n                when 'item'     { %invoice<items>.push($entry<data>) }\n                when 'tax'      { %invoice<tax> = $entry<data> }\n                when 'discount' { %invoice<discount> = $entry<data> }\n            }\n        }\n\n        make %invoice;\n    }\n\n    method item($/) {\n        make {\n            type => 'item',\n            data => {\n                desc  => ~$<desc>,\n                price => +$<price>,\n                qty   => +$<qty>,\n            }\n        };\n    }\n\n    method tax($/) {\n        make { type => 'tax', data => +$<percent> };\n    }\n\n    method discount($/) {\n        make { type => 'discount', data => +$<percent> };\n    }\n\n    method line($/) {\n        make $<entry>.made;\n    }\n}\n\nmy $res = InvoiceDSL.parse($input, :actions(InvoiceActions));\n\nsay $res<invoice>[0]<header><client>;\nsay $res<invoice>[0]<line>[0]<entry><item><price> * 1.1;\n\n\nrepl;\n\n","name":"","extension":"txt","url":"https://www.irccloud.com/pastebin/rIp1MKmx","modified":1777302389,"id":"rIp1MKmx","size":2257,"lines":116,"own_paste":false,"theme":"","date":1777302389}