Advertisement
Guest User

shunting_yard

a guest
Jul 23rd, 2014
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 1.89 KB | None | 0 0
  1. $ops = ['^' => ['assoc'    => 1,
  2.                 'prio'     => 3,
  3.                 'function' => function($b, $a) { return pow($a, $b); }],
  4.  
  5.         '*' => ['assoc'    => 0,
  6.                 'prio'     => 2,
  7.                 'function' => function($b, $a) { return $a * $b; }],
  8.            
  9.         '/' => ['assoc'    => 0,
  10.                 'prio'     => 2,
  11.                 'function' => function($b, $a) { return $a / $b; }],
  12.  
  13.         '+' => ['assoc'    => 0,
  14.                 'prio'     => 1,
  15.                 'function' => function($b, $a) { return $a + $b; }],
  16.  
  17.         '-' => ['assoc'    => 0,
  18.                 'prio'     => 1,
  19.                 'function' => function($b, $a) { return $a - $b; }]];
  20.  
  21. function shunting_yard($xs)
  22. {
  23.     global $ops;
  24.  
  25.     $numbers = range(0, 9);
  26.     $stack   = [];
  27.     $out     = [];
  28.  
  29.     //Läs in alla tecken från streamen
  30.     foreach ($xs as $x) {
  31.         // Casta om $x till en (int) om det är en int (string)
  32.         $x = is_numeric($x) ? intval($x) : $x;
  33.  
  34.         //Nummer? Pusha till utdatan
  35.         if(in_array($x, $numbers, true)) {
  36.             array_push($out, $x);
  37.         }
  38.         //Operator?
  39.         elseif(in_array($x, array_keys($ops), true))
  40.         {
  41.             //Finns det någon operator i stacken?
  42.             if(count($stack) AND in_array(end($stack), array_keys($ops), true)) {
  43.                 // Har $x lägre eller samma prioritet som sista operatorn på stacken?
  44.                 // OCH är $x vänster associativ / associativ.
  45.                 if(     ($ops[$x]['prio'] <= $ops[end($stack)]['prio']
  46.                         AND
  47.                         $ops[$x]['assoc'] < 1)
  48.  
  49.                     // ELLER
  50.                     // Är $x höger associativ (tex ^) OCH har $x lägre prio än operatorn på stacken?
  51.                     OR
  52.                         ($ops[$x]['assoc'] === 1
  53.                         AND
  54.                         $ops[$x]['prio'] < $ops[end($stack)]['prio']))
  55.                 {
  56.                     array_push($out, array_pop($stack));
  57.                 }
  58.             }
  59.  
  60.             array_push($stack, $x);
  61.         }
  62.         elseif($x == '(') {
  63.             array_push($stack, $x);
  64.         }
  65.         //
  66.         elseif($x == ')') {
  67.             while( ($y =  array_pop($stack)) != '(' )
  68.                 array_push($out, $y);
  69.         }
  70.     }
  71.  
  72.     while(count($stack) > 0)
  73.         array_push($out, array_pop($stack));
  74.  
  75.     return $out;
  76. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement