Formal grammar made up of named regexes
Every type declared with
grammar, and not explicitly stating its superclass, becomes a subclass of Grammar.
say Identifier.isa(Grammar); # OUTPUT: «True␤»my = Identifier.parse('W4anD0eR96');say ~; # OUTPUT: «W4anD0eR96␤»
More documentation on grammars is available.
method parse(, : = 'TOP', Capture() : = \(), Mu : = Mu, *)
$target, which will be coerced to Str if it isn't one, using
$rule as the starting rule. Additional
$args will be passed to the starting rule if provided.
say RepeatChar.parse('aaaaaa', :rule('start'), :args(\('a')));say RepeatChar.parse('bbbbbb', :rule('start'), :args(\('b')));# OUTPUT:# ｢aaaaaa｣# ｢bbbbbb｣
actions named argument is provided, it will be used as an actions object, that is, for each successful regex match, a method of the same name, if it exists, is called on the actions object, passing the match object as the sole positional argument.
my = class ;grammar .parse('ab', :);# OUTPUT: «42␤7␤»
Additional named arguments are used as options for matching, so you can for example specify things like
:pos(4) to start parsing from the fifth (:pos is zero-based) character. All matching adverbs are allowed, but not all of them take effect. There are several types of adverbs that a regex can have, some of which apply at compile time, like
:i. You cannot pass those to
.parse, because the regexes have already been compiled. But, you can pass those adverbs that affect the runtime behavior, such as
say RepeatChar.parse('bbbbbb', :rule('start'), :args(\('b')), :pos(4)).Str;# OUTPUT: «bb␤»
parse only succeeds if the cursor has arrived at the end of the target string when the match is over. Use method subparse if you want to be able to stop in the middle.
The top regex in the grammar will be allowed to backtrack.
Returns a Match object on success, and Nil on failure.
method subparse(, : = 'TOP', Capture() : = \(), Mu : = Mu, *)
Does exactly the same as method parse, except that cursor doesn't have to reach the end of the string to succeed. That is, it doesn't have to match the whole string.
Note that unlike method parse,
subparse always returns a Match object object, which will be a failed match (and thus falsy), if the grammar failed to match.
say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('b')));say RepeatChar.parse( 'bbbabb', :rule('start'), :args(\('b')));say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('a')));say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('a')), :pos(3));# OUTPUT:# ｢bbb｣# Nil# #<failed match># ｢a｣
method parsefile(Str(Cool) , :, *)
$filename encoding by
$enc, and parses it. All named arguments are passed on to method parse.
say Identifiers.parsefile('users.txt', :enc('UTF-8')).Str.trim.subst(/\n/, ',', :g);# users.txt :# TimToady# lizmat# jnthn# moritz# zoffixznet# MasterDuke17# OUTPUT: «TimToady,lizmat,jnthn,moritz,zoffixznet,MasterDuke17␤»