ejslex.c
来自「samba最新软件」· C语言 代码 · 共 924 行 · 第 1/2 页
C
924 行
} } } /* * Continue looking for a token, so get the next character */ if ((c = inputGetc(ep)) < 0) { return EJS_TOK_EOF; } break; case '<': /* < and <= */ if ((c = inputGetc(ep)) < 0) { ejsError(ep, "Syntax Error"); return EJS_TOK_ERR; } if (c == '<') { tokenAddChar(ep, EJS_EXPR_LSHIFT); return EJS_TOK_EXPR; } else if (c == '=') { tokenAddChar(ep, EJS_EXPR_LESSEQ); return EJS_TOK_EXPR; } tokenAddChar(ep, EJS_EXPR_LESS); inputPutback(ep, c); return EJS_TOK_EXPR; case '>': /* > and >= */ if ((c = inputGetc(ep)) < 0) { ejsError(ep, "Syntax Error"); return EJS_TOK_ERR; } if (c == '>') { tokenAddChar(ep, EJS_EXPR_RSHIFT); return EJS_TOK_EXPR; } else if (c == '=') { tokenAddChar(ep, EJS_EXPR_GREATEREQ); return EJS_TOK_EXPR; } tokenAddChar(ep, EJS_EXPR_GREATER); inputPutback(ep, c); return EJS_TOK_EXPR; case '=': /* "==" */ if ((c = inputGetc(ep)) < 0) { ejsError(ep, "Syntax Error"); return EJS_TOK_ERR; } if (c == '=') { tokenAddChar(ep, EJS_EXPR_EQ); return EJS_TOK_EXPR; } inputPutback(ep, c); return EJS_TOK_ASSIGNMENT; case '!': /* "!=" or "!"*/ if ((c = inputGetc(ep)) < 0) { ejsError(ep, "Syntax Error"); return EJS_TOK_ERR; } if (c == '=') { tokenAddChar(ep, EJS_EXPR_NOTEQ); return EJS_TOK_EXPR; } inputPutback(ep, c); tokenAddChar(ep, EJS_EXPR_BOOL_COMP); return EJS_TOK_EXPR; case ';': tokenAddChar(ep, c); return EJS_TOK_SEMI; case ',': tokenAddChar(ep, c); return EJS_TOK_COMMA; case '|': /* "||" */ if ((c = inputGetc(ep)) < 0 || c != '|') { ejsError(ep, "Syntax Error"); return EJS_TOK_ERR; } tokenAddChar(ep, EJS_COND_OR); return EJS_TOK_LOGICAL; case '&': /* "&&" */ if ((c = inputGetc(ep)) < 0 || c != '&') { ejsError(ep, "Syntax Error"); return EJS_TOK_ERR; } tokenAddChar(ep, EJS_COND_AND); return EJS_TOK_LOGICAL; case '\"': /* String quote */ case '\'': quote = c; if ((c = inputGetc(ep)) < 0) { ejsError(ep, "Syntax Error"); return EJS_TOK_ERR; } while (c != quote) { /* * Check for escape sequence characters */ if (c == '\\') { c = inputGetc(ep); if (isdigit(c)) { /* * Octal support, \101 maps to 65 = 'A'. Put first * char back so converter will work properly. */ inputPutback(ep, c); c = charConvert(ep, 8, 3); } else { switch (c) { case 'n': c = '\n'; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'x': /* * Hex support, \x41 maps to 65 = 'A' */ c = charConvert(ep, 16, 2); break; case 'u': /* * Unicode support, \x0401 maps to 65 = 'A' */ c = charConvert(ep, 16, 2); c = c*16 + charConvert(ep, 16, 2); break; case '\'': case '\"': case '\\': break; default: ejsError(ep, "Invalid Escape Sequence"); return EJS_TOK_ERR; } } if (tokenAddChar(ep, c) < 0) { return EJS_TOK_ERR; } } else { if (tokenAddChar(ep, c) < 0) { return EJS_TOK_ERR; } } if ((c = inputGetc(ep)) < 0) { ejsError(ep, "Unmatched Quote"); return EJS_TOK_ERR; } } return EJS_TOK_LITERAL; case '0': if (tokenAddChar(ep, c) < 0) { return EJS_TOK_ERR; } if ((c = inputGetc(ep)) < 0) { break; } if (tolower(c) == 'x') { do { if (tokenAddChar(ep, c) < 0) { return EJS_TOK_ERR; } if ((c = inputGetc(ep)) < 0) { break; } } while (isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f')); mprDestroyVar(&ep->tokenNumber); ep->tokenNumber = mprParseVar(ep->token, type); inputPutback(ep, c); return EJS_TOK_NUMBER; } if (! isdigit(c)) {#if BLD_FEATURE_FLOATING_POINT if (c == '.' || tolower(c) == 'e' || c == '+' || c == '-') { /* Fall through */ type = MPR_TYPE_FLOAT; } else#endif { mprDestroyVar(&ep->tokenNumber); ep->tokenNumber = mprParseVar(ep->token, type); inputPutback(ep, c); return EJS_TOK_NUMBER; } } /* Fall through to get more digits */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': do { if (tokenAddChar(ep, c) < 0) { return EJS_TOK_ERR; } if ((c = inputGetc(ep)) < 0) { break; }#if BLD_FEATURE_FLOATING_POINT if (c == '.' || tolower(c) == 'e' || tolower(c) == 'f') { type = MPR_TYPE_FLOAT; } } while (isdigit(c) || c == '.' || tolower(c) == 'e' || tolower(c) == 'f' || ((type == MPR_TYPE_FLOAT) && (c == '+' || c == '-')));#else } while (isdigit(c));#endif mprDestroyVar(&ep->tokenNumber); ep->tokenNumber = mprParseVar(ep->token, type); inputPutback(ep, c); return EJS_TOK_NUMBER; default: /* * Identifiers or a function names */ while (1) { if (c == '\\') { if ((c = inputGetc(ep)) < 0) { break; } if (c == '\n' || c == '\r') { break; } } else if (tokenAddChar(ep, c) < 0) { break; } if ((c = inputGetc(ep)) < 0) { break; } if (!isalnum(c) && c != '$' && c != '_' && c != '\\') { break; } } if (*ep->token == '\0') { c = inputGetc(ep); break; } if (! isalpha((int) *ep->token) && *ep->token != '$' && *ep->token != '_') { ejsError(ep, "Invalid identifier %s", ep->token); return EJS_TOK_ERR; } tid = checkReservedWord(ep, state, c, EJS_TOK_ID); if (tid != EJS_TOK_ID) { return tid; } /* * Skip white space after token to find out whether this is * a function or not. */ while (c == ' ' || c == '\t' || c == '\r' || c == '\n') { if ((c = inputGetc(ep)) < 0) break; } tid = EJS_TOK_ID; done++; } } /* * Putback the last extra character for next time */ inputPutback(ep, c); return tid;}/******************************************************************************//* * Convert a hex or octal character back to binary, return original char if * not a hex digit */static int charConvert(Ejs *ep, int base, int maxDig){ int i, c, lval, convChar; lval = 0; for (i = 0; i < maxDig; i++) { if ((c = inputGetc(ep)) < 0) { break; } /* * Initialize to out of range value */ convChar = base; if (isdigit(c)) { convChar = c - '0'; } else if (c >= 'a' && c <= 'f') { convChar = c - 'a' + 10; } else if (c >= 'A' && c <= 'F') { convChar = c - 'A' + 10; } /* * If unexpected character then return it to buffer. */ if (convChar >= base) { inputPutback(ep, c); break; } lval = (lval * base) + convChar; } return lval;}/******************************************************************************//* * Putback the last token read. Accept at most one push back token. */void ejsLexPutbackToken(Ejs *ep, int tid, char *string){ EjsInput *ip; int idx; mprAssert(ep); ip = ep->input; mprAssert(ip); ip->putBackIndex += 1; idx = ip->putBackIndex; ip->putBack[idx].id = tid; if (ip->putBack[idx].token) { if (ip->putBack[idx].token == string) { return; } mprFree(ip->putBack[idx].token); } ip->putBack[idx].token = mprStrdup(string);}/******************************************************************************//* * Add a character to the token buffer */static int tokenAddChar(Ejs *ep, int c){ EjsInput *ip; uchar *oldbuf; mprAssert(ep); ip = ep->input; mprAssert(ip); if (ip->tokEndp >= &ip->tokbuf[ip->tokSize - 1]) { ip->tokSize += EJS_PARSE_INCR; oldbuf = ip->tokbuf; ip->tokbuf = mprRealloc(ip->tokbuf, ip->tokSize); if (ip->tokbuf == 0) { ejsError(ep, "Token too big"); return -1; } ip->tokEndp += (int) ((uchar*) ip->tokbuf - oldbuf); ip->tokServp += (int) ((uchar*) ip->tokbuf - oldbuf); ep->token += (int) ((uchar*) ip->tokbuf - oldbuf); } *ip->tokEndp++ = c; *ip->tokEndp = '\0'; return 0;}/******************************************************************************//* * Get another input character */static int inputGetc(Ejs *ep){ EjsInput *ip; int c; mprAssert(ep); ip = ep->input; if (ip->scriptSize <= 0) { return -1; } c = (uchar) (*ip->scriptServp++); ip->scriptSize--; /* * For debugging, accumulate the line number and the currenly parsed line */ if (c == '\n') {#if BLD_DEBUG && 0 if (ip->lineColumn > 0) { printf("PARSED: %s\n", ip->line); }#endif ip->lineNumber++; ip->lineColumn = 0; } else { if ((ip->lineColumn + 2) >= ip->lineLength) { ip->lineLength += 80; ip->line = mprRealloc(ip->line, ip->lineLength * sizeof(char)); } ip->line[ip->lineColumn++] = c; ip->line[ip->lineColumn] = '\0'; } return c;}/******************************************************************************//* * Putback a character onto the input queue */static void inputPutback(Ejs *ep, int c){ EjsInput *ip; mprAssert(ep); if (c != 0) { ip = ep->input; *--ip->scriptServp = c; ip->scriptSize++; ip->lineColumn--; ip->line[ip->lineColumn] = '\0'; }}/******************************************************************************/#elsevoid ejsLexDummy() {}/******************************************************************************/#endif /* BLD_FEATURE_EJS *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim:tw=78 * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?