Raku modules can be specified in different ways, for example:
MyModule
MyModule:ver<1.0.3>
MyModule:ver<1.0.3>:auth<Name ([email protected])>;
MyModule:ver<1.0.3>:auth<Name <[email protected]>>;
I wrote the below grammar
to parse the module spec which works fine for most of specs but it fails if the auth
field contains <
or >
. How can I fix the grammar to match in this case as well?
I can't figure out how to say match everything in between <
and >
including any <
and >
as well.
#!/usr/bin/env perl6
grammar Spec {
token TOP { <spec> }
token spec { <name> <keyval>* }
token name { [<-[./:<>()\h]>+]+ % '::' }
token keyval { ':' <key> <value> }
proto token key { * }
token key:sym<ver> { <sym> }
token key:sym<version> { <sym> }
token key:sym<auth> { <sym> }
token key:sym<api> { <sym> }
token key:sym<from> { <sym> }
# BUG: fix specs that contains '<>' inside value;
token value { '<' ~ '>' $<val>=<-[<>]>* | '(' ~ ')' $<val>=<-[()]>* }
}
my \tests = (
'MyModule:ver<1.0.3>:auth<Name ([email protected])>',
'MyModule:ver<1.0.3>:auth<Name <[email protected]>>',
);
for tests -> \spec {
say so Spec.parse: spec;
}
# Output:
True
False
If you know that the inner field will basically be in the same format as the value token, you can recursively match for value with $<val>=[.*? <value>?]
. This even lets you capture the contents of the inner field seperately:
token value { '<' ~ '>' $<val>=[.*? <value>?] | '(' ~ ')' $<val>=<-[()]>* }
If you don't want the inner contents than you can use the recursive <~~>
in place of <value>
token value { '<' ~ '>' $<val>=[.*? <~~>?] | '(' ~ ')' $<val>=<-[()]>* }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With