Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- $ops = ['^' => ['assoc' => 1,
- 'prio' => 3,
- 'function' => function($b, $a) { return pow($a, $b); }],
- '*' => ['assoc' => 0,
- 'prio' => 2,
- 'function' => function($b, $a) { return $a * $b; }],
- '/' => ['assoc' => 0,
- 'prio' => 2,
- 'function' => function($b, $a) { return $a / $b; }],
- '+' => ['assoc' => 0,
- 'prio' => 1,
- 'function' => function($b, $a) { return $a + $b; }],
- '-' => ['assoc' => 0,
- 'prio' => 1,
- 'function' => function($b, $a) { return $a - $b; }]];
- function shunting_yard($xs)
- {
- global $ops;
- $numbers = range(0, 9);
- $stack = [];
- $out = [];
- //Läs in alla tecken från streamen
- foreach ($xs as $x) {
- // Casta om $x till en (int) om det är en int (string)
- $x = is_numeric($x) ? intval($x) : $x;
- //Nummer? Pusha till utdatan
- if(in_array($x, $numbers, true)) {
- array_push($out, $x);
- }
- //Operator?
- elseif(in_array($x, array_keys($ops), true))
- {
- //Finns det någon operator i stacken?
- if(count($stack) AND in_array(end($stack), array_keys($ops), true)) {
- // Har $x lägre eller samma prioritet som sista operatorn på stacken?
- // OCH är $x vänster associativ / associativ.
- if( ($ops[$x]['prio'] <= $ops[end($stack)]['prio']
- AND
- $ops[$x]['assoc'] < 1)
- // ELLER
- // Är $x höger associativ (tex ^) OCH har $x lägre prio än operatorn på stacken?
- OR
- ($ops[$x]['assoc'] === 1
- AND
- $ops[$x]['prio'] < $ops[end($stack)]['prio']))
- {
- array_push($out, array_pop($stack));
- }
- }
- array_push($stack, $x);
- }
- elseif($x == '(') {
- array_push($stack, $x);
- }
- //
- elseif($x == ')') {
- while( ($y = array_pop($stack)) != '(' )
- array_push($out, $y);
- }
- }
- while(count($stack) > 0)
- array_push($out, array_pop($stack));
- return $out;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement