src/Language/Lexer.php
private function readToken(Token $prev)
    {
        $bodyLength = $this->source->length;

        $this->positionAfterWhitespace();
        $position = $this->position;

        $line = $this->line;
        $col  = 1 + $position - $this->lineStart;

        if ($position >= $bodyLength) {
            return new Token(Token::EOF, $bodyLength, $bodyLength, $line, $col, $prev);
        }

        // Read next char and advance string cursor:
        [, $code, $bytes] = $this->readChar(true);

        switch ($code) {
            case self::TOKEN_BANG:
                return new Token(Token::BANG, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_HASH: // #
                $this->moveStringCursor(-1, -1 * $bytes);

                return $this->readComment($line, $col, $prev);
            case self::TOKEN_DOLLAR:
                return new Token(Token::DOLLAR, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_AMP:
                return new Token(Token::AMP, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_PAREN_L:
                return new Token(Token::PAREN_L, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_PAREN_R:
                return new Token(Token::PAREN_R, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_DOT: // .
                [, $charCode1] = $this->readChar(true);
                [, $charCode2] = $this->readChar(true);

                if ($charCode1 === self::TOKEN_DOT && $charCode2 === self::TOKEN_DOT) {
                    return new Token(Token::SPREAD, $position, $position + 3, $line, $col, $prev);
                }
                break;
            case self::TOKEN_COLON:
                return new Token(Token::COLON, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_EQUALS:
                return new Token(Token::EQUALS, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_AT:
                return new Token(Token::AT, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_BRACKET_L:
                return new Token(Token::BRACKET_L, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_BRACKET_R:
                return new Token(Token::BRACKET_R, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_BRACE_L:
                return new Token(Token::BRACE_L, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_PIPE:
                return new Token(Token::PIPE, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_BRACE_R:
                return new Token(Token::BRACE_R, $position, $position + 1, $line, $col, $prev);

            // A-Z
            case 65:
            case 66:
            case 67:
            case 68:
            case 69:
            case 70:
            case 71:
            case 72:
            case 73:
            case 74:
            case 75:
            case 76:
            case 77:
            case 78:
            case 79:
            case 80:
            case 81:
            case 82:
            case 83:
            case 84:
            case 85:
            case 86:
            case 87:
            case 88:
            case 89:
            case 90:
                // _
            case 95:
                // a-z
            case 97:
            case 98:
            case 99:
            case 100:
            case 101:
            case 102:
            case 103:
            case 104:
            case 105:
            case 106:
            case 107:
            case 108:
            case 109:
            case 110:
            case 111:
            case 112:
            case 113:
            case 114:
            case 115:
            case 116:
            case 117:
            case 118:
            case 119:
            case 120:
            case 121:
            case 122:
                return $this->moveStringCursor(-1, -1 * $bytes)
                    ->readName($line, $col, $prev);

            // -
            case 45:
                // 0-9
            case 48:
            case 49:
            case 50:
            case 51:
            case 52:
            case 53:
            case 54:
            case 55:
            case 56:
            case 57:
                return $this->moveStringCursor(-1, -1 * $bytes)
                    ->readNumber($line, $col, $prev);

            // "
            case 34:
                [, $nextCode]     = $this->readChar();
                [, $nextNextCode] = $this->moveStringCursor(1, 1)->readChar();

                if ($nextCode === 34 && $nextNextCode === 34) {
                    return $this->moveStringCursor(-2, (-1 * $bytes) - 1)
                        ->readBlockString($line, $col, $prev);
                }

                return $this->moveStringCursor(-2, (-1 * $bytes) - 1)
                    ->readString($line, $col, $prev);
        }

        throw new SyntaxError(
            $this->source,
            $position,
            $this->unexpectedCharacterMessage($code)
        );
    }
private function readToken(Token $prev)
    {
        $bodyLength = $this->source->length;

        $this->positionAfterWhitespace();
        $position = $this->position;

        $line = $this->line;
        $col  = 1 + $position - $this->lineStart;

        if ($position >= $bodyLength) {
            return new Token(Token::EOF, $bodyLength, $bodyLength, $line, $col, $prev);
        }

        // Read next char and advance string cursor:
        [, $code, $bytes] = $this->readChar(true);

        switch ($code) {
            case self::TOKEN_BANG:
                return new Token(Token::BANG, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_HASH: // #
                $this->moveStringCursor(-1, -1 * $bytes);

                return $this->readComment($line, $col, $prev);
            case self::TOKEN_DOLLAR:
                return new Token(Token::DOLLAR, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_AMP:
                return new Token(Token::AMP, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_PAREN_L:
                return new Token(Token::PAREN_L, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_PAREN_R:
                return new Token(Token::PAREN_R, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_DOT: // .
                [, $charCode1] = $this->readChar(true);
                [, $charCode2] = $this->readChar(true);

                if ($charCode1 === self::TOKEN_DOT && $charCode2 === self::TOKEN_DOT) {
                    return new Token(Token::SPREAD, $position, $position + 3, $line, $col, $prev);
                }
                break;
            case self::TOKEN_COLON:
                return new Token(Token::COLON, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_EQUALS:
                return new Token(Token::EQUALS, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_AT:
                return new Token(Token::AT, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_BRACKET_L:
                return new Token(Token::BRACKET_L, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_BRACKET_R:
                return new Token(Token::BRACKET_R, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_BRACE_L:
                return new Token(Token::BRACE_L, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_PIPE:
                return new Token(Token::PIPE, $position, $position + 1, $line, $col, $prev);
            case self::TOKEN_BRACE_R:
                return new Token(Token::BRACE_R, $position, $position + 1, $line, $col, $prev);

            // A-Z
            case 65:
            case 66:
            case 67:
            case 68:
            case 69:
            case 70:
            case 71:
            case 72:
            case 73:
            case 74:
            case 75:
            case 76:
            case 77:
            case 78:
            case 79:
            case 80:
            case 81:
            case 82:
            case 83:
            case 84:
            case 85:
            case 86:
            case 87:
            case 88:
            case 89:
            case 90:
                // _
            case 95:
                // a-z
            case 97:
            case 98:
            case 99:
            case 100:
            case 101:
            case 102:
            case 103:
            case 104:
            case 105:
            case 106:
            case 107:
            case 108:
            case 109:
            case 110:
            case 111:
            case 112:
            case 113:
            case 114:
            case 115:
            case 116:
            case 117:
            case 118:
            case 119:
            case 120:
            case 121:
            case 122:
                return $this->moveStringCursor(-1, -1 * $bytes)
                    ->readName($line, $col, $prev);

            // -
            case 45:
                // 0-9
            case 48:
            case 49:
            case 50:
            case 51:
            case 52:
            case 53:
            case 54:
            case 55:
            case 56:
            case 57:
                return $this->moveStringCursor(-1, -1 * $bytes)
                    ->readNumber($line, $col, $prev);

            // "
            case 34:
                [, $nextCode]     = $this->readChar();
                [, $nextNextCode] = $this->moveStringCursor(1, 1)->readChar();

                if ($nextCode === 34 && $nextNextCode === 34) {
                    return $this->moveStringCursor(-2, (-1 * $bytes) - 1)
                        ->readBlockString($line, $col, $prev);
                }

                return $this->moveStringCursor(-2, (-1 * $bytes) - 1)
                    ->readString($line, $col, $prev);
        }

        throw new SyntaxError(
            $this->source,
            $position,
            $this->unexpectedCharacterMessage($code)
        );
    }
private function readToken ( Token $ prev ) { $ bodyLength = $ this -> source -> length ; $ this -> positionAfterWhitespace ( ) ; $ position = $ this -> position ; $ line = $ this -> line ; $ col = 1 + $ position - $ this -> lineStart ; if ( $ position >= $ bodyLength ) { return new Token ( Token :: EOF , $ bodyLength , $ bodyLength , $ line , $ col , $ prev ) ; } // Read next char and advance string cursor: [ , $ code , $ bytes ] = $ this -> readChar ( true ) ; switch ( $ code ) { case self :: TOKEN_BANG : return new Token ( Token :: BANG , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_HASH : // # $ this -> moveStringCursor ( - 1 , - 1 * $ bytes ) ; return $ this -> readComment ( $ line , $ col , $ prev ) ; case self :: TOKEN_DOLLAR : return new Token ( Token :: DOLLAR , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_AMP : return new Token ( Token :: AMP , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_PAREN_L : return new Token ( Token :: PAREN_L , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_PAREN_R : return new Token ( Token :: PAREN_R , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_DOT : // . [ , $ charCode1 ] = $ this -> readChar ( true ) ; [ , $ charCode2 ] = $ this -> readChar ( true ) ; if ( $ charCode1 === self :: TOKEN_DOT && $ charCode2 === self :: TOKEN_DOT ) { return new Token ( Token :: SPREAD , $ position , $ position + 3 , $ line , $ col , $ prev ) ; } break ; case self :: TOKEN_COLON : return new Token ( Token :: COLON , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_EQUALS : return new Token ( Token :: EQUALS , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_AT : return new Token ( Token :: AT , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_BRACKET_L : return new Token ( Token :: BRACKET_L , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_BRACKET_R : return new Token ( Token :: BRACKET_R , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_BRACE_L : return new Token ( Token :: BRACE_L , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_PIPE : return new Token ( Token :: PIPE , $ position , $ position + 1 , $ line , $ col , $ prev ) ; case self :: TOKEN_BRACE_R : return new Token ( Token :: BRACE_R , $ position , $ position + 1 , $ line , $ col , $ prev ) ; // A-Z case 65 : case 66 : case 67 : case 68 : case 69 : case 70 : case 71 : case 72 : case 73 : case 74 : case 75 : case 76 : case 77 : case 78 : case 79 : case 80 : case 81 : case 82 : case 83 : case 84 : case 85 : case 86 : case 87 : case 88 : case 89 : case 90 : // _ case 95 : // a-z case 97 : case 98 : case 99 : case 100 : case 101 : case 102 : case 103 : case 104 : case 105 : case 106 : case 107 : case 108 : case 109 : case 110 : case 111 : case 112 : case 113 : case 114 : case 115 : case 116 : case 117 : case 118 : case 119 : case 120 : case 121 : case 122 : return $ this -> moveStringCursor ( - 1 , - 1 * $ bytes ) -> readName ( $ line , $ col , $ prev ) ; // - case 45 : // 0-9 case 48 : case 49 : case 50 : case 51 : case 52 : case 53 : case 54 : case 55 : case 56 : case 57 : return $ this -> moveStringCursor ( - 1 , - 1 * $ bytes ) -> readNumber ( $ line , $ col , $ prev ) ; // " case 34 : [ , $ nextCode ] = $ this -> readChar ( ) ; [ , $ nextNextCode ] = $ this -> moveStringCursor ( 1 , 1 ) -> readChar ( ) ; if ( $ nextCode === 34 && $ nextNextCode === 34 ) { return $ this -> moveStringCursor ( - 2 , ( - 1 * $ bytes ) - 1 ) -> readBlockString ( $ line , $ col , $ prev ) ; } return $ this -> moveStringCursor ( - 2 , ( - 1 * $ bytes ) - 1 ) -> readString ( $ line , $ col , $ prev ) ; } throw new SyntaxError ( $ this -> source , $ position , $ this -> unexpectedCharacterMessage ( $ code ) ) ; }
@return Token

@throws SyntaxError
@return Token