/** 
  * Tokenize a soap type
  *
  * @param string $type  Type
  *
  * @return array         Tokens
  */
 public static function tokenize($type)
 {
     $stack = new Stack();
     $stack->push(SOAP_STATE_DEFAULT);
     $stack->push(SOAP_STATE_TYPE);
     $tokens = array();
     $token = '';
     $len = strlen($type);
     // We don't actually care whether we're inside of a type or not
     // That's why there aren't separate states for inside and outside of braces
     for ($pos = 0; $pos < $len; ++$pos) {
         $char = $type[$pos];
         $nextChar = isset($type[$pos + 1]) ? $type[$pos + 1] : null;
         switch ($stack->top()) {
             case SOAP_STATE_DEFAULT:
                 if (ctype_alnum($nextChar)) {
                     $stack->push(SOAP_STATE_TYPE);
                 } elseif (in_array($char, self::$whitespace)) {
                     $tokens[] = array('code' => SOAP_WHITESPACE, 'token' => $char);
                 } elseif ($char === '{') {
                     $tokens[] = array('code' => SOAP_OPEN_BRACE, 'token' => $char);
                 } elseif ($char === '}') {
                     $tokens[] = array('code' => SOAP_CLOSE_BRACE, 'token' => $char);
                 } elseif ($char === ';') {
                     $tokens[] = array('code' => SOAP_SEMICOLON, 'token' => $char);
                 }
                 break;
             case SOAP_STATE_TYPE:
                 if (ctype_alnum($char)) {
                     $token .= $char;
                     if ($nextChar === ' ') {
                         if (in_array($token, self::$nativeTypes)) {
                             $tokens[] = array('code' => SOAP_NATIVE_TYPE, 'token' => $token);
                         } else {
                             $tokens[] = array('code' => SOAP_USER_TYPE, 'token' => $token);
                         }
                         $token = '';
                         $stack->pop();
                         $stack->push(SOAP_STATE_PROPERTY);
                     }
                 }
                 break;
             case SOAP_STATE_PROPERTY:
                 if (ctype_alnum($char)) {
                     $token .= $char;
                     if ($nextChar === ';' || $nextChar === ' ' || $nextChar === null) {
                         $tokens[] = array('code' => SOAP_PROPERTY, 'token' => $token);
                         $token = '';
                         $stack->pop();
                     }
                 } elseif ($char === ' ') {
                     $tokens[] = array('code' => SOAP_WHITESPACE, 'token' => $char);
                 }
                 break;
         }
     }
     return $tokens;
 }
Exemplo n.º 2
0
function get_polish_notation($expression)
{
    $current_op_stack = new Stack();
    $outstring = '';
    for ($i = 0; $i < strlen($expression); $i++) {
        if ($expression[$i] == ')') {
            while ($current_op_stack->top() != '(') {
                $outstring .= $current_op_stack->pop();
            }
            $current_op_stack->pop();
        }
        if ($expression[$i] == '(') {
            $current_op_stack->push($expression[$i]);
        }
        if ($expression[$i] == '-' or $expression[$i] == '+' or $expression[$i] == '*' or $expression[$i] == '/' or $expression[$i] == '^') {
            if ($current_op_stack->is_empty()) {
                $current_op_stack->push($expression[$i]);
            } elseif (spot_priority($expression[$i]) > spot_priority($current_op_stack->top())) {
                $current_op_stack->push($expression[$i]);
            } else {
                while (!$current_op_stack->is_empty() and spot_priority($current_op_stack->top()) >= spot_priority($expression[$i])) {
                    $outstring .= $current_op_stack->pop();
                }
                $current_op_stack->push($expression[$i]);
            }
        }
        if (is_numeric($expression[$i])) {
            $outstring .= '.';
            do {
                $outstring .= $expression[$i];
            } while (is_numeric($expression[++$i]));
            --$i;
        }
    }
    while (!$current_op_stack->is_empty()) {
        $outstring .= $current_op_stack->pop();
    }
    return $outstring;
}
Exemplo n.º 3
0
 /**
  * Vrátí aktuální blok
  *
  * @returns Block
  */
 protected function getActualBlock()
 {
     return $this->stack->top();
 }
Exemplo n.º 4
0
 /**
  * Vyhodnocení výrazu
  *
  * @param array
  * @return array
  */
 protected function evaluateExpression(array $expr)
 {
     if ($expr[0] != 'expression') {
         return $this->reduceValue($expr);
     }
     array_shift($expr);
     //převod výrazu do postfixové notace
     $postfix = array();
     $stack = new Stack();
     foreach ($expr as $symbol) {
         if ($symbol == '(') {
             $stack->push($symbol);
         } elseif ($symbol == ')') {
             while ($top = $stack->pop()) {
                 if ($top == '(') {
                     break;
                 }
                 $postfix[] = $top;
             }
             $top = $stack->top();
             if ($top[0] == 'unary' && array_key_exists($top[1], Compiler::$unaryOperators)) {
                 $postfix[] = $stack->pop();
             }
         } elseif ($symbol[0] == 'binary' && array_key_exists($symbol[1], Compiler::$binaryOperators)) {
             if ($stack->count() == 0) {
                 $stack->push($symbol);
                 continue;
             }
             $top = $stack->top();
             while ($top != '(' && $stack->count() > 0 && $top[0] == 'binary' && Compiler::$binaryOperators[$symbol[1]] <= Compiler::$binaryOperators[$top[1]]) {
                 $postfix[] = $stack->pop();
                 $top = $stack->top();
             }
             $stack->push($symbol);
         } elseif ($symbol[0] == 'unary' && array_key_exists($symbol[1], Compiler::$unaryOperators)) {
             $stack->push($symbol);
         } else {
             $postfix[] = $this->reduceValue($symbol);
             $top = $stack->top();
             if ($top[0] == 'unary' && array_key_exists($top[1], Compiler::$unaryOperators)) {
                 $postfix[] = $stack->pop();
             }
         }
     }
     while ($stack->count() > 0) {
         $postfix[] = $stack->pop();
     }
     //vyhodnocení výrazu
     $stack->clear();
     foreach ($postfix as $symbol) {
         if ($symbol[0] == 'unary' && array_key_exists($symbol[1], Compiler::$unaryOperators)) {
             if ($stack->count() < 1) {
                 throw new CompileException("Nedostatek operandů pro unární operátor '{$symbol['1']}'");
             }
             $symbol = $this->evaluateUnaryOperation($symbol[1], $stack->pop());
         } elseif ($symbol[0] == 'binary' && array_key_exists($symbol[1], Compiler::$binaryOperators)) {
             if ($stack->count() < 2) {
                 throw new CompileException("Nedostatek operandů pro binární operátor '{$symbol['1']}'");
             }
             $value2 = $stack->pop();
             $symbol = $this->evaluateBinaryOperation($symbol[1], $stack->pop(), $value2);
         }
         $stack->push($symbol);
     }
     if ($stack->count() != 1) {
         throw new CompileException("Výsledkem výrazu má být pouze 1 hodnota");
     }
     return $stack->pop();
 }
