srctree

Robin Linden parent f4e482bf 099560a8
css2: Support parsing integers into number tokens

inlinesplit
css2/tokenizer.cpp added: 56, removed: 6, total 50
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2022 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022 Mikael Larsson <c.mikael.larsson@gmail.com>
//
// SPDX-License-Identifier: BSD-2-Clause
@@ -84,6 +84,21 @@ void Tokenizer::run() {
case '}':
emit(CloseCurlyToken{});
continue;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': {
// TODO(robinlinden): https://www.w3.org/TR/css-syntax-3/#consume-a-numeric-token
auto number = consume_number(*c);
emit(NumberToken{number.second, number.first});
continue;
}
default:
emit(DelimToken{*c});
continue;
@@ -298,4 +313,26 @@ void Tokenizer::reconsume_in(State state) {
state_ = state;
}
 
// https://www.w3.org/TR/css-syntax-3/#consume-a-number
std::pair<std::variant<int, double>, NumericType> Tokenizer::consume_number(char first_byte) {
NumericType type{NumericType::Integer};
std::variant<int, double> result{};
std::string repr{};
 
// TODO(robinlinden): Step 2
 
for (std::optional<char> next_input = first_byte; next_input && util::is_digit(*next_input);
next_input = consume_next_input_character()) {
repr += *next_input;
}
 
// TODO(robinlinden): Step 4, 5
 
[[maybe_unused]] auto fc_res = std::from_chars(repr.data(), repr.data() + repr.size(), std::get<int>(result));
// The tokenizer will verify that this is a number before calling consume_number.
assert(fc_res.ec == std::errc{});
 
return {result, type};
}
 
} // namespace css2
 
css2/tokenizer.h added: 56, removed: 6, total 50
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2022 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022 Mikael Larsson <c.mikael.larsson@gmail.com>
//
// SPDX-License-Identifier: BSD-2-Clause
@@ -13,6 +13,7 @@
#include <optional>
#include <string_view>
#include <utility>
#include <variant>
 
namespace css2 {
 
@@ -62,6 +63,8 @@ private:
bool inputs_starts_ident_sequence(char first_character) const;
bool is_eof() const;
void reconsume_in(State);
 
std::pair<std::variant<int, double>, NumericType> consume_number(char first_byte);
};
 
} // namespace css2
 
css2/tokenizer_test.cpp added: 56, removed: 6, total 50
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2022 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022 Mikael Larsson <c.mikael.larsson@gmail.com>
//
// SPDX-License-Identifier: BSD-2-Clause
@@ -306,5 +306,15 @@ int main() {
expect_token(output, CloseCurlyToken{});
});
 
etest::test("number: ez", [] {
auto output = run_tokenizer("13");
expect_token(output, NumberToken{.data = 13});
});
 
etest::test("number: leading 0", [] {
auto output = run_tokenizer("00000001");
expect_token(output, NumberToken{.data = 1});
});
 
return etest::run_all_tests();
}