📄 jsscan.c
字号:
atom = TOKENBUF_TO_ATOM(); if (!atom) goto error; tp->pos.end.lineno = (uint16)ts->lineno; tp->t_op = JSOP_STRING; tp->t_atom = atom; tt = TOK_XMLATTR; goto out; case '>': tt = TOK_XMLTAGC; goto out; case '/': if (MatchChar(ts, '>')) { tt = TOK_XMLPTAGC; goto out; } /* FALL THROUGH */ bad_xml_char: default: js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_BAD_XML_CHARACTER); goto error; } /* NOTREACHED */ }#endif /* JS_HAS_XML_SUPPORT */retry: do { c = GetChar(ts); if (c == '\n') { ts->flags &= ~TSF_DIRTYLINE; if (ts->flags & TSF_NEWLINES) break; } } while (JS_ISSPACE(c)); tp = NewToken(ts, -1); if (c == EOF) { tt = TOK_EOF; goto out; } hadUnicodeEscape = JS_FALSE; if (JS_ISIDSTART(c) || (c == '\\' && (c = GetUnicodeEscape(ts), hadUnicodeEscape = JS_ISIDSTART(c)))) { INIT_TOKENBUF(); for (;;) { ADD_TO_TOKENBUF(c); c = GetChar(ts); if (c == '\\') { c = GetUnicodeEscape(ts); if (!JS_ISIDENT(c)) break; hadUnicodeEscape = JS_TRUE; } else { if (!JS_ISIDENT(c)) break; } } UngetChar(ts, c); /* * Check for keywords unless we saw Unicode escape or parser asks * to ignore keywords. */ if (!hadUnicodeEscape && !(ts->flags & TSF_KEYWORD_IS_NAME) && TOKENBUF_OK() && (kw = FindKeyword(TOKENBUF_BASE(), TOKENBUF_LENGTH()))) { if (kw->tokentype == TOK_RESERVED) { if (!js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_WARNING | JSREPORT_STRICT, JSMSG_RESERVED_ID, kw->chars)) { goto error; } } else if (kw->version <= JSVERSION_NUMBER(cx)) { tt = kw->tokentype; tp->t_op = (JSOp) kw->op; goto out; } } atom = TOKENBUF_TO_ATOM(); if (!atom) goto error; tp->t_op = JSOP_NAME; tp->t_atom = atom; tt = TOK_NAME; goto out; } if (JS7_ISDEC(c) || (c == '.' && JS7_ISDEC(PeekChar(ts)))) { jsint radix; const jschar *endptr; jsdouble dval; radix = 10; INIT_TOKENBUF(); if (c == '0') { ADD_TO_TOKENBUF(c); c = GetChar(ts); if (JS_TOLOWER(c) == 'x') { ADD_TO_TOKENBUF(c); c = GetChar(ts); radix = 16; } else if (JS7_ISDEC(c)) { radix = 8; } } while (JS7_ISHEX(c)) { if (radix < 16) { if (JS7_ISLET(c)) break; /* * We permit 08 and 09 as decimal numbers, which makes our * behaviour a superset of the ECMA numeric grammar. We might * not always be so permissive, so we warn about it. */ if (radix == 8 && c >= '8') { if (!js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_WARNING, JSMSG_BAD_OCTAL, c == '8' ? "08" : "09")) { goto error; } radix = 10; } } ADD_TO_TOKENBUF(c); c = GetChar(ts); } if (radix == 10 && (c == '.' || JS_TOLOWER(c) == 'e')) { if (c == '.') { do { ADD_TO_TOKENBUF(c); c = GetChar(ts); } while (JS7_ISDEC(c)); } if (JS_TOLOWER(c) == 'e') { ADD_TO_TOKENBUF(c); c = GetChar(ts); if (c == '+' || c == '-') { ADD_TO_TOKENBUF(c); c = GetChar(ts); } if (!JS7_ISDEC(c)) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_MISSING_EXPONENT); goto error; } do { ADD_TO_TOKENBUF(c); c = GetChar(ts); } while (JS7_ISDEC(c)); } } /* Put back the next char and NUL-terminate tokenbuf for js_strto*. */ UngetChar(ts, c); ADD_TO_TOKENBUF(0); if (!TOKENBUF_OK()) goto error; if (radix == 10) { if (!js_strtod(cx, TOKENBUF_BASE(), &endptr, &dval)) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_OUT_OF_MEMORY); goto error; } } else { if (!js_strtointeger(cx, TOKENBUF_BASE(), &endptr, radix, &dval)) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_OUT_OF_MEMORY); goto error; } } tp->t_dval = dval; tt = TOK_NUMBER; goto out; } if (c == '"' || c == '\'') { qc = c; INIT_TOKENBUF(); while ((c = GetChar(ts)) != qc) { if (c == '\n' || c == EOF) { UngetChar(ts, c); js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_UNTERMINATED_STRING); goto error; } if (c == '\\') { switch (c = GetChar(ts)) { case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; default: if ('0' <= c && c < '8') { int32 val = JS7_UNDEC(c); c = PeekChar(ts); if ('0' <= c && c < '8') { val = 8 * val + JS7_UNDEC(c); GetChar(ts); c = PeekChar(ts); if ('0' <= c && c < '8') { int32 save = val; val = 8 * val + JS7_UNDEC(c); if (val <= 0377) GetChar(ts); else val = save; } } c = (jschar)val; } else if (c == 'u') { jschar cp[4]; if (PeekChars(ts, 4, cp) && JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3])) { c = (((((JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1])) << 4) + JS7_UNHEX(cp[2])) << 4) + JS7_UNHEX(cp[3]); SkipChars(ts, 4); } } else if (c == 'x') { jschar cp[2]; if (PeekChars(ts, 2, cp) && JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1])) { c = (JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1]); SkipChars(ts, 2); } } else if (c == '\n' && JS_VERSION_IS_ECMA(cx)) { /* ECMA follows C by removing escaped newlines. */ continue; } break; } } ADD_TO_TOKENBUF(c); } atom = TOKENBUF_TO_ATOM(); if (!atom) goto error; tp->pos.end.lineno = (uint16)ts->lineno; tp->t_op = JSOP_STRING; tp->t_atom = atom; tt = TOK_STRING; goto out; } switch (c) { case '\n': tt = TOK_EOL; goto eol_out; case ';': tt = TOK_SEMI; break; case '[': tt = TOK_LB; break; case ']': tt = TOK_RB; break; case '{': tt = TOK_LC; break; case '}': tt = TOK_RC; break; case '(': tt = TOK_LP; break; case ')': tt = TOK_RP; break; case ',': tt = TOK_COMMA; break; case '?': tt = TOK_HOOK; break; case '.':#if JS_HAS_XML_SUPPORT if (MatchChar(ts, c)) tt = TOK_DBLDOT; else#endif tt = TOK_DOT; break; case ':':#if JS_HAS_XML_SUPPORT if (MatchChar(ts, c)) { tt = TOK_DBLCOLON; break; }#endif /* * Default so compiler can modify to JSOP_GETTER if 'p getter: v' in an * object initializer, likewise for setter. */ tp->t_op = JSOP_NOP; tt = TOK_COLON; break; case '|': if (MatchChar(ts, c)) { tt = TOK_OR; } else if (MatchChar(ts, '=')) { tp->t_op = JSOP_BITOR; tt = TOK_ASSIGN; } else { tt = TOK_BITOR; } break; case '^': if (MatchChar(ts, '=')) { tp->t_op = JSOP_BITXOR; tt = TOK_ASSIGN; } else { tt = TOK_BITXOR; } break; case '&': if (MatchChar(ts, c)) { tt = TOK_AND; } else if (MatchChar(ts, '=')) { tp->t_op = JSOP_BITAND; tt = TOK_ASSIGN; } else { tt = TOK_BITAND; } break; case '=': if (MatchChar(ts, c)) { tp->t_op = MatchChar(ts, c) ? JSOP_NEW_EQ : (JSOp)cx->jsop_eq; tt = TOK_EQOP; } else { tp->t_op = JSOP_NOP; tt = TOK_ASSIGN; } break; case '!': if (MatchChar(ts, '=')) { tp->t_op = MatchChar(ts, '=') ? JSOP_NEW_NE : (JSOp)cx->jsop_ne; tt = TOK_EQOP; } else { tp->t_op = JSOP_NOT; tt = TOK_UNARYOP; } break;#if JS_HAS_XML_SUPPORT case '@': tt = TOK_AT; break;#endif case '<':#if JS_HAS_XML_SUPPORT /* * After much testing, it's clear that Postel's advice to protocol * designers ("be liberal in what you accept, and conservative in what * you send") invites a natural-law repercussion for JS as "protocol": * * "If you are liberal in what you accept, others will utterly fail to * be conservative in what they send." * * Which means you will get <!-- comments to end of line in the middle * of .js files, and after if conditions whose then statements are on * the next line, and other wonders. See at least the following bugs: * https://bugzilla.mozilla.org/show_bug.cgi?id=309242 * https://bugzilla.mozilla.org/show_bug.cgi?id=309712 * https://bugzilla.mozilla.org/show_bug.cgi?id=310993 * * So without JSOPTION_XML, we never scan an XML comment or CDATA * literal. We always scan <! as the start of an HTML comment hack * to end of line, used since Netscape 2 to hide script tag content * from script-unaware browsers. */ if ((ts->flags & TSF_OPERAND) && (JS_HAS_XML_OPTION(cx) || PeekChar(ts) != '!')) { /* Check for XML comment or CDATA section. */ if (MatchChar(ts, '!')) { INIT_TOKENBUF(); /* Scan XML comment. */ if (MatchChar(ts, '-')) { if (!MatchChar(ts, '-')) goto bad_xml_markup; while ((c = GetChar(ts)) != '-' || !MatchChar(ts, '-')) { if (c == EOF) goto bad_xml_markup; ADD_TO_TOKENBUF(c); } tt = TOK_XMLCOMMENT; tp->t_op = JSOP_XMLCOMMENT; goto finish_xml_markup; } /* Scan CDATA section. */ if (MatchChar(ts, '[')) { jschar cp[6];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -