Esempio n. 1
0
static bool parseDecimal(IParser::Pos & pos, IParser::Pos end, ASTSampleRatio::Rational & res, IParser::Pos & max_parsed_pos)
{
    ParserWhitespaceOrComments ws;
    ws.ignore(pos, end);

    UInt64 num_before = 0;
    UInt64 num_after = 0;
    Int64 exponent = 0;

    IParser::Pos pos_after_first_num = tryReadIntText(num_before, pos, end);

    bool has_num_before_point = pos_after_first_num > pos;
    pos = pos_after_first_num;
    bool has_point = pos < end && *pos == '.';

    if (has_point)
        ++pos;

    if (!has_num_before_point && !has_point)
        return false;

    size_t number_of_digits_after_point = 0;

    if (has_point)
    {
        IParser::Pos pos_after_second_num = tryReadIntText(num_after, pos, end);
        number_of_digits_after_point = pos_after_second_num - pos;
        pos = pos_after_second_num;
    }

    bool has_exponent = pos < end && (*pos == 'e' || *pos == 'E');

    if (has_exponent)
    {
        ++pos;
        IParser::Pos pos_after_exponent = tryReadIntText(exponent, pos, end);

        if (pos_after_exponent == pos)
            return false;

        pos = pos_after_exponent;
    }

    res.numerator = num_before * exp10(number_of_digits_after_point) + num_after;
    res.denominator = exp10(number_of_digits_after_point);

    if (exponent > 0)
        res.numerator *= exp10(exponent);
    if (exponent < 0)
        res.denominator *= exp10(-exponent);

    /// NOTE You do not need to remove the common power of ten from the numerator and denominator.
    return true;
}
Esempio n. 2
0
static bool parseDecimal(IParser::Pos & pos, IParser::Pos end, ASTSampleRatio::Rational & res, IParser::Pos & max_parsed_pos)
{
	ParserWhiteSpaceOrComments ws;
	ws.ignore(pos, end);

	UInt64 num_before = 0;
	UInt64 num_after = 0;
	Int64 exponent = 0;

	IParser::Pos pos_after_first_num = tryReadIntText(num_before, pos, end);

	bool has_num_before_point = pos_after_first_num > pos;
	pos = pos_after_first_num;
	bool has_point = pos < end && *pos == '.';

	if (has_point)
		++pos;

	if (!has_num_before_point && !has_point)
		return false;

	size_t number_of_digits_after_point = 0;

	if (has_point)
	{
		IParser::Pos pos_after_second_num = tryReadIntText(num_after, pos, end);
		number_of_digits_after_point = pos_after_second_num - pos;
		pos = pos_after_second_num;
	}

	bool has_exponent = pos < end && (*pos == 'e' || *pos == 'E');

	if (has_exponent)
	{
		++pos;
		IParser::Pos pos_after_exponent = tryReadIntText(exponent, pos, end);

		if (pos_after_exponent == pos)
			return false;

		pos = pos_after_exponent;
	}

	res.numerator = num_before * exp10(number_of_digits_after_point) + num_after;
	res.denominator = exp10(number_of_digits_after_point);

	if (exponent > 0)
		res.numerator *= exp10(exponent);
	if (exponent < 0)
		res.denominator *= exp10(-exponent);

	/// NOTE Удаление общих степеней десяти из числителя и знаменателя - не нужно.
	return true;
}
bool ParserUnsignedInteger::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{
	Field res;

	Pos begin = pos;
	if (pos == end)
		return false;

	UInt64 x = 0;
	ReadBuffer in(const_cast<char *>(pos), end - pos, 0);
	if (!tryReadIntText(x, in) || in.count() == 0)
	{
		expected = "unsigned integer";
		return false;
	}

	res = x;
	pos += in.count();
	node = std::make_shared<ASTLiteral>(StringRange(begin, pos), res);
	return true;
}