Ejemplo n.º 1
0
	const Token& _UnquotedString()
	{
		const char* begin = fCurrentChar;

		while (*fCurrentChar != 0 && !_IsUnquotedDelimitingChar(*fCurrentChar))
			fCurrentChar++;

		int32 length = fCurrentChar - begin;
		fCurrentToken.SetTo(begin, length, _CurrentPos() - length,
			TOKEN_UNKNOWN);

		return fCurrentToken;
	}
Ejemplo n.º 2
0
	const Token& _NextTokenCommand()
	{
		switch (*fCurrentChar) {
			case '(':
			case ')':
			case '[':
			case ']':
			case '|':
			case ';':
				fCurrentToken.SetTo(fCurrentChar, 1, _CurrentPos(),
					*fCurrentChar);
				fCurrentChar++;
				return fCurrentToken;
			case '"':
				return _QuotedString();

			default:
				return _UnquotedString();
		}
	}
Ejemplo n.º 3
0
	const Token& NextToken()
	{
		if (fCurrentToken.type == TOKEN_END_OF_LINE)
			return fCurrentToken;

		if (fReuseToken) {
			fReuseToken = false;
			return fCurrentToken;
		}

		while (*fCurrentChar != 0 && isspace(*fCurrentChar))
			fCurrentChar++;

		if (*fCurrentChar == 0) {
			fCurrentToken.SetTo("", 0, _CurrentPos(), TOKEN_END_OF_LINE);
			return fCurrentToken;
		}

		return (fCommandMode ? _NextTokenCommand() : _NextTokenExpression());
	}
Ejemplo n.º 4
0
	const Token& NextToken()
	{
		if (fCurrentToken.type == TOKEN_END_OF_LINE)
			return fCurrentToken;

		if (fReuseToken) {
			fReuseToken = false;
//printf("next token (recycled): '%s'\n", fCurrentToken.string.String());
			return fCurrentToken;
		}

		while (*fCurrentChar != 0 && isspace(*fCurrentChar))
			fCurrentChar++;

		if (*fCurrentChar == 0)
			return fCurrentToken = Token("", 0, _CurrentPos(), TOKEN_END_OF_LINE);

		bool decimal = *fCurrentChar == '.' || *fCurrentChar == ',';

		if (decimal || isdigit(*fCurrentChar)) {
			if (fHexSupport && *fCurrentChar == '0' && fCurrentChar[1] == 'x')
				return _ParseHexNumber();

			BString temp;

			const char* begin = fCurrentChar;

			// optional digits before the comma
			while (isdigit(*fCurrentChar)) {
				temp << *fCurrentChar;
				fCurrentChar++;
			}

			// optional post comma part
			// (required if there are no digits before the comma)
			if (*fCurrentChar == '.' || *fCurrentChar == ',') {
				temp << '.';
				fCurrentChar++;

				// optional post comma digits
				while (isdigit(*fCurrentChar)) {
					temp << *fCurrentChar;
					fCurrentChar++;
				}
			}

			// optional exponent part
			if (*fCurrentChar == 'e' || *fCurrentChar == 'E') {
				temp << *fCurrentChar;
				fCurrentChar++;

				// optional exponent sign
				if (*fCurrentChar == '+' || *fCurrentChar == '-') {
					temp << *fCurrentChar;
					fCurrentChar++;
				}

				// required exponent digits
				if (!isdigit(*fCurrentChar)) {
					throw ParseException("missing exponent in constant",
						fCurrentChar - begin);
				}

				while (isdigit(*fCurrentChar)) {
					temp << *fCurrentChar;
					fCurrentChar++;
				}
			}

			int32 length = fCurrentChar - begin;
			BString test = temp;
			test << "&_";
			double value;
			char t[2];
			int32 matches = sscanf(test.String(), "%lf&%s", &value, t);
			if (matches != 2) {
				throw ParseException("error in constant",
					_CurrentPos() - length);
			}

			fCurrentToken = Token(begin, length, _CurrentPos() - length,
				TOKEN_CONSTANT);
			fCurrentToken.value = temp.String();

		} else if (isalpha(*fCurrentChar) && *fCurrentChar != 'x') {
			const char* begin = fCurrentChar;
			while (*fCurrentChar != 0 && (isalpha(*fCurrentChar)
				|| isdigit(*fCurrentChar))) {
				fCurrentChar++;
			}
			int32 length = fCurrentChar - begin;
			fCurrentToken = Token(begin, length, _CurrentPos() - length,
				TOKEN_IDENTIFIER);

		} else {
			int32 type = TOKEN_NONE;

			switch (*fCurrentChar) {
				case '+':
					type = TOKEN_PLUS;
					break;
				case '-':
					type = TOKEN_MINUS;
					break;
				case '*':
					type = TOKEN_STAR;
					break;
				case '/':
				case '\\':
				case ':':
					type = TOKEN_SLASH;
					break;

				case '%':
					type = TOKEN_MODULO;
					break;
				case '^':
					type = TOKEN_POWER;
					break;

				case '(':
					type = TOKEN_OPENING_BRACKET;
					break;
				case ')':
					type = TOKEN_CLOSING_BRACKET;
					break;

				case '&':
					type = TOKEN_AND;
					break;
				case '|':
					type = TOKEN_OR;
					break;
				case '~':
					type = TOKEN_NOT;
					break;

				case '\n':
					type = TOKEN_END_OF_LINE;
					break;

				case 'x':
					if (!fHexSupport) {
						type = TOKEN_STAR;
						break;
					}
					// fall through

				default:
					throw ParseException("unexpected character", _CurrentPos());
			}
			fCurrentToken = Token(fCurrentChar, 1, _CurrentPos(), type);
			fCurrentChar++;
		}

//printf("next token: '%s'\n", fCurrentToken.string.String());
		return fCurrentToken;
	}
