Jump to content

Parsing/Shunting-yard algorithm: Difference between revisions

m
→‎{{header|Raku}}: Undo bizarre single space indent that somebody found necessary to do
m (syntax highlighting fixup automation)
m (→‎{{header|Raku}}: Undo bizarre single space indent that somebody found necessary to do)
Line 4,087:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line> my %prec =
'(^' => 1;4,
my %prec =
'^*' => 43,
'*/' => 3,
'/+' => 32,
'+-' => 2,
'-(' => 2,1;
 
'(' => 1;
my %precassoc =
'-^' => 'leftright';,
my %assoc =
'^*' => 'rightleft',
'*/' => 'left',
'/+' => 'left',
'+-' => 'left',;
 
'-' => 'left';
sub shunting-yard ($prog) {
my @inp = $prog.words;
sub shunting-yard ($prog) {
my @inp = $prog.wordsops;
my @opsres;
 
my @res;
sub report($op) { printf "%25s %-7s %10s %s\n", ~@res, ~@ops, $op, ~@inp }
sub reportshift($opt) { printfreport( "%25sshift %-7s %10s %s\n$t",); ~@res, ~@ops,.push: $op, ~@inpt }
sub shiftreduce($t) { report( "shiftreduce $t"); @opsres.push: $t }
 
sub reduce($t) { report("reduce $t"); @res.push: $t }
while @inp {
while given @inp.shift {
given @inp.shiftwhen /\d/ { reduce $_ };
when /\d/'(' { reduceshift $_ };
when ')' { while @ops and (my $x = @ops.pop and $x ne '(') { shiftreduce $_x } }
default {
when ')' { while @ops and (my $x = @ops.pop and $x ne '(') { reduce $x } }
default my $newprec = %prec{$_};
my $newprecwhile =@ops %prec{$_};
while @ops my $oldprec = %prec{@ops[*-1]};
last myif $oldprecnewprec => %prec{@ops[*-1]}$oldprec;
last if $newprec >== $oldprec and %assoc{$_} eq 'right';
reduce last if $newprec == $oldprec and %assoc{$_} eq 'right'@ops.pop;
reduce @ops.pop;}
shift }$_;
shift $_;}
}
}
reduce @ops.pop while @ops;
}
my @res;
reduce @ops.pop while @ops;
}
@res;
 
}
say shunting-yard '3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3';</syntaxhighlight>
say shunting-yard '3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3';
</syntaxhighlight>
{{out}}
<pre> reduce 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
10,333

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.