src/Converter.php
protected function doConvert() {
		$expectOperator = true;

		// Iterate through all tokens, saving the operators and operands to a
		// stack per Dijkstra's shunting yard algorithm.
		/** @var Operator $token */
		while ( false !== ( $token = $this->nextToken() ) ) {
			// In this grammar, there are only binary operators, so every valid
			// rule string will alternate between operator and operand tokens.
			$expectOperator = !$expectOperator;

			if ( $token instanceof Expression ) {
				// Operand
				if ( $expectOperator ) {
					$token->error( 'unexpected operand' );
				}
				$this->operands[] = $token;
				continue;
			} else {
				// Operator
				if ( !$expectOperator ) {
					$token->error( 'unexpected operator' );
				}
				// Resolve higher precedence levels
				$lastOp = end( $this->operators );
				while ( $lastOp && self::$precedence[$token->name] <= self::$precedence[$lastOp->name] ) {
					$this->doOperation( $lastOp );
					array_pop( $this->operators );
					$lastOp = end( $this->operators );
				}
				$this->operators[] = $token;
			}
		}

		// Finish off the stack
		while ( $op = array_pop( $this->operators ) ) {
			$this->doOperation( $op );
		}

		// Make sure the result is sane. The first case is possible for an empty
		// string input, the second should be unreachable.
		if ( !count( $this->operands ) ) {
			$this->error( 'condition expected' );
		} elseif ( count( $this->operands ) > 1 ) {
			$this->error( 'missing operator or too many operands' );
		}

		$value = $this->operands[0];
		if ( $value->type !== 'boolean' ) {
			$this->error( 'the result must have a boolean type' );
		}

		return $this->operands[0]->rpn;
	}
protected function doConvert() {
		$expectOperator = true;

		// Iterate through all tokens, saving the operators and operands to a
		// stack per Dijkstra's shunting yard algorithm.
		/** @var Operator $token */
		while ( false !== ( $token = $this->nextToken() ) ) {
			// In this grammar, there are only binary operators, so every valid
			// rule string will alternate between operator and operand tokens.
			$expectOperator = !$expectOperator;

			if ( $token instanceof Expression ) {
				// Operand
				if ( $expectOperator ) {
					$token->error( 'unexpected operand' );
				}
				$this->operands[] = $token;
				continue;
			} else {
				// Operator
				if ( !$expectOperator ) {
					$token->error( 'unexpected operator' );
				}
				// Resolve higher precedence levels
				$lastOp = end( $this->operators );
				while ( $lastOp && self::$precedence[$token->name] <= self::$precedence[$lastOp->name] ) {
					$this->doOperation( $lastOp );
					array_pop( $this->operators );
					$lastOp = end( $this->operators );
				}
				$this->operators[] = $token;
			}
		}

		// Finish off the stack
		while ( $op = array_pop( $this->operators ) ) {
			$this->doOperation( $op );
		}

		// Make sure the result is sane. The first case is possible for an empty
		// string input, the second should be unreachable.
		if ( !count( $this->operands ) ) {
			$this->error( 'condition expected' );
		} elseif ( count( $this->operands ) > 1 ) {
			$this->error( 'missing operator or too many operands' );
		}

		$value = $this->operands[0];
		if ( $value->type !== 'boolean' ) {
			$this->error( 'the result must have a boolean type' );
		}

		return $this->operands[0]->rpn;
	}
protected function doConvert ( ) { $ expectOperator = true ; // Iterate through all tokens, saving the operators and operands to a // stack per Dijkstra's shunting yard algorithm. /** @var Operator $token */ while ( false !== ( $ token = $ this -> nextToken ( ) ) ) { // In this grammar, there are only binary operators, so every valid // rule string will alternate between operator and operand tokens. $ expectOperator = ! $ expectOperator ; if ( $ token instanceof Expression ) { // Operand if ( $ expectOperator ) { $ token -> error ( 'unexpected operand' ) ; } $ this -> operands [ ] = $ token ; continue ; } else { // Operator if ( ! $ expectOperator ) { $ token -> error ( 'unexpected operator' ) ; } // Resolve higher precedence levels $ lastOp = end ( $ this -> operators ) ; while ( $ lastOp && self :: $ precedence [ $ token -> name ] <= self :: $ precedence [ $ lastOp -> name ] ) { $ this -> doOperation ( $ lastOp ) ; array_pop ( $ this -> operators ) ; $ lastOp = end ( $ this -> operators ) ; } $ this -> operators [ ] = $ token ; } } // Finish off the stack while ( $ op = array_pop ( $ this -> operators ) ) { $ this -> doOperation ( $ op ) ; } // Make sure the result is sane. The first case is possible for an empty // string input, the second should be unreachable. if ( ! count ( $ this -> operands ) ) { $ this -> error ( 'condition expected' ) ; } elseif ( count ( $ this -> operands ) > 1 ) { $ this -> error ( 'missing operator or too many operands' ) ; } $ value = $ this -> operands [ 0 ] ; if ( $ value -> type !== 'boolean' ) { $ this -> error ( 'the result must have a boolean type' ) ; } return $ this -> operands [ 0 ] -> rpn ; }
Do the operation.

@return string The RPN representation of the rule (e.g. "5 3 mod n is")
Do the operation .