Ejemplo n.º 5
0
	const Token& _NextTokenExpression()
	{
		if (isdigit(*fCurrentChar)) {
			// number
			const char* begin = fCurrentChar++;

			if (*fCurrentChar == 'x') {
				// hex number
				fCurrentChar++;
				while (*fCurrentChar != 0
					&& (isdigit(*fCurrentChar)
						|| strchr("abcdefABCDEF", *fCurrentChar))) {
					fCurrentChar++;
				}

				if (fCurrentChar - begin == 2)
					parse_exception("invalid hex number", begin - fString);

			} else {
				// decimal number
				while (*fCurrentChar != 0 && isdigit(*fCurrentChar))
					fCurrentChar++;
			}

			int32 length = fCurrentChar - begin;
			fCurrentToken.SetTo(begin, length, _CurrentPos() - length,
				TOKEN_CONSTANT);
			fCurrentToken.value = strtoull(fCurrentToken.string, NULL, 0);

		} else if (isalpha(*fCurrentChar) || *fCurrentChar == '_'
				|| *fCurrentChar == '$' || *fCurrentChar == '@') {
			// identifier
			const char* begin = fCurrentChar;
			fCurrentChar++;
			while (*fCurrentChar != 0
				&& (isalpha(*fCurrentChar) || *fCurrentChar == '_'
					|| isdigit(*fCurrentChar))) {
				fCurrentChar++;
			}

			int32 length = fCurrentChar - begin;
			fCurrentToken.SetTo(begin, length, _CurrentPos() - length,
				TOKEN_IDENTIFIER);

		} else {
			const char* begin = fCurrentChar;
			char c = *fCurrentChar;
			fCurrentChar++;
			int32 flags = 0;

			switch (c) {
				case '=':
					fCurrentChar--;
				case '+':
				case '-':
				case '*':
				case '/':
				case '%':
					if (*fCurrentChar == '=') {
						fCurrentChar++;
						flags = TOKEN_ASSIGN_FLAG;
					}

				case '(':
				case ')':
				case '[':
				case ']':
				case '{':
				case '}':
				case ';':
				{
					int32 length = fCurrentChar - begin;
					fCurrentToken.SetTo(begin, length, _CurrentPos() - length,
						c | flags);
					break;
				}

				case '"':
				{
					fCurrentChar--;
					_QuotedString();
					break;
				}

				default:
				{
					fCurrentChar--;
					_UnquotedString();
					break;
				}
			}
		}

		return fCurrentToken;
	}