int parse()

in grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageExpressionParser.java [61:121]


    int parse() {
        int currentPos = startPos;
        char previousChar = 0;
        char previousPreviousChar = 0;

        while(currentPos < scriptTokens.length() && terminationCharPos==-1) {
            ParsingState parsingState = parsingStateStack.peek();
            char ch = scriptTokens.charAt(currentPos++);
            char nextChar = (currentPos < scriptTokens.length()) ? scriptTokens.charAt(currentPos) : 0;

            if (parsingStateStack.size()==1 && ch==terminationChar && (nextTerminationChar==0 || nextTerminationChar==nextChar)) {
                terminationCharPos = currentPos-1;
            } else if (parsingState==ParsingState.EXPRESSION || parsingState==ParsingState.NORMAL) {
                switch(ch) {
                    case '{':
                        if (previousChar=='$' && parsingState==ParsingState.EXPRESSION) {
                            // invalid expression, starting new ${} expression inside expression
                            return -1;
                        }
                        if (previousChar=='$' || parsingState==ParsingState.EXPRESSION) {
                            changeState(ParsingState.EXPRESSION);
                        }
                        break;
                    case '[':
                        if (relativeCharIndex==0 || parsingState==ParsingState.EXPRESSION) {
                            changeState(ParsingState.EXPRESSION);
                        }
                        break;
                    case '}':
                    case ']':
                        if (parsingState==ParsingState.EXPRESSION) {
                            parsingStateStack.pop();
                        }
                        break;
                    case '\'':
                    case '"':
                        if (parsingState==ParsingState.EXPRESSION) {
                            if (nextChar != ch && previousChar != ch) {
                                changeState(ch=='"' ? ParsingState.QUOTEDVALUE_DOUBLE : ParsingState.QUOTEDVALUE_SINGLE);
                            } else if (previousChar==ch && previousPreviousChar==ch) {
                                changeState(ch=='"' ? ParsingState.TRIPLEQUOTED_DOUBLE : ParsingState.TRIPLEQUOTED_SINGLE);
                            }
                        }
                        break;
                }
            } else if (ch=='"' || ch=='\'') {
                if (nextChar != ch && (previousChar != ch || previousPreviousChar=='\\') && (previousChar != '\\' || (previousChar=='\\' && previousPreviousChar=='\\'))
                        && ((parsingState == ParsingState.QUOTEDVALUE_DOUBLE && ch == '"') || (parsingState == ParsingState.QUOTEDVALUE_SINGLE && ch == '\''))) {
                    parsingStateStack.pop();
                }
                else if ((previousChar == ch && previousPreviousChar == ch)
                        && ((parsingState == ParsingState.TRIPLEQUOTED_DOUBLE && ch == '"') || (parsingState == ParsingState.TRIPLEQUOTED_SINGLE && ch == '\''))) {
                    parsingStateStack.pop();
                }
            }
            previousPreviousChar = previousChar;
            previousChar=ch;
            relativeCharIndex++;
        }
        return terminationCharPos;
    }