Skip to content

Instantly share code, notes, and snippets.

@2colours
Created February 16, 2023 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 2colours/f2148c63138e55ac8477dd023d12c587 to your computer and use it in GitHub Desktop.
Save 2colours/f2148c63138e55ac8477dd023d12c587 to your computer and use it in GitHub Desktop.
#!/usr/bin/env raku
use Test;
grammar Command {
token TOP { [<option>+ % \s \s]? <command> }
token command { 'command' }
token option { <option-a> | <option-b> }
token option-a { 'a' }
token option-b { 'b' | 'b' \s <val> }
token val { <-option> }
token anything-but-space { <-[ \s ]>+ }
}
class Actions {
method TOP ( $/ ) {
my %h;
%h<command> = ~$<command>;
%h<options> = $<option>».made.hash;
make %h;
}
method option ( $/ ) { make $<option-a> ?? $<option-a>.made !! $<option-b>.made }
method option-a ( $/ ) { make ( :a ) }
method option-b ( $/ ) { make ( $<val> ?? b => ~$<val> !! :b ) }
}
my @test = (
'command' => ${:command("command"), :options({})},
'a command' => ${:command("command"), :options(${:a})},
'b command' => ${:command("command"), :options(${:b})},
'a b command' => ${:command("command"), :options(${:a, :b})},
'b a command' => ${:command("command"), :options(${:a, :b})},
'b val command' => ${:command("command"), :options(${:b("val")})}, # this one fails probably because <val> matches anything
);
for @test {
my $cmd = .key;
my $expected = .value;
my $parser = Command;
my $actions = Actions;
my $got = $parser.parse( $cmd, :$actions ).made;
is-deeply $got, $expected, $cmd;
}
done-testing;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment