in modules/asc/src/java/macromedia/asc/parser/Scanner.java [404:1622]
public int nexttoken(boolean resetState)
{
String doctagname = "description";
StringBuilder doctextbuf = null;
int startofxml = pos();
StringBuilder blockcommentbuf = null;
char regexp_flags = 0; // used to track option flags encountered in a regexp expression. Initialized in regexp_state
boolean maybe_reserved = false;
char c = 0;
if (resetState)
{
isFirstTokenOnLine = false;
}
while (true)
{
if (debug)
{
System.out.println("state = " + state + ", next = " + pos());
}
switch (state)
{
case start_state:
{
c = nextchar();
mark();
switch (c)
{
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
maybe_reserved = true;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
case '_': case '$':
state = A_state;
continue;
case 0xffef: // could not have worked...case 0xffffffef: // ??? not in Character type range ???
if (nextchar()==0xffffffbb &&
nextchar()==0xffffffbf)
{
// ISSUE: set encoding scheme to utf-8, and implement support for utf8
state = start_state;
}
else
{
state = error_state;
}
continue;
case '@':
return makeToken( ATSIGN_TOKEN );
case '\'':
case '\"':
{
char startquote = (char) c;
boolean needs_escape = false;
while ( (c=nextchar()) != startquote )
{
if ( c == '\\' )
{
needs_escape = true;
c = nextchar();
// special case: escaped eol strips crlf or lf
if ( c == '\r' )
c = nextchar();
if ( c == '\n' )
continue;
}
else if ( c == '\r' || c == '\n' )
{
if ( startquote == '\'' )
error(kError_Lexical_LineTerminatorInSingleQuotedStringLiteral);
else
error(kError_Lexical_LineTerminatorInDoubleQuotedStringLiteral);
break;
}
else if ( c == 0 )
{
error(kError_Lexical_EndOfStreamInStringLiteral);
return makeToken( EOS_TOKEN );
}
}
return makeToken(STRINGLITERAL_TOKEN, input.copyReplaceStringEscapes(needs_escape));
}
case '-': // tokens: -- -= -
switch (nextchar())
{
case '-':
return makeToken( MINUSMINUS_TOKEN );
case '=':
return makeToken( MINUSASSIGN_TOKEN );
default:
retract();
return makeToken( MINUS_TOKEN );
}
case '!': // tokens: ! != !===
if (nextchar()=='=')
{
if (nextchar()=='=')
return makeToken( STRICTNOTEQUALS_TOKEN );
retract();
return makeToken( NOTEQUALS_TOKEN );
}
retract();
return makeToken( NOT_TOKEN );
case '%': // tokens: % %=
switch (nextchar())
{
case '=':
return makeToken( MODULUSASSIGN_TOKEN );
default:
retract();
return makeToken( MODULUS_TOKEN );
}
case '&': // tokens: & &= && &&=
c = nextchar();
if (c=='=')
return makeToken( BITWISEANDASSIGN_TOKEN );
if (c=='&')
{
if (nextchar()=='=')
return makeToken( LOGICALANDASSIGN_TOKEN );
retract();
return makeToken( LOGICALAND_TOKEN );
}
retract();
return makeToken( BITWISEAND_TOKEN );
case '#': // # is short for use
if (HAS_HASHPRAGMAS)
{
return makeToken( USE_TOKEN );
}
state = error_state;
continue;
case '(':
return makeToken( LEFTPAREN_TOKEN );
case ')':
return makeToken( RIGHTPAREN_TOKEN );
case '*': // tokens: *= *
if (nextchar()=='=')
return makeToken( MULTASSIGN_TOKEN );
retract();
return makeToken( MULT_TOKEN );
case ',':
return makeToken( COMMA_TOKEN );
case '.':
state = dot_state;
continue;
case '/':
state = slash_state;
continue;
case ':': // tokens: : ::
if (nextchar()==':')
{
return makeToken( DOUBLECOLON_TOKEN );
}
retract();
return makeToken( COLON_TOKEN );
case ';':
return makeToken( SEMICOLON_TOKEN );
case '?':
return makeToken( QUESTIONMARK_TOKEN );
case '[':
return makeToken( LEFTBRACKET_TOKEN );
case ']':
return makeToken( RIGHTBRACKET_TOKEN );
case '^': // tokens: ^= ^
if (nextchar()=='=')
return makeToken( BITWISEXORASSIGN_TOKEN );
retract();
return makeToken( BITWISEXOR_TOKEN );
case '{':
return makeToken( LEFTBRACE_TOKEN );
case '|': // tokens: | |= || ||=
c = nextchar();
if (c=='=')
return makeToken( BITWISEORASSIGN_TOKEN );
if (c=='|')
{
if (nextchar()=='=')
return makeToken( LOGICALORASSIGN_TOKEN );
retract();
return makeToken( LOGICALOR_TOKEN );
}
retract();
return makeToken( BITWISEOR_TOKEN );
case '}':
return makeToken( RIGHTBRACE_TOKEN );
case '~':
return makeToken( BITWISENOT_TOKEN );
case '+': // tokens: ++ += +
c = nextchar();
if (c=='+')
return makeToken( PLUSPLUS_TOKEN );
if (c=='=')
return makeToken( PLUSASSIGN_TOKEN );
retract();
return makeToken( PLUS_TOKEN );
case '<':
switch (nextchar())
{
case '<': // tokens: << <<=
if (nextchar()=='=')
return makeToken( LEFTSHIFTASSIGN_TOKEN );
retract();
return makeToken( LEFTSHIFT_TOKEN );
case '=':
return makeToken( LESSTHANOREQUALS_TOKEN );
case '/':
return makeToken( XMLTAGSTARTEND_TOKEN );
case '!':
state = xmlcommentorcdatastart_state;
continue;
case '?':
state = xmlpi_state;
continue;
}
retract();
return makeToken( LESSTHAN_TOKEN );
case '=': // tokens: === == =
if (nextchar()=='=')
{
if (nextchar()=='=')
return makeToken( STRICTEQUALS_TOKEN );
retract();
return makeToken( EQUALS_TOKEN );
}
retract();
return makeToken( ASSIGN_TOKEN );
case '>': // tokens: > >= >> >>= >>> >>>=
state = start_state;
switch ( nextchar() )
{
case '>':
switch (nextchar())
{
case '>':
if (nextchar()=='=')
return makeToken( UNSIGNEDRIGHTSHIFTASSIGN_TOKEN );
retract();
return makeToken( UNSIGNEDRIGHTSHIFT_TOKEN );
case '=':
return makeToken( RIGHTSHIFTASSIGN_TOKEN );
default:
retract();
return makeToken( RIGHTSHIFT_TOKEN );
}
case '=':
return makeToken( GREATERTHANOREQUALS_TOKEN );
}
retract();
return makeToken( GREATERTHAN_TOKEN );
case '0':
state = zero_state;
continue;
case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
state = decimalinteger_state;
continue;
case ' ': // ascii range white space
case '\t':
case 0x000b:
case 0x000c:
case 0x0085:
case 0x00a0:
continue;
case '\n': // ascii line terminators.
case '\r':
isFirstTokenOnLine = true;
continue;
case 0:
return makeToken( EOS_TOKEN );
default:
switch (input.nextcharClass((char)c,true))
{
case Lu: case Ll: case Lt: case Lm: case Lo: case Nl:
maybe_reserved = false;
state = A_state;
continue;
case Zs:// unicode whitespace and control-characters
case Cc:
case Cf:
continue;
case Zl:// unicode line terminators
case Zp:
isFirstTokenOnLine = true;
continue;
default:
state = error_state;
continue;
}
}
}
/*
* prefix: <letter>
*/
case A_state:
{
boolean needs_escape = c == '\\'; // ??? really should only be true if the word started with a backslash
while ( true ){
c = nextchar();
if ( c >= 'a' && c <= 'z' )
{
continue;
}
if ( (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '$' || c == '_' ){
maybe_reserved = false;
continue;
}
if ( c <= 0x7f ) // in ascii range & mostly not a valid char
{
if ( c == '\\' )
{
needs_escape = true; // close enough, we just want to minimize rescans for unicode escapes
}
else {
retract();
break;
}
}
// else outside ascii range (or an escape sequence )
switch (input.nextcharClass(c,false))
{
case Lu: case Ll: case Lt: case Lm: case Lo: case Nl: case Mn: case Mc: case Nd: case Pc:
maybe_reserved = false;
input.nextcharClass(c,true); // advance input cursor
continue;
}
retract();
break;
}
state = start_state;
String s = input.copyReplaceUnicodeEscapes(needs_escape);
if ( maybe_reserved )
{
Integer i = reservedWord.get(s);
if ( i != null )
return makeToken( (int) i );
}
return makeToken(IDENTIFIER_TOKEN,s);
}
/*
* prefix: 0
* accepts: 0x... | 0X... | 01... | 0... | 0
*/
case zero_state:
switch (nextchar())
{
case 'x':
case 'X':
switch(nextchar())
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D':
case 'E': case 'F':
state = hexinteger_state;
break;
default:
state = start_state;
error(kError_Lexical_General);
}
continue;
case '.':
state = decimal_state;
continue;
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
state = decimalinteger_state;
continue;
case 'E':
case 'e':
state = exponentstart_state;
continue;
case 'd':
case 'm':
case 'i':
case 'u':
if (!ctx.statics.es4_numerics)
retract();
state = start_state;
return makeToken(NUMBERLITERAL_TOKEN, input.copy());
default:
retract();
state = start_state;
return makeToken(NUMBERLITERAL_TOKEN, input.copy());
}
/*
* prefix: 0x<hex digits>
* accepts: 0x123f
*/
case hexinteger_state:
switch (nextchar())
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D':
case 'E': case 'F':
state = hexinteger_state;
continue;
case 'u':
case 'i':
if (!ctx.statics.es4_numerics)
retract();
state = start_state;
return makeToken( NUMBERLITERAL_TOKEN, input.copy() );
default:
retract();
state = start_state;
return makeToken( NUMBERLITERAL_TOKEN, input.copy() );
}
/*
* prefix: .
* accepts: .123 | .
*/
case dot_state:
switch (nextchar())
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
state = decimal_state;
continue;
case '.':
state = start_state;
if (nextchar()=='.')
return makeToken( TRIPLEDOT_TOKEN );
retract();
return makeToken( DOUBLEDOT_TOKEN );
case '<':
state = start_state;
return makeToken( DOTLESSTHAN_TOKEN );
default:
retract();
state = start_state;
return makeToken( DOT_TOKEN );
}
/*
* prefix: N
* accepts: 0.123 | 1.23 | 123 | 1e23 | 1e-23
*/
case decimalinteger_state:
switch (nextchar())
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
state = decimalinteger_state;
continue;
case '.':
state = decimal_state;
continue;
case 'd':
case 'm':
case 'u':
case 'i':
if (!ctx.statics.es4_numerics)
retract();
state = start_state;
return makeToken(NUMBERLITERAL_TOKEN, input.copy());
case 'E':
case 'e':
state = exponentstart_state;
continue;
default:
retract();
state = start_state;
return makeToken(NUMBERLITERAL_TOKEN, input.copy());
}
/*
* prefix: N.
* accepts: 0.1 | 1e23 | 1e-23
*/
case decimal_state:
switch (nextchar())
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
state = decimal_state;
continue;
case 'd':
case 'm':
if (!ctx.statics.es4_numerics)
retract();
state = start_state;
return makeToken(NUMBERLITERAL_TOKEN, input.copy());
case 'E':
case 'e':
state = exponentstart_state;
continue;
default:
retract();
state = start_state;
return makeToken(NUMBERLITERAL_TOKEN, input.copy());
}
/*
* prefix: ..e
* accepts: ..eN | ..e+N | ..e-N
*/
case exponentstart_state:
switch (nextchar())
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
case '+':
case '-':
state = exponent_state;
continue;
default:
error(kError_Lexical_General);
state = start_state;
continue;
// Issue: needs specific error here.
}
/*
* prefix: ..e
* accepts: ..eN | ..e+N | ..e-N
*/
case exponent_state:
switch (nextchar())
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
state = exponent_state;
continue;
case 'd':
case 'm':
if (!ctx.statics.es4_numerics)
retract();
state = start_state;
return makeToken(NUMBERLITERAL_TOKEN, input.copy());
default:
retract();
state = start_state;
return makeToken(NUMBERLITERAL_TOKEN, input.copy());
}
/*
* prefix: /
*/
case slash_state:
{
c = nextchar();
switch (c)
{
case '/': // line comment
state = start_state;
line_comment:
while ( (c=nextchar()) != 0)
{
if ( c == '\r' || c == '\n' )
{
isFirstTokenOnLine = true;
if (save_comments == false)
{
break line_comment;
}
retract(); // don't include newline in line comment. (Sec 7.3)
return makeCommentToken( SLASHSLASHCOMMENT_TOKEN, input.copyReplaceUnicodeEscapes() );
}
}
continue;
case '*':
if (save_comments == false)
{
block_comment:
while ( (c=nextchar()) != 0)
{
if ( c == '\r' || c == '\n' )
isFirstTokenOnLine = true;
if (c == '*')
{
c = nextchar();
if (c == '/' )
{
break block_comment;
}
retract();
}
}
state = start_state;
}
else
{
if (blockcommentbuf == null)
blockcommentbuf = new StringBuilder();
blockcommentbuf.append("/*");
state = blockcommentstart_state;
}
continue;
case '>':
if ( inXML > 0) // ignore this if outside an XML context
{
state = start_state;
return makeToken( XMLTAGENDEND_TOKEN );
}
// FALL THROUGH
default:
// If the last token read is any of these, then the '/' must start a div or div_assign...
int lb = currentToken.lookback;
if ( lb == IDENTIFIER_TOKEN || lb == NUMBERLITERAL_TOKEN || lb == RIGHTPAREN_TOKEN ||
lb == RIGHTBRACE_TOKEN || lb == RIGHTBRACKET_TOKEN )
{
/*
* tokens: /= /
*/
state = start_state;
if (c=='=')
return makeToken( DIVASSIGN_TOKEN );
retract();
return makeToken( DIV_TOKEN );
}
state = slashregexp_state;
retract();
continue;
}
}
/*
* tokens: /<regexpbody>/<regexpflags>
*/
case slashregexp_state:
switch (nextchar())
{
case '\\':
nextchar();
continue;
case '/':
regexp_flags = 0;
state = regexp_state;
continue;
case 0:
case '\n':
case '\r':
error(kError_Lexical_General);
state = start_state;
continue;
default:
state = slashregexp_state;
continue;
}
/*
* tokens: g | i | m | s | x . Note that s and x are custom extentions to match perl's functionality
* Also note we handle this via an array of boolean flags intead of state change logic.
* (5,1) + (5,2) + (5,3) + (5,4) + (5,5) is just too many states to handle this via state logic
*/
case regexp_state:
c = nextchar();
switch ( c )
{
case 'g':
if ((regexp_flags & 0x01) == 0)
{
regexp_flags |= 0x01;
continue;
}
error(kError_Lexical_General);
state = start_state;
continue;
case 'i':
if ((regexp_flags & 0x02) == 0)
{
regexp_flags |= 0x02;
continue;
}
error(kError_Lexical_General);
state = start_state;
continue;
case 'm':
if ((regexp_flags & 0x04) == 0)
{
regexp_flags |= 0x04;
continue;
}
error(kError_Lexical_General);
state = start_state;
continue;
case 's':
if ((regexp_flags & 0x08) == 0)
{
regexp_flags |= 0x08;
continue;
}
error(kError_Lexical_General);
state = start_state;
continue;
case 'x':
if ((regexp_flags & 0x10) == 0)
{
regexp_flags |= 0x10;
continue;
}
error(kError_Lexical_General);
state = start_state;
continue;
default:
if (Character.isJavaIdentifierPart(c))
{
error(kError_Lexical_General);
state = start_state;
continue;
}
retract();
state = start_state;
return makeToken( REGEXPLITERAL_TOKEN, input.copyReplaceUnicodeEscapes());
}
/*
* prefix: <!
*/
case xmlcommentorcdatastart_state:
switch ( nextchar() )
{
case '[':
if (nextchar()=='C' &&
nextchar()=='D' &&
nextchar()=='A' &&
nextchar()=='T' &&
nextchar()=='A' &&
nextchar()=='[')
{
state = xmlcdata_state;
continue;
}
break; // error
case '-':
if (nextchar()=='-')
{
state = xmlcomment_state;
continue;
}
}
error(kError_Lexical_General);
state = start_state;
continue;
case xmlcdata_state:
switch ( nextchar() )
{
case ']':
if (nextchar()==']' && nextchar()=='>')
{
state = start_state;
return makeToken(XMLMARKUP_TOKEN,input.substringReplaceUnicodeEscapes(startofxml,pos()));
}
continue;
case 0:
error(kError_Lexical_General);
state = start_state;
}
continue;
case xmlcomment_state:
while ( (c=nextchar()) != '-' && c != 0 )
;
if (c=='-' && nextchar() != '-')
{
continue;
}
// got -- if next is > ok else error
if ( nextchar()=='>')
{
state = start_state;
return makeToken(XMLMARKUP_TOKEN,input.substringReplaceUnicodeEscapes(startofxml,pos()));
}
error(kError_Lexical_General);
state = start_state;
continue;
case xmlpi_state:
while ( (c=nextchar()) != '?' && c != 0 )
;
if (c=='?' && nextchar() == '>')
{
state = start_state;
return makeToken(XMLMARKUP_TOKEN,input.substringReplaceUnicodeEscapes(startofxml,pos()));
}
if (c==0)
{
error(kError_Lexical_General);
state = start_state;
}
continue;
case xmltext_state:
{
switch(nextchar())
{
case '<': case '{':
{
retract();
String xmltext = input.substringReplaceUnicodeEscapes(startofxml,pos());
if( xmltext != null )
{
state = start_state;
return makeToken(XMLTEXT_TOKEN,xmltext);
}
else // if there is no leading text, then just return punctuation token to avoid empty text tokens
{
switch(nextchar())
{
case '<':
switch( nextchar() )
{
case '/': state = start_state; return makeToken( XMLTAGSTARTEND_TOKEN );
case '!': state = xmlcommentorcdatastart_state; continue;
case '?': state = xmlpi_state; continue;
default: retract(); state = start_state; return makeToken( LESSTHAN_TOKEN );
}
case '{':
state = start_state;
return makeToken( LEFTBRACE_TOKEN );
}
}
}
case 0:
state = start_state;
return makeToken( EOS_TOKEN );
}
continue;
}
case xmlliteral_state:
switch (nextchar())
{
case '{': // return makeToken( XMLPART_TOKEN
return makeToken(XMLPART_TOKEN, input.substringReplaceUnicodeEscapes(startofxml, pos()-1));
case '<':
if (nextchar()=='/')
{
--level;
nextchar();
mark();
retract();
state = endxmlname_state;
}
else
{
++level;
state = xmlliteral_state;
}
continue;
case '/':
if (nextchar()=='>')
{
--level;
if (level == 0)
{
state = start_state;
return makeToken(XMLLITERAL_TOKEN, input.substringReplaceUnicodeEscapes(startofxml, pos()+1));
}
}
continue;
case 0:
retract();
error(kError_Lexical_NoMatchingTag);
state = start_state;
continue;
default:
continue;
}
case endxmlname_state:
c = nextchar();
if (Character.isJavaIdentifierPart(c)||c==':')
{
continue;
}
switch(c)
{
case '{': // return makeToken( XMLPART_TOKEN
{
String xmltext = input.substringReplaceUnicodeEscapes(startofxml, pos()-1);
return makeToken(XMLPART_TOKEN, xmltext);
}
case '>':
retract();
nextchar();
if (level == 0)
{
String xmltext = input.substringReplaceUnicodeEscapes(startofxml, pos()+1);
state = start_state;
return makeToken(XMLLITERAL_TOKEN, xmltext);
}
state = xmlliteral_state;
continue;
default:
state = xmlliteral_state;
continue;
}
/*
* prefix: /*
*/
case blockcommentstart_state:
{
c = nextchar();
blockcommentbuf.append(c);
switch ( c )
{
case '*':
if ( nextchar() == '/' ){
state = start_state;
return makeCommentToken( BLOCKCOMMENT_TOKEN, new String());
}
retract();
state = doccomment_state;
continue;
case 0:
error(kError_BlockCommentNotTerminated);
state = start_state;
continue;
case '\n':
case '\r':
isFirstTokenOnLine = true;
default:
state = blockcomment_state;
continue;
}
}
/*
* prefix: /**
*/
case doccomment_state:
{
c = nextchar();
blockcommentbuf.append(c);
switch ( c )
{
case '*':
state = doccommentstar_state;
continue;
case '@':
if (doctextbuf == null)
doctextbuf = getDocTextBuffer(doctagname);
if( doctagname.length() > 0 )
{
doctextbuf.append("]]></").append(doctagname).append(">");
}
doctagname = "";
state = doccommenttag_state;
continue;
case '\r':
case '\n':
isFirstTokenOnLine = true;
if (doctextbuf == null)
doctextbuf = getDocTextBuffer(doctagname);
doctextbuf.append('\n');
continue;
case 0:
error(kError_BlockCommentNotTerminated);
state = start_state;
continue;
default:
if (doctextbuf == null)
doctextbuf = getDocTextBuffer(doctagname);
doctextbuf.append((char)(c));
continue;
}
}
case doccommentstar_state:
{
c = nextchar();
blockcommentbuf.append(c);
switch ( c )
{
case '/':
{
if (doctextbuf == null)
doctextbuf = getDocTextBuffer(doctagname);
if( doctagname.length() > 0 )
{
doctextbuf.append("]]></").append(doctagname).append(">");
}
String doctext = doctextbuf.toString(); // ??? does this needs escape conversion ???
state = start_state;
return makeCommentToken(DOCCOMMENT_TOKEN,doctext);
}
case '*':
continue;
case 0:
error(kError_BlockCommentNotTerminated);
state = start_state;
continue;
default:
state = doccomment_state;
continue;
// if not a slash, then keep looking for an end comment.
}
}
/*
* prefix: @
*/
case doccommenttag_state:
{
c = nextchar();
switch ( c )
{
case '*':
state = doccommentstar_state;
continue;
case ' ': case '\t': case '\r': case '\n':
{
if (doctextbuf == null)
doctextbuf = getDocTextBuffer(doctagname);
// skip extra whitespace --fixes bug on tag text parsing
// --but really, the problem is not here, it's in whatever reads asdoc output..
// --So if that gets fixed, feel free to delete the following.
while ( (c=nextchar()) == ' ' || c == '\t' )
;
retract();
if( doctagname.length() > 0 )
{
doctextbuf.append("\n<").append(doctagname).append("><![CDATA[");
}
state = doccomment_state;
continue;
}
case 0:
error(kError_BlockCommentNotTerminated);
state = start_state;
continue;
default:
doctagname += (char)(c);
continue;
}
}
/*
* prefix: /**
*/
case doccommentvalue_state:
switch ( nextchar() )
{
case '*':
state = doccommentstar_state;
continue;
case '@':
state = doccommenttag_state;
continue;
case 0:
error(kError_BlockCommentNotTerminated);
state = start_state;
continue;
default:
state = doccomment_state;
continue;
}
/*
* prefix: /*
*/
case blockcomment_state:
{
c = nextchar();
blockcommentbuf.append(c);
switch ( c )
{
case '*':
c = nextchar();
if (c == '/')
{
state = start_state;
blockcommentbuf.append(c);
String blocktext = blockcommentbuf.toString(); // ??? needs escape conversion
return makeCommentToken( BLOCKCOMMENT_TOKEN, blocktext );
}
retract();
break;
case '\r': case '\n':
isFirstTokenOnLine = true;
break;
case 0:
error(kError_BlockCommentNotTerminated);
state = start_state;
break;
}
continue;
}
/*
* skip error
*/
case error_state:
error(kError_Lexical_General);
skiperror();
state = start_state;
continue;
default:
error("invalid scanner state");
state = start_state;
return makeToken(EOS_TOKEN);
}
}
}