Exemplo n.º 5
0
 public function run()
 {
     $this->variables = [];
     $token = $this->scanner->next(TRUE);
     $stack = new Stack();
     $stack->push('$');
     do {
         $a = $stack->topTerminal();
         try {
             switch ($this->getFromTable($a, $token)) {
                 case '=':
                     debug::printString(debug::TYPE_PRECEDENCE, "= so push token");
                     $stack->push($token);
                     $token = $this->scanner->next(TRUE);
                     break;
                 case '<':
                     debug::printString(debug::TYPE_PRECEDENCE, "< so push < and token");
                     $stack->pushTerminal('<');
                     $stack->push($token);
                     $token = $this->scanner->next(TRUE);
                     break;
                 case '>':
                     // Hledáme pravidlo!
                     $found = FALSE;
                     foreach ($this->rules as $key => $rule) {
                         $error = FALSE;
                         for ($i = 0; $i < count($rule['source']); $i++) {
                             $tmp = $stack->top($i);
                             if (is_array($tmp) && !isset($tmp['nonTerminal'])) {
                                 $tmp = $this->normalizeCodes($tmp);
                             }
                             if (is_array($tmp) && $tmp['nonTerminal'] != $rule['source'][count($rule['source']) - 1 - $i] || !is_array($tmp) && $tmp != $rule['source'][count($rule['source']) - 1 - $i]) {
                                 $error = TRUE;
                                 $i = count($rule['source']);
                             }
                         }
                         $error = $error || $stack->top(count($rule['source'])) != '<';
                         if (!$error) {
                             $result = [];
                             foreach ($rule['source'] as $unused) {
                                 $result[] = $stack->pop();
                             }
                             $stack->pop();
                             $stack->push(['nonTerminal' => $rule['target'], 'terminals' => $result]);
                             $found = TRUE;
                             break;
                         }
                     }
                     if (!$found) {
                         $stack->debug();
                         throw new PrecedenceException("Error - rule not found! " . print_r($token, TRUE) . " " . print_r($a, TRUE));
                     } else {
                         debug::printString(debug::TYPE_PRECEDENCE, "rule: " . $key . " " . $rule['target'] . " -> " . implode(' ', $rule['source']));
                     }
                     break;
                 case '#':
                     if ($a == '$' && in_array($token['code'], $this->stopTokens)) {
                         $this->scanner->back();
                         $token = ['code' => T_SEMICOLON, 'value' => ';'];
                     } else {
                         throw new PrecedenceException(print_r($a, TRUE) . print_r($token, TRUE));
                     }
                     break;
                 default:
                     die("Chyba v precedenční tabulce");
             }
             // This solve function calls with any argument number
             try {
                 $e1 = $stack->top();
                 $comma = $stack->top(1);
                 $e2 = $stack->top(2);
                 if (isset($e1['nonTerminal']) && $e1['nonTerminal'] == 'E' && isset($comma['code']) && $comma['code'] == T_COMMA && isset($e2['nonTerminal']) && $e2['nonTerminal'] == 'E') {
                     $stack->pop();
                     $stack->pop();
                     $stack->pop();
                     $stack->push(['nonTerminal' => 'E', 'terminals' => [$e1, $comma, $e2]]);
                     $stack->debug();
                     echo "\n";
                 }
             } catch (StackEmptyException $e) {
             }
         } catch (PrecedenceNotInTableException $e) {
             $this->scanner->back();
             $token = ['code' => T_SEMICOLON, 'value' => ';'];
         }
         debug::printStack(debug::TYPE_PRECEDENCE, $stack);
     } while ($this->normalizeCodes($token) != '$' || $stack->topTerminal() != '$');
     $this->result = $stack->top();
 }
     * @param mixed $el Element to be pushed.
     * @return void.
     */
    public function push($el)
    {
        array_push($this->_data, $el);
    }
    /**
     * Pop the top element of the stack.
     *
     * @return mixed $element.
     */
    public function pop()
    {
        if ($this->top() !== null) {
            return array_pop($this->_data);
        }
        return null;
    }
}
// Example usage:
$stack = new Stack();
$stack->push("Element");
$stack->push(23);
$stack->push(array(3, 4, 6));
while (!$stack->is_empty()) {
    var_dump($stack->top());
    $stack->pop();
}
// Outputs NULL
var_dump($stack->top());