txBoolean fxGetNextIdentiferX(txParser* parser, txU4* value) { fxGetNextCharacter(parser); if (parser->character == 'u') { fxGetNextCharacter(parser); if (parser->character == '{') { fxGetNextCharacter(parser); while (fxGetNextStringX(parser, parser->character, value)) { fxGetNextCharacter(parser); } if (parser->character == '}') { fxGetNextCharacter(parser); return 1; } } else { if (fxGetNextStringX(parser, parser->character, value)) { fxGetNextCharacter(parser); if (fxGetNextStringX(parser, parser->character, value)) { fxGetNextCharacter(parser); if (fxGetNextStringX(parser, parser->character, value)) { fxGetNextCharacter(parser); if (fxGetNextStringX(parser, parser->character, value)) { fxGetNextCharacter(parser); return 1; } } } } } } return 0; }
void fxGetNextTokenTemplate(txParser* parser) { parser->crlf2 = 0; parser->escaped2 = 0; parser->integer2 = 0; parser->modifierLength2 = 0; parser->modifier2 = parser->emptyString; parser->number2 = 0; parser->rawLength2 = 0; parser->raw2 = parser->emptyString; parser->stringLength2 = 0; parser->string2 = parser->emptyString; parser->symbol2 = C_NULL; parser->token2 = XS_NO_TOKEN; fxGetNextString(parser, '`'); if (parser->character == '{') parser->token2 = XS_TOKEN_TEMPLATE_MIDDLE; else parser->token2 = XS_TOKEN_TEMPLATE_TAIL; fxGetNextCharacter(parser); parser->line = parser->line2; parser->crlf = parser->crlf2; parser->escaped = parser->escaped2; parser->integer = parser->integer2; parser->modifierLength = parser->modifierLength2; parser->modifier = parser->modifier2; parser->number = parser->number2; parser->rawLength = parser->rawLength2; parser->raw = parser->raw2; parser->stringLength = parser->stringLength2; parser->string = parser->string2; parser->symbol = parser->symbol2; parser->token = parser->token2; parser->ahead = 0; }
void fxParserTree(txParser* parser, void* theStream, txGetter theGetter, txUnsigned flags, txString* name) { parser->stream = theStream; parser->getter = theGetter; parser->line = 1; parser->flags = flags; parser->modifier = parser->emptyString; parser->string = parser->emptyString; parser->line2 = 1; parser->modifier2 = parser->emptyString; parser->string2 = parser->emptyString; fxGetNextCharacter(parser); fxGetNextToken(parser); parser->root = NULL; if (parser->flags & mxProgramFlag) fxProgram(parser); else fxModule(parser); #ifdef mxTreePrint fxTreePrint(parser, parser->root); #endif if (parser->errorCount) return; if (name) *name = parser->name; }
void fxParseJSON(txMachine* the, void* theStream, txGetter theGetter) { txSlot* aStack = the->stack; txScriptParser *aParser; aParser = the->parser; if (NULL == aParser) { aParser = c_malloc(sizeof(txScriptParser)); if (NULL == aParser) { const char *msg = "Out of memory!"; #ifdef mxDebug fxDebugLoop(the, (char *)msg); #endif fxThrowMessage(the, XS_UNKNOWN_ERROR, (char *)msg); } the->parser = aParser; } c_memset(aParser, 0, sizeof(txScriptParser) - sizeof(aParser->buffer)); aParser->the = the; aParser->stream = theStream; aParser->getter = theGetter; aParser->path = C_NULL; aParser->line2 = 0; mxZeroSlot(--the->stack); aParser->flags = the->stack; aParser->flags->value.string = mxEmptyString.value.string; aParser->flags->kind = mxEmptyString.kind; mxZeroSlot(--the->stack); aParser->string = the->stack; aParser->string->value.string = mxEmptyString.value.string; aParser->string->kind = mxEmptyString.kind; mxZeroSlot(--the->stack); aParser->flags2 = the->stack; aParser->flags2->value.string = mxEmptyString.value.string; aParser->flags2->kind = mxEmptyString.kind; mxZeroSlot(--the->stack); aParser->string2 = the->stack; aParser->string2->value.string = mxEmptyString.value.string; aParser->string2->kind = mxEmptyString.kind; fxGetNextCharacter(aParser); fxGetNextJSONToken(aParser); fxGetNextJSONToken(aParser); fxParseJSONValue(aParser); fxMatchToken(aParser, XS_TOKEN_EOF); if (aParser->errorCount > 0) { the->stack = aStack; c_strcpy(aParser->buffer, "JSON error(s)!"); #ifdef mxDebug fxDebugLoop(the, aParser->buffer); #endif fxThrowMessage(the, XS_SYNTAX_ERROR, aParser->buffer); } }
void fxGetNextNumberO(txParser* parser, int c) { txNumber aNumber = c - '0'; for (;;) { fxGetNextCharacter(parser); c = parser->character; if (('0' <= c) && (c <= '7')) aNumber = (aNumber * 8) + (c - '0'); else break; } fxGetNextNumber(parser, aNumber); }
void fxGetNextNumberB(txParser* parser) { txNumber aNumber = 0; int c; for (;;) { fxGetNextCharacter(parser); c = parser->character; if (('0' <= c) && (c <= '1')) aNumber = (aNumber * 2) + (c - '0'); else break; } fxGetNextNumber(parser, aNumber); }
void fxGetNextNumberX(txParser* parser) { txNumber aNumber = 0; int c; for (;;) { fxGetNextCharacter(parser); c = parser->character; if (('0' <= c) && (c <= '9')) aNumber = (aNumber * 16) + (c - '0'); else if (('a' <= c) && (c <= 'f')) aNumber = (aNumber * 16) + (10 + c - 'a'); else if (('A' <= c) && (c <= 'F')) aNumber = (aNumber * 16) + (10 + c - 'A'); else break; } fxGetNextNumber(parser, aNumber); }
void fxGetNextNumberE(txParser* parser, int parseDot) { txString p = parser->buffer; if (parser->character == '-') { *p++ = (char)parser->character; fxGetNextCharacter(parser); } if (!parseDot) *p++ = '.'; while (('0' <= parser->character) && (parser->character <= '9')) { *p++ = (char)parser->character; fxGetNextCharacter(parser); } if (parseDot) { if (parser->character == '.') { *p++ = (char)parser->character; fxGetNextCharacter(parser); while (('0' <= parser->character) && (parser->character <= '9')) { *p++ = (char)parser->character; fxGetNextCharacter(parser); } } else *p++ = '.'; } if ((parser->character == 'e') || (parser->character == 'E')) { *p++ = '0'; *p++ = (char)parser->character; fxGetNextCharacter(parser); if ((parser->character == '+') || (parser->character == '-')) { *p++ = (char)parser->character; fxGetNextCharacter(parser); } while (('0' <= parser->character) && (parser->character <= '9')) { *p++ = (char)parser->character; fxGetNextCharacter(parser); } } *p++ = 0; fxGetNextNumber(parser, fxStringToNumber(parser->dtoa, parser->buffer, 1)); }
void fxGetNextJSONToken(txScriptParser* theParser) { txMachine* the = theParser->the; int c; txString p; txString q; txString r; txString s; txU4 t = 0; txNumber aNumber; theParser->line = theParser->line2; theParser->crlf = theParser->crlf2; theParser->escaped = theParser->escaped2; theParser->flags->value.string = theParser->flags2->value.string; theParser->integer = theParser->integer2; theParser->number = theParser->number2; theParser->string->value.string = theParser->string2->value.string; theParser->symbol = theParser->symbol2; theParser->token = theParser->token2; theParser->crlf2 = 0; theParser->escaped2 = 0; theParser->flags2->value.string = mxEmptyString.value.string; theParser->integer2 = 0; theParser->number2 = 0; theParser->string2->value.string = mxEmptyString.value.string; theParser->symbol2 = C_NULL; theParser->token2 = XS_NO_TOKEN; while (theParser->token2 == XS_NO_TOKEN) { switch (theParser->character) { case C_EOF: theParser->token2 = XS_TOKEN_EOF; break; case 10: theParser->line2++; fxGetNextCharacter(theParser); theParser->crlf2 = 1; break; case 13: theParser->line2++; fxGetNextCharacter(theParser); if (theParser->character == 10) fxGetNextCharacter(theParser); theParser->crlf2 = 1; break; case '\t': case ' ': fxGetNextCharacter(theParser); break; case '0': fxGetNextCharacter(theParser); c = theParser->character; if (c == '.') { fxGetNextCharacter(theParser); c = theParser->character; if ((('0' <= c) && (c <= '9')) || (c == 'e') || (c == 'E')) fxGetNextNumber(theParser, 0); else { theParser->number2 = 0; theParser->token2 = XS_TOKEN_NUMBER; } } else if ((c == 'e') || (c == 'E')) { fxGetNextNumber(theParser, 0); } else if ((c == 'x') || (c == 'X')) { p = theParser->buffer; *p++ = '0'; *p++ = 'x'; for (;;) { fxGetNextCharacter(theParser); c = theParser->character; if (('0' <= c) && (c <= '9')) *p++ = c; else if (('A' <= c) && (c <= 'Z')) *p++ = c; else if (('a' <= c) && (c <= 'z')) *p++ = c; else break; } *p = 0; theParser->number2 = fxStringToNumber(theParser->the, theParser->buffer, 1); theParser->integer2 = (txInteger)theParser->number2; aNumber = theParser->integer2; if (theParser->number2 == aNumber) theParser->token2 = XS_TOKEN_INTEGER; else theParser->token2 = XS_TOKEN_NUMBER; } else { theParser->integer2 = 0; theParser->token2 = XS_TOKEN_INTEGER; } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': fxGetNextNumber(theParser, 1); break; case ',': theParser->token2 = XS_TOKEN_COMMA; fxGetNextCharacter(theParser); break; case ':': theParser->token2 = XS_TOKEN_COLON; fxGetNextCharacter(theParser); break; case '[': theParser->token2 = XS_TOKEN_LEFT_BRACKET; fxGetNextCharacter(theParser); break; case ']': theParser->token2 = XS_TOKEN_RIGHT_BRACKET; fxGetNextCharacter(theParser); break; case '{': theParser->token2 = XS_TOKEN_LEFT_BRACE; fxGetNextCharacter(theParser); break; case '}': theParser->token2 = XS_TOKEN_RIGHT_BRACE; fxGetNextCharacter(theParser); break; case '"': p = theParser->buffer; q = p + sizeof(theParser->buffer) - 1; r = C_NULL; fxGetNextCharacter(theParser); for (;;) { if (theParser->character == C_EOF) { fxReportParserError(theParser, "end of file in string"); break; } else if ((theParser->character == 10) || (theParser->character == 13)) { fxReportParserError(theParser, "end of line in string"); break; } else if ((0 <= theParser->character) && (theParser->character < 32)) { fxReportParserError(theParser, "invalid character in string"); break; } else if (theParser->character == '"') { fxGetNextCharacter(theParser); break; } else if (theParser->character == '"') { fxGetNextCharacter(theParser); break; } else if (theParser->character == '\\') { theParser->escaped2 = 1; r = C_NULL; fxGetNextCharacter(theParser); switch (theParser->character) { case 10: theParser->line2++; fxGetNextCharacter(theParser); break; case 13: theParser->line2++; fxGetNextCharacter(theParser); if (theParser->character == 10) fxGetNextCharacter(theParser); break; case '\'': if (p < q) *p++ = '\''; fxGetNextCharacter(theParser); break; case '"': if (p < q) *p++ = '"'; fxGetNextCharacter(theParser); break; case '\\': if (p < q) *p++ = '\\'; fxGetNextCharacter(theParser); break; case '0': if (p < q) *p++ = 0; fxGetNextCharacter(theParser); break; case 'b': if (p < q) *p++ = '\b'; fxGetNextCharacter(theParser); break; case 'f': if (p < q) *p++ = '\f'; fxGetNextCharacter(theParser); break; case 'n': if (p < q) *p++ = '\n'; fxGetNextCharacter(theParser); break; case 'r': if (p < q) *p++ = '\r'; fxGetNextCharacter(theParser); break; case 't': if (p < q) *p++ = '\t'; fxGetNextCharacter(theParser); break; case 'u': r = p; t = 5; if (p < q) *p++ = 'u'; fxGetNextCharacter(theParser); break; case 'v': if (p < q) *p++ = '\v'; fxGetNextCharacter(theParser); break; case 'x': r = p; t = 3; if (p < q) *p++ = 'x'; fxGetNextCharacter(theParser); break; default: p = (txString)fsX2UTF8(theParser, theParser->character, (txU1*)p, q - p); fxGetNextCharacter(theParser); break; } } else { p = (txString)fsX2UTF8(theParser, theParser->character, (txU1*)p, q - p); if (r) { if ((txU4)(p - r) > t) r = C_NULL; else if (((txU4)(p - r) == t) && (p < q)) { *p = 0; t = c_strtoul(r + 1, &s, 16); if (!*s) p = (txString)fsX2UTF8(theParser, t, (txU1*)r, q - r); r = C_NULL; } } fxGetNextCharacter(theParser); } } *p = 0; if (p == q) fxReportParserError(theParser, "string overflow"); fxCopyStringC(theParser->the, theParser->string2, theParser->buffer); theParser->token2 = XS_TOKEN_STRING; break; default: if (fxIsIdentifierFirst(theParser->character)) { p = theParser->buffer; q = p + sizeof(theParser->buffer) - 1; for (;;) { if (p == q) { fxReportParserError(theParser, "identifier overflow"); break; } *p++ = theParser->character; fxGetNextCharacter(theParser); if (!fxIsIdentifierNext(theParser->character)) break; } *p = 0; fxGetNextJSONKeyword(theParser); } else { mxDebug1(theParser->the, XS_SYNTAX_ERROR, "invalid character %d", theParser->character); fxGetNextCharacter(theParser); } break; } } }
void fxGetNextTokenAux(txParser* parser) { int c; txString p; txString q; txU4 t = 0; parser->crlf2 = 0; parser->escaped2 = 0; parser->integer2 = 0; parser->modifierLength2 = 0; parser->modifier2 = parser->emptyString; parser->number2 = 0; parser->rawLength2 = 0; parser->raw2 = parser->emptyString; parser->stringLength2 = 0; parser->string2 = parser->emptyString; parser->symbol2 = C_NULL; parser->token2 = XS_NO_TOKEN; while (parser->token2 == XS_NO_TOKEN) { switch (parser->character) { case C_EOF: parser->token2 = XS_TOKEN_EOF; break; case 10: parser->line2++; fxGetNextCharacter(parser); parser->crlf2 = 1; #ifdef mxColor parser->startOffset2 = parser->offset; #endif break; case 13: parser->line2++; fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); parser->crlf2 = 1; #ifdef mxColor parser->startOffset2 = parser->offset; #endif break; case 11: case 12: case 160: case ' ': case '\t': fxGetNextCharacter(parser); #ifdef mxColor parser->startOffset2 = parser->offset; #endif break; case '0': fxGetNextCharacter(parser); c = parser->character; if (c == '.') { fxGetNextCharacter(parser); c = parser->character; if ((('0' <= c) && (c <= '9')) || (c == 'e') || (c == 'E')) fxGetNextNumberE(parser, 0); else { parser->number2 = 0; parser->token2 = XS_TOKEN_NUMBER; } } else if ((c == 'b') || (c == 'B')) { fxGetNextNumberB(parser); } else if ((c == 'e') || (c == 'E')) { fxGetNextNumberE(parser, 0); } else if ((c == 'o') || (c == 'O')) { fxGetNextNumberO(parser, '0'); } else if ((c == 'x') || (c == 'X')) { fxGetNextNumberX(parser); } else if (('0' <= c) && (c <= '7')) { if ((parser->flags & mxStrictFlag)) fxReportParserError(parser, "octal number (strict mode)"); fxGetNextNumberO(parser, c); } else { parser->integer2 = 0; parser->token2 = XS_TOKEN_INTEGER; } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': fxGetNextNumberE(parser, 1); break; case '.': fxGetNextCharacter(parser); if (parser->character == '.') { fxGetNextCharacter(parser); if (parser->character == '.') { parser->token2 = XS_TOKEN_SPREAD; fxGetNextCharacter(parser); } else { fxReportParserError(parser, "invalid character %d", parser->character); } } else if (('0' <= parser->character) && (parser->character <= '9')) fxGetNextNumberE(parser, 0); else parser->token2 = XS_TOKEN_DOT; break; case ',': parser->token2 = XS_TOKEN_COMMA; fxGetNextCharacter(parser); break; case ';': parser->token2 = XS_TOKEN_SEMICOLON; fxGetNextCharacter(parser); break; case ':': parser->token2 = XS_TOKEN_COLON; fxGetNextCharacter(parser); break; case '?': parser->token2 = XS_TOKEN_QUESTION_MARK; fxGetNextCharacter(parser); break; case '(': parser->token2 = XS_TOKEN_LEFT_PARENTHESIS; fxGetNextCharacter(parser); break; case ')': parser->token2 = XS_TOKEN_RIGHT_PARENTHESIS; fxGetNextCharacter(parser); break; case '[': parser->token2 = XS_TOKEN_LEFT_BRACKET; fxGetNextCharacter(parser); break; case ']': parser->token2 = XS_TOKEN_RIGHT_BRACKET; fxGetNextCharacter(parser); break; case '{': parser->token2 = XS_TOKEN_LEFT_BRACE; fxGetNextCharacter(parser); break; case '}': parser->token2 = XS_TOKEN_RIGHT_BRACE; fxGetNextCharacter(parser); break; case '=': fxGetNextCharacter(parser); if (parser->character == '=') { fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_STRICT_EQUAL; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_EQUAL; } else if (parser->character == '>') { parser->token2 = XS_TOKEN_ARROW; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_ASSIGN; break; case '<': fxGetNextCharacter(parser); if (parser->character == '<') { fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_LEFT_SHIFT_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_LEFT_SHIFT; } else if (parser->character == '=') { parser->token2 = XS_TOKEN_LESS_EQUAL; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_LESS; break; case '>': fxGetNextCharacter(parser); if (parser->character == '>') { fxGetNextCharacter(parser); if (parser->character == '>') { fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_UNSIGNED_RIGHT_SHIFT_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_UNSIGNED_RIGHT_SHIFT; } else if (parser->character == '=') { parser->token2 = XS_TOKEN_SIGNED_RIGHT_SHIFT_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_SIGNED_RIGHT_SHIFT; } else if (parser->character == '=') { parser->token2 = XS_TOKEN_MORE_EQUAL; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_MORE; break; case '!': fxGetNextCharacter(parser); if (parser->character == '=') { fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_STRICT_NOT_EQUAL; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_NOT_EQUAL; } else parser->token2 = XS_TOKEN_NOT; break; case '~': parser->token2 = XS_TOKEN_BIT_NOT; fxGetNextCharacter(parser); break; case '&': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_BIT_AND_ASSIGN; fxGetNextCharacter(parser); } else if (parser->character == '&') { parser->token2 = XS_TOKEN_AND; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_BIT_AND; break; case '|': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_BIT_OR_ASSIGN; fxGetNextCharacter(parser); } else if (parser->character == '|') { parser->token2 = XS_TOKEN_OR; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_BIT_OR; break; case '^': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_BIT_XOR_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_BIT_XOR; break; case '+': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_ADD_ASSIGN; fxGetNextCharacter(parser); } else if (parser->character == '+') { parser->token2 = XS_TOKEN_INCREMENT; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_ADD; break; case '-': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_SUBTRACT_ASSIGN; fxGetNextCharacter(parser); } else if (parser->character == '-') { parser->token2 = XS_TOKEN_DECREMENT; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_SUBTRACT; break; case '*': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_MULTIPLY_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_MULTIPLY; break; case '/': fxGetNextCharacter(parser); if (parser->character == '*') { fxGetNextCharacter(parser); for (;;) { if (parser->character == (txU4)C_EOF) break; else if (parser->character == 10) { parser->line2++; fxGetNextCharacter(parser); } else if (parser->character == 13) { parser->line2++; fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); } else if (parser->character == '*') { fxGetNextCharacter(parser); if (parser->character == '/') { fxGetNextCharacter(parser); break; } } else fxGetNextCharacter(parser); } } else if (parser->character == '/') { fxGetNextCharacter(parser); p = parser->buffer; q = p + parser->bufferSize - 1; while ((parser->character != (txU4)C_EOF) && (parser->character != 10) && (parser->character != 13)) { if (p < q) *p++ = (char)parser->character; fxGetNextCharacter(parser); } *p = 0; p = parser->buffer; if (!c_strcmp(p, "@module")) { if (parser->token2 == XS_NO_TOKEN) parser->flags |= mxCommonModuleFlag; } else if (!c_strcmp(p, "@program")) { if (parser->token2 == XS_NO_TOKEN) parser->flags |= mxCommonProgramFlag; } else if (parser->flags & mxDebugFlag) { if (!c_strncmp(p, "@line ", 6)) { p += 6; t = 0; c = *p++; while (('0' <= c) && (c <= '9')) { t = (t * 10) + (c - '0'); c = *p++; } if (!t) goto bail; if (c == ' ') { c = *p++; if (c != '"') goto bail; q = p; c = *q++; while ((c != 0) && (c != 10) && (c != 13) && (c != '"')) c = *q++; if (c != '"') goto bail; *(--q) = 0; parser->path = fxNewParserSymbol(parser, p); } parser->line2 = t - 1; } else if (!c_strncmp(p, "# sourceMappingURL=", 19) || !c_strncmp(p, "@ sourceMappingURL=", 19)) { p += 19; q = p; c = *q++; while ((c != 0) && (c != 10) && (c != 13)) c = *q++; *q = 0; parser->name = fxNewParserString(parser, p, q - p); } } bail: ; } else if ((parser->crlf2) || (fxAcceptRegExp(parser))) { parser->token2 = XS_TOKEN_NULL; p = parser->buffer; q = p + parser->bufferSize - 1; for (;;) { if (p == q) { fxReportParserWarning(parser, "regular expression overflow"); break; } else if (parser->character == (txU4)C_EOF) { fxReportParserWarning(parser, "end of file in regular expression"); break; } else if ((parser->character == 10) || (parser->character == 13)) { fxReportParserWarning(parser, "end of line in regular expression"); break; } else if (parser->character == '/') { *p = 0; parser->stringLength2 = p - parser->buffer; parser->string2 = fxNewParserString(parser, parser->buffer, parser->stringLength2); parser->token2 = XS_TOKEN_REGEXP; p = parser->buffer; q = p + parser->bufferSize - 1; for (;;) { fxGetNextCharacter(parser); if (p == q) { fxReportParserWarning(parser, "regular expression overflow"); break; } else if (fxIsIdentifierNext((char)parser->character)) *p++ = (char)parser->character; else { if (p != parser->buffer) { *p = 0; parser->modifierLength2 = p - parser->buffer; parser->modifier2 = fxNewParserString(parser, parser->buffer, parser->modifierLength2); } break; } } break; } else if (parser->character == '\\') { *p++ = (char)parser->character; fxGetNextCharacter(parser); if (p == q) { fxReportParserWarning(parser, "regular expression overflow"); break; } } p = (txString)fsX2UTF8(parser->character, (txU1*)p, q - p); //*p++ = parser->character; fxGetNextCharacter(parser); } } else if (parser->character == '=') { parser->token2 = XS_TOKEN_DIVIDE_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_DIVIDE; break; case '%': fxGetNextCharacter(parser); if (parser->character == '=') { parser->token2 = XS_TOKEN_MODULO_ASSIGN; fxGetNextCharacter(parser); } else parser->token2 = XS_TOKEN_MODULO; break; case '"': case '\'': c = parser->character; fxGetNextCharacter(parser); fxGetNextString(parser, c); parser->token2 = XS_TOKEN_STRING; fxGetNextCharacter(parser); break; case '`': fxGetNextCharacter(parser); fxGetNextString(parser, '`'); if (parser->character == '{') parser->token2 = XS_TOKEN_TEMPLATE_HEAD; else parser->token2 = XS_TOKEN_TEMPLATE; fxGetNextCharacter(parser); break; case '@': if (parser->flags & mxCFlag) parser->token2 = XS_TOKEN_HOST; else fxReportParserError(parser, "invalid character @"); fxGetNextCharacter(parser); break; default: p = parser->buffer; q = p + parser->bufferSize - 1; if (fxIsIdentifierFirst((char)parser->character)) { *p++ = (char)parser->character; fxGetNextCharacter(parser); } else if (parser->character == '\\') { t = 0; if (fxGetNextIdentiferX(parser, &t)) p = (txString)fsX2UTF8(t, (txU1*)p, q - p); else p = C_NULL; } else p = C_NULL; if (p) { for (;;) { if (p == q) { fxReportParserWarning(parser, "identifier overflow"); break; } if (fxIsIdentifierNext((char)parser->character)) { *p++ = (char)parser->character; fxGetNextCharacter(parser); } else if (parser->character == '\\') { t = 0; if (fxGetNextIdentiferX(parser, &t)) p = (txString)fsX2UTF8(t, (txU1*)p, q - p); else { p = C_NULL; break; } } else { *p = 0; fxGetNextKeyword(parser); break; } } } if (!p) { fxReportParserWarning(parser, "invalid character %d", parser->character); fxGetNextCharacter(parser); } break; } } }
void fxGetNextString(txParser* parser, int c) { txString p = parser->buffer; txString q = p + parser->bufferSize - 1; txString r, s; char character; txU4 t; for (;;) { if (parser->character == (txU4)C_EOF) { fxReportParserError(parser, "end of file in string"); break; } else if (parser->character == 10) { parser->line2++; if (c == '`') { p = (txString)fsX2UTF8(10, (txU1*)p, q - p); fxGetNextCharacter(parser); } else { fxReportParserError(parser, "end of line in string"); break; } } else if (parser->character == 13) { parser->line2++; if (c == '`') { p = (txString)fsX2UTF8(10, (txU1*)p, q - p); fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); } else { fxReportParserError(parser, "end of line in string"); break; } } else if (parser->character == (txU4)c) { break; } else if (parser->character == '$') { fxGetNextCharacter(parser); if ((c == '`') && (parser->character == '{')) break; p = (txString)fsX2UTF8('$', (txU1*)p, q - p); } else if (parser->character == '\\') { parser->escaped2 = 1; p = (txString)fsX2UTF8('\\', (txU1*)p, q - p); fxGetNextCharacter(parser); switch (parser->character) { case 10: parser->line2++; p = (txString)fsX2UTF8(10, (txU1*)p, q - p); fxGetNextCharacter(parser); break; case 13: parser->line2++; p = (txString)fsX2UTF8(10, (txU1*)p, q - p); fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); break; default: p = (txString)fsX2UTF8(parser->character, (txU1*)p, q - p); fxGetNextCharacter(parser); break; } } else { p = (txString)fsX2UTF8(parser->character, (txU1*)p, q - p); fxGetNextCharacter(parser); } } *p = 0; if (p == q) fxReportParserWarning(parser, "string overflow"); parser->rawLength2 = p - parser->buffer; parser->raw2 = fxNewParserString(parser, parser->buffer, parser->rawLength2); if (parser->escaped2) { p = parser->buffer; q = p + parser->bufferSize - 1; s = parser->raw2; character = *s++; while (character) { if (character == '\\') { character = *s++; switch (character) { case 10: if (c == '`') *p++ = 10; character = *s++; break; case 'b': *p++ = '\b'; character = *s++; break; case 'f': *p++ = '\f'; character = *s++; break; case 'n': *p++ = '\n'; character = *s++; break; case 'r': *p++ = '\r'; character = *s++; break; case 't': *p++ = '\t'; character = *s++; break; case 'u': r = p; t = 0; *p++ = 'u'; character = *s++; if (character == '{') { *p++ = character; character = *s++; while (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; } if (character == '}') { p = (txString)fsX2UTF8(t, (txU1*)r, q - r); character = *s++; } } else { if (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; if (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; if (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; if (fxGetNextStringX(parser, character, &t)) { p = (txString)fsX2UTF8(t, (txU1*)r, q - r); character = *s++; } } } } } break; case 'v': *p++ = '\v'; character = *s++; break; case 'x': r = p; t = 0; *p++ = 'x'; character = *s++; if (fxGetNextStringX(parser, character, &t)) { *p++ = character; character = *s++; if (fxGetNextStringX(parser, character, &t)) { p = (txString)fsX2UTF8(t, (txU1*)r, q - r); character = *s++; } } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': r = p; t = character - '0'; *p++ = character; character = *s++; while (fxGetNextString0(parser, character, &t)) { *p++ = character; character = *s++; } p = (txString)fsX2UTF8(t, (txU1*)r, q - r); if ((parser->flags & mxStrictFlag)) fxReportParserError(parser, "octal escape sequence (strict mode)"); break; default: *p++ = character; character = *s++; break; } } else { *p++ = character; character = *s++; } } *p = 0; parser->stringLength2 = p - parser->buffer; parser->string2 = fxNewParserString(parser, parser->buffer, parser->stringLength2); } else { parser->stringLength2 = parser->rawLength2; parser->string2 = parser->raw2; } }
void fxGetNextTokenJSON(txParser* parser) { int c; txString p; txString q; parser->line = parser->line2; parser->crlf = parser->crlf2; parser->escaped = parser->escaped2; parser->integer = parser->integer2; parser->modifierLength = parser->modifierLength2; parser->modifier = parser->modifier2; parser->number = parser->number2; parser->rawLength = parser->rawLength2; parser->raw = parser->raw2; parser->stringLength = parser->stringLength2; parser->string = parser->string2; parser->symbol = parser->symbol2; parser->token = parser->token2; parser->crlf2 = 0; parser->escaped2 = 0; parser->integer2 = 0; parser->modifierLength2 = 0; parser->modifier2 = parser->emptyString; parser->number2 = 0; parser->rawLength2 = 0; parser->raw2 = parser->emptyString; parser->stringLength2 = 0; parser->string2 = parser->emptyString; parser->symbol2 = C_NULL; parser->token2 = XS_NO_TOKEN; while (parser->token2 == XS_NO_TOKEN) { switch (parser->character) { case C_EOF: parser->token2 = XS_TOKEN_EOF; break; case 10: parser->line2++; fxGetNextCharacter(parser); parser->crlf2 = 1; break; case 13: parser->line2++; fxGetNextCharacter(parser); if (parser->character == 10) fxGetNextCharacter(parser); parser->crlf2 = 1; break; case '\t': case ' ': fxGetNextCharacter(parser); break; case '0': fxGetNextCharacter(parser); c = parser->character; if (c == '.') { fxGetNextCharacter(parser); c = parser->character; if ((('0' <= c) && (c <= '9')) || (c == 'e') || (c == 'E')) fxGetNextNumberE(parser, 0); else { parser->number2 = 0; parser->token2 = XS_TOKEN_NUMBER; } } else if ((c == 'b') || (c == 'B')) { fxGetNextNumberB(parser); } else if ((c == 'e') || (c == 'E')) { fxGetNextNumberE(parser, 0); } else if ((c == 'o') || (c == 'O')) { fxGetNextNumberO(parser, '0'); } else if ((c == 'x') || (c == 'X')) { fxGetNextNumberX(parser); } else { parser->integer2 = 0; parser->token2 = XS_TOKEN_INTEGER; } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': fxGetNextNumberE(parser, 1); break; case ',': parser->token2 = XS_TOKEN_COMMA; fxGetNextCharacter(parser); break; case ':': parser->token2 = XS_TOKEN_COLON; fxGetNextCharacter(parser); break; case '[': parser->token2 = XS_TOKEN_LEFT_BRACKET; fxGetNextCharacter(parser); break; case ']': parser->token2 = XS_TOKEN_RIGHT_BRACKET; fxGetNextCharacter(parser); break; case '{': parser->token2 = XS_TOKEN_LEFT_BRACE; fxGetNextCharacter(parser); break; case '}': parser->token2 = XS_TOKEN_RIGHT_BRACE; fxGetNextCharacter(parser); break; case '"': fxGetNextCharacter(parser); fxGetNextString(parser, '"'); parser->token2 = XS_TOKEN_STRING; fxGetNextCharacter(parser); break; default: if (fxIsIdentifierFirst((char)parser->character)) { p = parser->buffer; q = p + parser->bufferSize - 1; for (;;) { if (p == q) { fxReportParserError(parser, "identifier overflow"); break; } *p++ = (char)parser->character; fxGetNextCharacter(parser); if (!fxIsIdentifierNext((char)parser->character)) break; } *p = 0; if (!c_strcmp("false", parser->buffer)) parser->token2 = XS_TOKEN_FALSE; else if (!c_strcmp("null", parser->buffer)) parser->token2 = XS_TOKEN_NULL; else if (!c_strcmp("true", parser->buffer)) parser->token2 = XS_TOKEN_TRUE; else { parser->symbol2 = fxNewParserSymbol(parser, parser->buffer); parser->token2 = XS_TOKEN_IDENTIFIER; } } else { fxReportParserWarning(parser, "invalid character %d", parser->character); fxGetNextCharacter(parser); } break; } } }