Skip to content

Instantly share code, notes, and snippets.

@VienosNotes
Last active January 3, 2016 03:39
Show Gist options
  • Select an option

  • Save VienosNotes/8403725 to your computer and use it in GitHub Desktop.

Select an option

Save VienosNotes/8403725 to your computer and use it in GitHub Desktop.
use v6;
grammar Expression {
rule num { \d+ }
rule qexp { '(' <exp> ')' }
rule atom { <exp2> || <num> || <qexp> }
rule ops { <.ws><ops1><.ws> || <.ws><ops2><.ws> }
token ops1 { '+'|'-' }
token ops2{ '*'|'/' }
rule exp { <atom>+ % <ops> }
rule exp2 { <head> <.ws> <ops2> <.ws> <atom> }
rule head { <num> || <qexp> }
rule TOP { <.ws><exp><.ws> }
}
class Operations {
method num ($/) { make $/.Int }
method qexp ($/) { make $<exp>.ast }
method atom ($/) { make $/.values[0].ast }
method ops ($/) { make $/.values[0].ast; }
method ops1 ($/) { make $/.Str; }
method ops2 ($/) { make $/.Str; }
method head ($/) { make $/.values[0].ast; }
method exp2 ($/) {
given ($<ops2>.ast) {
when '*' {
make $<head>.ast * $<atom>.ast;
}
when '/' {
make $<head>.ast / $<atom>.ast;
}
}
}
method exp ($/) {
my $acc = $<atom>[0].ast;
for ($<ops>>>.ast Z $<atom>[1..^$<atom>.elems]>>.ast) -> $op, $num {
given ($op) {
when '+' {
$acc += $num;
}
when '-' {
$acc -= $num;
}
}
}
make $acc;
}
method TOP ($/) { make $<exp>.ast }
}
my $exp = "12*(3+3)/4-10";
my $a = Expression.parse($exp, actions => Operations);
say $a;
say $a.ast;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment