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; }
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; }