Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. ParserAbstract.php

function ParserAbstract::doParse

Return value

Stmt[]|null

1 call to ParserAbstract::doParse()
ParserAbstract::parse in vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php
Parses PHP code into a node tree.

File

vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php, line 220

Class

ParserAbstract

Namespace

PhpParser

Code

protected function doParse() : ?array {
    // We start off with no lookahead-token
    $symbol = self::SYMBOL_NONE;
    $tokenValue = null;
    $this->tokenPos = -1;
    // Keep stack of start and end attributes
    $this->tokenStartStack = [];
    $this->tokenEndStack = [
        0,
    ];
    // Start off in the initial state and keep a stack of previous states
    $state = 0;
    $stateStack = [
        $state,
    ];
    // Semantic value stack (contains values of tokens and semantic action results)
    $this->semStack = [];
    // Current position in the stack(s)
    $stackPos = 0;
    $this->errorState = 0;
    for (;;) {
        
        //$this->traceNewState($state, $symbol);
        if ($this->actionBase[$state] === 0) {
            $rule = $this->actionDefault[$state];
        }
        else {
            if ($symbol === self::SYMBOL_NONE) {
                do {
                    $token = $this->tokens[++$this->tokenPos];
                    $tokenId = $token->id;
                } while (isset($this->dropTokens[$tokenId]));
                // Map the lexer token id to the internally used symbols.
                $tokenValue = $token->text;
                if (!isset($this->phpTokenToSymbol[$tokenId])) {
                    throw new \RangeException(sprintf('The lexer returned an invalid token (id=%d, value=%s)', $tokenId, $tokenValue));
                }
                $symbol = $this->phpTokenToSymbol[$tokenId];
                
                //$this->traceRead($symbol);
            }
            $idx = $this->actionBase[$state] + $symbol;
            if (($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) && ($action = $this->action[$idx]) !== $this->defaultAction) {
                
                /*
                 * >= numNonLeafStates: shift and reduce
                 * > 0: shift
                 * = 0: accept
                 * < 0: reduce
                 * = -YYUNEXPECTED: error
                 */
                if ($action > 0) {
                    
                    /* shift */
                    
                    //$this->traceShift($symbol);
                    ++$stackPos;
                    $stateStack[$stackPos] = $state = $action;
                    $this->semStack[$stackPos] = $tokenValue;
                    $this->tokenStartStack[$stackPos] = $this->tokenPos;
                    $this->tokenEndStack[$stackPos] = $this->tokenPos;
                    $symbol = self::SYMBOL_NONE;
                    if ($this->errorState) {
                        --$this->errorState;
                    }
                    if ($action < $this->numNonLeafStates) {
                        continue;
                    }
                    
                    /* $yyn >= numNonLeafStates means shift-and-reduce */
                    $rule = $action - $this->numNonLeafStates;
                }
                else {
                    $rule = -$action;
                }
            }
            else {
                $rule = $this->actionDefault[$state];
            }
        }
        for (;;) {
            if ($rule === 0) {
                
                /* accept */
                
                //$this->traceAccept();
                return $this->semValue;
            }
            if ($rule !== $this->unexpectedTokenRule) {
                
                /* reduce */
                
                //$this->traceReduce($rule);
                $ruleLength = $this->ruleToLength[$rule];
                try {
                    $callback = $this->reduceCallbacks[$rule];
                    if ($callback !== null) {
                        $callback($this, $stackPos);
                    }
                    elseif ($ruleLength > 0) {
                        $this->semValue = $this->semStack[$stackPos - $ruleLength + 1];
                    }
                } catch (Error $e) {
                    if (-1 === $e->getStartLine()) {
                        $e->setStartLine($this->tokens[$this->tokenPos]->line);
                    }
                    $this->emitError($e);
                    // Can't recover from this type of error
                    return null;
                }
                
                /* Goto - shift nonterminal */
                $lastTokenEnd = $this->tokenEndStack[$stackPos];
                $stackPos -= $ruleLength;
                $nonTerminal = $this->ruleToNonTerminal[$rule];
                $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos];
                if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] === $nonTerminal) {
                    $state = $this->goto[$idx];
                }
                else {
                    $state = $this->gotoDefault[$nonTerminal];
                }
                ++$stackPos;
                $stateStack[$stackPos] = $state;
                $this->semStack[$stackPos] = $this->semValue;
                $this->tokenEndStack[$stackPos] = $lastTokenEnd;
                if ($ruleLength === 0) {
                    // Empty productions use the start attributes of the lookahead token.
                    $this->tokenStartStack[$stackPos] = $this->tokenPos;
                }
            }
            else {
                
                /* error */
                switch ($this->errorState) {
                    case 0:
                        $msg = $this->getErrorMessage($symbol, $state);
                        $this->emitError(new Error($msg, $this->getAttributesForToken($this->tokenPos)));
                    // Break missing intentionally
                    // no break
                    case 1:
                    case 2:
                        $this->errorState = 3;
                        // Pop until error-expecting state uncovered
                        while (!(($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) || ($action = $this->action[$idx]) === $this->defaultAction) {
                            // Not totally sure about this
                            if ($stackPos <= 0) {
                                // Could not recover from error
                                return null;
                            }
                            $state = $stateStack[--$stackPos];
                            
                            //$this->tracePop($state);
                        }
                        
                        //$this->traceShift($this->errorSymbol);
                        ++$stackPos;
                        $stateStack[$stackPos] = $state = $action;
                        // We treat the error symbol as being empty, so we reset the end attributes
                        // to the end attributes of the last non-error symbol
                        $this->tokenStartStack[$stackPos] = $this->tokenPos;
                        $this->tokenEndStack[$stackPos] = $this->tokenEndStack[$stackPos - 1];
                        break;
                    case 3:
                        if ($symbol === 0) {
                            // Reached EOF without recovering from error
                            return null;
                        }
                        
                        //$this->traceDiscard($symbol);
                        $symbol = self::SYMBOL_NONE;
                        break 2;
                }
            }
            if ($state < $this->numNonLeafStates) {
                break;
            }
            
            /* >= numNonLeafStates means shift-and-reduce */
            $rule = $state - $this->numNonLeafStates;
        }
    }
    throw new \RuntimeException('Reached end of parser loop');
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal