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 + -
显示快捷键?