in grails-gsp/core/src/main/groovy/org/grails/gsp/compiler/GroovyPageScanner.java [117:230]
int nextToken() {
for (;;) {
int left = len - end1;
if (left == 0) {
end1++; // in order to include the last letter
return found(EOF, 0);
}
char c = text.charAt(end1++);
char c1 = left > 1 ? text.charAt(end1) : 0;
char c2 = left > 2 ? text.charAt(end1 + 1) : 0;
int tokenLength = end1 - begin1;
switch (state) {
case HTML:
if (isPotentialScriptletOrTag(c, left)) {
if (c1 == '%') {
if (c2 == '=') {
return found(JEXPR, 3);
}
if (c2 == '@') {
return found(JDIRECT, 3);
}
if (c2 == '!') {
return found(JDECLAR, 3);
}
if (isStartComment(c1, c2, left)) {
if (skipJComment())
continue;
}
return found(JSCRIPT, 2);
}
boolean bStartTag = !isClosingTag(c1);
String tagNameSpace = getTagNamespace(bStartTag ? end1 : end1 + 1);
if (isTagDefinition(tagNameSpace)) {
if (bStartTag) {
return foundStartOrEndTag(GSTART_TAG, tagNameSpace.length() + 2, tagNameSpace);
}
return foundStartOrEndTag(GEND_TAG, tagNameSpace.length() + 3, tagNameSpace);
}
}
else if (isStartOfGExpression(c, c1)) {
return found(GEXPR, 2);
}
if (c == '%' && c1 == '{') {
if (c2 == '-' && left > 3 && text.charAt(end1 + 2) == '-') {
if (skipGComment())
continue;
}
return found(GSCRIPT, 2);
}
if (c == '!' && c1 == '{') {
return found(GDECLAR, 2);
}
if (c == '@' && c1 == '{') {
return found(GDIRECT, 2);
}
if (tokenLength > maxHtmlLength) {
return found(HTML, 0);
}
break;
case JEXPR:
case JSCRIPT:
case JDIRECT:
case JDECLAR:
if (c == '%' && c1 == '>') {
return found(HTML, 2);
}
break;
case GSTART_TAG:
if (isStartOfGExpression(c, c1)) {
return found(GTAG_EXPR, 2);
}
if (c == '>') {
return found(HTML, 1);
}
else if (isClosingTag(c) && c1 == '>') {
return found(GEND_EMPTY_TAG, 1);
}
break;
case GEND_TAG:
case GEND_EMPTY_TAG:
if (c == '>') {
return found(HTML, 1);
}
break;
case GTAG_EXPR:
case GEXPR:
return parseExpression();
case GDIRECT:
if (c == '}') {
return found(HTML, 1);
}
break;
case GSCRIPT:
if (c == '}' && c1 == '%') {
return found(HTML, 2);
}
break;
case GDECLAR:
if (c == '}' && (c1 == '!' || c1 == '%')) {
return found(HTML, 2);
}
break;
}
}
}