// Path: src/main/java/com/nebhale/jsonpath/internal/parser/PathCharacter.java
// enum CharacterType {
//     ARRAY_CLOSE, //
//     ARRAY_OPEN, //
//     COMMA, //
//     COMPLEX_NAME_CHARACTER, //
//     DIGIT, //
//     DOT, //
//     DOUBLE_QUOTE, //
//     END, //
//     HYPHEN, //
//     INDEX_CHARACTER, //
//     LETTER, //
//     QUOTE, //
//     ROOT, //
//     SIMPLE_NAME_CHARACTER, //
//     SPACE, //
//     UNDERSCORE, //
//     WILDCARD;
// }
// 
// Path: src/main/java/com/nebhale/jsonpath/internal/parser/Token.java
// enum TokenType {
// 
//     CHILD, //
//     DEEP_WILDCARD, //
//     INDEX, //
//     ROOT, //
//     WILDCARD
// 
// }


import java.util.ArrayList;
import java.util.List;
import com.nebhale.jsonpath.internal.parser.PathCharacter.CharacterType;
import com.nebhale.jsonpath.internal.parser.Token.TokenType;
/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.nebhale.jsonpath.internal.parser;



/**
 * An implementation of {@link PathLexer} that tokenizes into the following types:
 * <p />
 *
 * <pre>
 * ROOT:            ROOT
 * CHILD:           DOT_CHILD | ARRAY_CHILD
 * INDEX:           ARRAY_OPEN ( INDEX_CHARACTER* | WILDCARD ) ARRAY_CLOSE
 * DOT_CHILD:       DOT SIMPLE_NAME
 * ARRAY_CHILD:     ARRAY_OPEN ( QUOTE COMPLEX_NAME QUOTE | DOUBLE_QUOTE COMPLEX_NAME DOUBLE_QUOTE ) ARRAY_CLOSE
 * SIMPLE_NAME:     SIMPLE_NAME_CHARACTER* | WILDCARD
 * COMPLEX_NAME:    COMPLEX_NAME_CHARACTER* | WILDCARD
 * </pre>
 *
 * <strong>Concurrent Semantics</strong><br />
 *
 * Thread-safe
 *
 * @see StandardPathScanner
 */
final class RecoveringPathLexer implements PathLexer {

    @Override
    public LexerResult lex(String expression) {
        LexerContext context = new LexerContext(expression);
        PathScanner scanner = context.scanner;

        while (scanner.ready()) {
            PathCharacter c = scanner.get();

            if (context.parsingState == ParsingState.BASE) {
                base(context, c);
            } else if (context.parsingState == ParsingState.ARRAY_OPEN) {
                arrayOpen(context, c);
            } else if (context.parsingState == ParsingState.ARRAY_CLOSE) {
                arrayClose(context, c);
            } else if (context.parsingState == ParsingState.DOUBLE_QUOTE_CHILD) {
// Path: src/main/java/com/nebhale/jsonpath/internal/parser/PathCharacter.java
// enum CharacterType {
//     ARRAY_CLOSE, //
//     ARRAY_OPEN, //
//     COMMA, //
//     COMPLEX_NAME_CHARACTER, //
//     DIGIT, //
//     DOT, //
//     DOUBLE_QUOTE, //
//     END, //
//     HYPHEN, //
//     INDEX_CHARACTER, //
//     LETTER, //
//     QUOTE, //
//     ROOT, //
//     SIMPLE_NAME_CHARACTER, //
//     SPACE, //
//     UNDERSCORE, //
//     WILDCARD;
// }
// 
// Path: src/main/java/com/nebhale/jsonpath/internal/parser/Token.java
// enum TokenType {
// 
//     CHILD, //
//     DEEP_WILDCARD, //
//     INDEX, //
//     ROOT, //
//     WILDCARD
// 
// }


// Path: src/main/java/com/nebhale/jsonpath/internal/parser/RecoveringPathLexer.java
import java.util.ArrayList;
import java.util.List;
import com.nebhale.jsonpath.internal.parser.PathCharacter.CharacterType;
import com.nebhale.jsonpath.internal.parser.Token.TokenType;

/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.nebhale.jsonpath.internal.parser;



/**
 * An implementation of {@link PathLexer} that tokenizes into the following types:
 * <p />
 *
 * <pre>
 * ROOT:            ROOT
 * CHILD:           DOT_CHILD | ARRAY_CHILD
 * INDEX:           ARRAY_OPEN ( INDEX_CHARACTER* | WILDCARD ) ARRAY_CLOSE
 * DOT_CHILD:       DOT SIMPLE_NAME
 * ARRAY_CHILD:     ARRAY_OPEN ( QUOTE COMPLEX_NAME QUOTE | DOUBLE_QUOTE COMPLEX_NAME DOUBLE_QUOTE ) ARRAY_CLOSE
 * SIMPLE_NAME:     SIMPLE_NAME_CHARACTER* | WILDCARD
 * COMPLEX_NAME:    COMPLEX_NAME_CHARACTER* | WILDCARD
 * </pre>
 *
 * <strong>Concurrent Semantics</strong><br />
 *
 * Thread-safe
 *
 * @see StandardPathScanner
 */
final class RecoveringPathLexer implements PathLexer {

    @Override
    public LexerResult lex(String expression) {
        LexerContext context = new LexerContext(expression);
        PathScanner scanner = context.scanner;

        while (scanner.ready()) {
            PathCharacter c = scanner.get();

            if (context.parsingState == ParsingState.BASE) {
                base(context, c);
            } else if (context.parsingState == ParsingState.ARRAY_OPEN) {
                arrayOpen(context, c);
            } else if (context.parsingState == ParsingState.ARRAY_CLOSE) {
                arrayClose(context, c);
            } else if (context.parsingState == ParsingState.DOUBLE_QUOTE_CHILD) {
                arrayChild(context, c, CharacterType.DOUBLE_QUOTE, ParsingState.DOUBLE_QUOTE_CLOSE);