public function readExpression(array $breaks = null, array $brackets = null)
    {
        if (!$this->hasLength()) {
            return;
        }

        $breaks = $breaks ?: [];
        $brackets = $brackets ?: $this->expressionBrackets;
        $expression = '';
        $char = null;
        $bracketStack = [];
        while ($this->hasLength()) {
            //Append a string if any was found
            //Notice there can be brackets in strings, we dont want to
            //count those
            $expression .= $this->readString(null, true);

            if (!$this->hasLength()) {
                break;
            }

            //Check for breaks
            if (count($bracketStack) === 0) {
                foreach ($breaks as $break) {
                    if ($this->peekString($break)) {
                        break 2;
                    }
                }
            }

            //Count brackets
            $char = $this->peek();
            if (in_array($char, array_keys($brackets), true)) {
                $bracketStack[] = $char;
            } elseif (in_array($char, array_values($brackets), true)) {
                if (count($bracketStack) < 1) {
                    $this->throwException(
                        "Unexpected bracket $char encountered, no brackets open"
                    );
                }

                $last = count($bracketStack) - 1;
                if ($char !== $brackets[$bracketStack[$last]]) {
                    $this->throwException(
                        "Unclosed bracket {$bracketStack[$last]} encountered, "
                        ."got $char instead"
                    );
                }

                array_pop($bracketStack);
            }

            $expression .= $char;
            $this->consume();
        }

        if (count($bracketStack) > 0) {
            $this->throwException(
                'Unclosed brackets '.implode(', ', $bracketStack).' encountered '
                .'at end of expression'
            );
        }

        return trim($expression);
    }
public function readExpression(array $breaks = null, array $brackets = null)
    {
        if (!$this->hasLength()) {
            return;
        }

        $breaks = $breaks ?: [];
        $brackets = $brackets ?: $this->expressionBrackets;
        $expression = '';
        $char = null;
        $bracketStack = [];
        while ($this->hasLength()) {
            //Append a string if any was found
            //Notice there can be brackets in strings, we dont want to
            //count those
            $expression .= $this->readString(null, true);

            if (!$this->hasLength()) {
                break;
            }

            //Check for breaks
            if (count($bracketStack) === 0) {
                foreach ($breaks as $break) {
                    if ($this->peekString($break)) {
                        break 2;
                    }
                }
            }

            //Count brackets
            $char = $this->peek();
            if (in_array($char, array_keys($brackets), true)) {
                $bracketStack[] = $char;
            } elseif (in_array($char, array_values($brackets), true)) {
                if (count($bracketStack) < 1) {
                    $this->throwException(
                        "Unexpected bracket $char encountered, no brackets open"
                    );
                }

                $last = count($bracketStack) - 1;
                if ($char !== $brackets[$bracketStack[$last]]) {
                    $this->throwException(
                        "Unclosed bracket {$bracketStack[$last]} encountered, "
                        ."got $char instead"
                    );
                }

                array_pop($bracketStack);
            }

            $expression .= $char;
            $this->consume();
        }

        if (count($bracketStack) > 0) {
            $this->throwException(
                'Unclosed brackets '.implode(', ', $bracketStack).' encountered '
                .'at end of expression'
            );
        }

        return trim($expression);
    }
public function readExpression ( array $ breaks = null , array $ brackets = null ) { if ( ! $ this -> hasLength ( ) ) { return ; } $ breaks = $ breaks ? : [ ] ; $ brackets = $ brackets ? : $ this -> expressionBrackets ; $ expression = '' ; $ char = null ; $ bracketStack = [ ] ; while ( $ this -> hasLength ( ) ) { //Append a string if any was found //Notice there can be brackets in strings, we dont want to //count those $ expression .= $ this -> readString ( null , true ) ; if ( ! $ this -> hasLength ( ) ) { break ; } //Check for breaks if ( count ( $ bracketStack ) === 0 ) { foreach ( $ breaks as $ break ) { if ( $ this -> peekString ( $ break ) ) { break 2 ; } } } //Count brackets $ char = $ this -> peek ( ) ; if ( in_array ( $ char , array_keys ( $ brackets ) , true ) ) { $ bracketStack [ ] = $ char ; } elseif ( in_array ( $ char , array_values ( $ brackets ) , true ) ) { if ( count ( $ bracketStack ) < 1 ) { $ this -> throwException ( "Unexpected bracket $char encountered, no brackets open" ) ; } $ last = count ( $ bracketStack ) - 1 ; if ( $ char !== $ brackets [ $ bracketStack [ $ last ] ] ) { $ this -> throwException ( "Unclosed bracket {$bracketStack[$last]} encountered, " . "got $char instead" ) ; } array_pop ( $ bracketStack ) ; } $ expression .= $ char ; $ this -> consume ( ) ; } if ( count ( $ bracketStack ) > 0 ) { $ this -> throwException ( 'Unclosed brackets ' . implode ( ', ' , $ bracketStack ) . ' encountered ' . 'at end of expression' ) ; } return trim ( $ expression ) ; }
Reads a code-expression that applies bracket counting correctly.

The expression reading stops on any string specified in the `$breaks`-argument.
Breaks will be ignored if we are still in an open bracket.

Notice that this also validates brackets, if any bracket set doesn't match, this
will throw an exception (e.g. "callMe(['demacia')]" would throw an exception)

@param array $breaks   the break characters to use (Breaks on string end by default).
@param array $brackets the brackets to allow (Defaulting to whatever is defined in Reader->expressionBrackets)

@return string|null the resulting expression or null, if none encountered.
Reads a code - expression that applies bracket counting correctly .