}
break;
case 3: // After "/*"
if (this.nextChar == -1) {
throw new CompileException("EOF in traditional comment", this.location());
} else
if (this.nextChar == '*') {
state = 4;
} else
{
state = 9;
}
break;
case 4: // After "/**"
if (this.nextChar == -1) {
throw new CompileException("EOF in doc comment", this.location());
} else
if (this.nextChar == '/') {
state = 0;
} else
{
if (this.docComment != null) {
this.warning(
"MDC",
"Multiple doc comments",
new Location(this.optionalFileName, this.nextCharLineNumber, this.nextCharColumnNumber)
);
}
dcsb = new StringBuffer();
dcsb.append((char) this.nextChar);
state = (
(this.nextChar == '\r' || this.nextChar == '\n') ? 6
: this.nextChar == '*' ? 8
: 5
);
}
break;
case 5: // After "/**..."
if (this.nextChar == -1) {
throw new CompileException("EOF in doc comment", this.location());
} else
if (this.nextChar == '*') {
state = 8;
} else
if (this.nextChar == '\r' || this.nextChar == '\n') {
dcsb.append((char) this.nextChar);
state = 6;
} else
{
dcsb.append((char) this.nextChar);
}
break;
case 6: // After "/**...\n"
if (this.nextChar == -1) {
throw new CompileException("EOF in doc comment", this.location());
} else
if (this.nextChar == '*') {
state = 7;
} else
if (this.nextChar == '\r' || this.nextChar == '\n') {
dcsb.append((char) this.nextChar);
} else
if (this.nextChar == ' ' || this.nextChar == '\t') {
;
} else
{
dcsb.append((char) this.nextChar);
state = 5;
}
break;
case 7: // After "/**...\n *"
if (this.nextChar == -1) {
throw new CompileException("EOF in doc comment", this.location());
} else
if (this.nextChar == '*') {
;
} else
if (this.nextChar == '/') {
this.docComment = dcsb.toString();
state = 0;
} else
{
dcsb.append((char) this.nextChar);
state = 5;
}
break;
case 8: // After "/**...*"
if (this.nextChar == -1) {
throw new CompileException("EOF in doc comment", this.location());
} else
if (this.nextChar == '/') {
this.docComment = dcsb.toString();
state = 0;
} else
if (this.nextChar == '*') {
dcsb.append('*');
} else
{
dcsb.append('*');
dcsb.append((char) this.nextChar);
state = 5;
}
break;
case 9: // After "/*..."
if (this.nextChar == -1) {
throw new CompileException("EOF in traditional comment", this.location());
} else
if (this.nextChar == '*') {
state = 10;
} else
{
;
}
break;
case 10: // After "/*...*"
if (this.nextChar == -1) {
throw new CompileException("EOF in traditional comment", this.location());
} else
if (this.nextChar == '/') {
state = 0;
} else
if (this.nextChar == '*') {
;
} else
{
state = 9;
}
break;
default:
throw new JaninoRuntimeException(Integer.toString(state));
}
this.readNextChar();
}
/*
* Whitespace and comments are now skipped; "nextChar" is definitely
* the first character of the token.
*/
this.tokenLineNumber = this.nextCharLineNumber;
this.tokenColumnNumber = this.nextCharColumnNumber;
// Scan identifier.
if (Character.isJavaIdentifierStart((char) this.nextChar)) {
StringBuffer sb = new StringBuffer();
sb.append((char) this.nextChar);
for (;;) {
this.readNextChar();
if (
this.nextChar == -1 ||
!Character.isJavaIdentifierPart((char) this.nextChar)
) break;
sb.append((char) this.nextChar);
}
String s = sb.toString();
if (s.equals("true")) return new LiteralToken(Boolean.TRUE);
if (s.equals("false")) return new LiteralToken(Boolean.FALSE);
if (s.equals("null")) return new LiteralToken(null);
{
String v = (String) Scanner.JAVA_KEYWORDS.get(s);
if (v != null) return new KeywordToken(v);
}
return new IdentifierToken(s);
}
// Scan numeric literal.
if (Character.isDigit((char) this.nextChar)) {
return this.scanNumericLiteral(0);
}
// A "." is special: Could either be a floating-point constant like ".001", or the "."
// operator.
if (this.nextChar == '.') {
this.readNextChar();
if (Character.isDigit((char) this.nextChar)) {
return this.scanNumericLiteral(2);
} else {
return new OperatorToken(".");
}
}
// Scan string literal.
if (this.nextChar == '"') {
StringBuffer sb = new StringBuffer("");
this.readNextChar();
if (this.nextChar == -1) throw new CompileException("EOF in string literal", this.location());
if (this.nextChar == '\r' || this.nextChar == '\n') {
throw new CompileException("Line break in string literal", this.location());
}
while (this.nextChar != '"') {
sb.append(this.unescapeCharacterLiteral());
}
this.readNextChar();
return new LiteralToken(sb.toString());
}
// Scan character literal.
if (this.nextChar == '\'') {
this.readNextChar();
if (this.nextChar == '\'') {
throw new CompileException(
"Single quote must be backslash-escaped in character literal",
this.location()
);
}
char lit = this.unescapeCharacterLiteral();
if (this.nextChar != '\'') throw new CompileException("Closing single quote missing", this.location());
this.readNextChar();
return new LiteralToken(new Character(lit));
}
// Scan separator / operator.
{
String v = (String) Scanner.JAVA_OPERATORS.get(
new String(new char[] { (char) this.nextChar })
);
if (v != null) {
for (;;) {
this.readNextChar();
String v2 = (String) Scanner.JAVA_OPERATORS.get(v + (char) this.nextChar);
if (v2 == null) return new OperatorToken(v);
v = v2;
}
}
}
throw new CompileException(
"Invalid character input \"" + (char) this.nextChar + "\" (character code " + this.nextChar + ")",
this.location()
);
}