diff --git a/src/bong.cpp b/src/bong.cpp index 9f54411..779ae6c 100644 --- a/src/bong.cpp +++ b/src/bong.cpp @@ -339,85 +339,110 @@ auto Lexer::step() noexcept -> void } } -// auto Parser::parse_top_level() noexcept -> Result, -// Error> -// { -// if (!lexer.peek()) -// return Error { lexer.peek().unwrap_error() }; -// else if (lexer.peek()->type == Tokens::Name) -// return parse_element(); -// else -// return parse_value(); -// } +auto Parser::parse_top_level() noexcept -> Result, Error> +{ + if (!lexer.peek()) + return Error { lexer.peek().unwrap_error() }; + else if (lexer.peek()->type == Tokens::Name) + return parse_element(); + else + return parse_value(); +} -// auto Parser::parse_element() noexcept -> Result, Error> -// { -// auto name = *lexer.peek(); +auto Parser::parse_element() noexcept -> Result, Error> +{ + auto name = *lexer.peek(); -// auto ids = Element::Ids {}; -// auto classes = Element::Classes {}; -// auto properties = Element::Properties {}; -// auto values = Element::Values {}; + auto ids = Element::Ids {}; + auto classes = Element::Classes {}; + auto properties = Element::Properties {}; + auto values = Element::Values {}; -// if (auto result = lexer.next(); !result) -// return Error { result.unwrap_error() }; -// return Result, Error>::create_ok( -// std::make_unique( -// Element { std::string { name.value() }, {}, {}, {}, {} })); -// } + if (auto result = lexer.next(); !result) + return Error { result.unwrap_error() }; + return Result, Error>::create_ok( + std::make_unique( + Element { std::string { name.value() }, {}, {}, {}, {} })); +} -// auto Parser::parse_single_line_fields( -// Element::Initializer& initializer) noexcept -> Result -// { -// if (lexer.peek()->type == Tokens::Id) { -// initializer.ids.push_back(std::string { lexer.peek()->value() }); -// if (auto result = lexer.next(); !result) -// return Error { result.unwrap_error() }; -// // do the rest; -// } else if (lexer.peek()->type == Tokens::Class) { -// initializer.classes.push_back(std::string { lexer.peek()->value() }); -// if (auto result = lexer.next(); !result) -// return Error { result.unwrap_error() }; -// // do the rest -// } else { -// if (auto result = parse_mandatory_same_line_whitespace(); !result) -// return result; -// if (lexer.peek()->type == Tokens::Name) { -// auto key = lexer.peek(); -// if (auto result = lexer.next(); !result) -// return Error { result.unwrap_error() }; -// if (auto result = parse_optional_whitespace(); !result) -// return result; -// if (lexer.peek()->type != Tokens::Equal -// and lexer.peek()->type != Tokens::Colon) -// return Error { -// fmt::format("expected '=' or ':', got {}", -// lexer.peek()->to_string()), -// lexer.peek()->location, -// }; -// if (auto result = lexer.next(); !result) -// return Error { result.unwrap_error() }; -// if (auto result = parse_optional_same_line_whitespace(); !result) -// return result; -// auto value = parse_single_line_value(); -// if (!value) -// return value; -// // do the rest -// } else { -// auto value = parse_single_line_value(); -// if (!value) -// return value; -// // do the rest -// } -// } -// return {}; -// } +auto remove_first_char(std::string_view value) noexcept -> std::string_view +{ + return value.substr(1, value.size() - 1); +} -// auto Parser::parse_single_line_field(Element::Initializer& initializer) -// noexcept -// -> Result -// { +auto Parser::parse_single_line_fields( + Element::Initializer& initializer) noexcept -> Result +{ + if (lexer.peek()->type == Tokens::Id) + return parse_single_line_fields_starts_id(initializer); + else if (lexer.peek()->type == Tokens::Class) + return parse_single_line_fields_starts_class(initializer); + else + return parse_single_line_fields_starts_with_property_or_value( + initializer); +} -// } +auto Parser::parse_single_line_fields_starts_id( + Element::Initializer& initializer) noexcept -> Result +{ + initializer.ids.push_back(std::string { + remove_first_char(lexer.peek()->value()), + }); + if (auto result = lexer.next(); !result) + return Error { result.unwrap_error() }; + return parse_single_line_fields_tail(initializer); +} + +auto Parser::parse_single_line_fields_starts_class( + Element::Initializer& initializer) noexcept -> Result +{ + initializer.classes.push_back(std::string { + remove_first_char(lexer.peek()->value()), + }); + if (auto result = lexer.next(); !result) + return Error { result.unwrap_error() }; + return parse_single_line_fields_tail(initializer); +} + +auto Parser::parse_single_line_fields_starts_with_property_or_value( + Element::Initializer& initializer) noexcept -> Result +{ + if (auto result = parse_mandatory_same_line_whitespace(); !result) + return result; + if (lexer.peek()->type == Tokens::Name) { + auto key = lexer.peek(); + if (auto result = lexer.next(); !result) + return Error { result.unwrap_error() }; + if (auto result = parse_optional_whitespace(); !result) + return result; + if (lexer.peek()->type != Tokens::Equal + and lexer.peek()->type != Tokens::Colon) + return Error { + fmt::format( + "expected '=' or ':', got {}", lexer.peek()->to_string()), + lexer.peek()->location, + }; + if (auto result = lexer.next(); !result) + return Error { result.unwrap_error() }; + if (auto result = parse_optional_same_line_whitespace(); !result) + return result; + auto value = parse_single_line_value(); + if (!value) + return value.transform(); + initializer.properties.insert_or_assign( + std::string { key->value() }, *value); + return parse_single_line_fields_tail(initializer); + } else { + auto value = parse_single_line_value(); + if (!value) + return value.transform(); + initializer.values.push_back(*value); + return parse_single_line_fields_tail(initializer); + } +} + +auto Parser::parse_single_line_fields_tail( + Element::Initializer& initializer) noexcept -> Result +{ } } diff --git a/src/bong.hpp b/src/bong.hpp index b7d3d74..8a9ba7a 100644 --- a/src/bong.hpp +++ b/src/bong.hpp @@ -201,57 +201,66 @@ struct Bool final : public Node { auto type() const noexcept -> Nodes override { return Nodes::Bool; } }; -// class Parser { -// public: -// struct Error { -// Error(Lexer::Error error) -// : message { std::move(error.message) } -// , location { error.location } -// { } -// Error(std::string message, Location location) -// : message { std::move(message) } -// , location { location } -// { } +class Parser { +public: + struct Error { + Error(Lexer::Error error) + : message { std::move(error.message) } + , location { error.location } + { } + Error(std::string message, Location location) + : message { std::move(message) } + , location { location } + { } -// std::string message; -// Location location; -// }; + std::string message; + Location location; + }; -// Parser(Lexer lexer) -// : lexer { std::move(lexer) } -// { } + Parser(Lexer lexer) + : lexer { std::move(lexer) } + { } -// auto parse_top_level() noexcept -> Result, Error>; -// auto parse_element() noexcept -> Result, Error>; -// auto parse_element_body(Element::Initializer& initializer) noexcept -// -> Result; -// auto parse_element_fields(Element::Initializer& initializer) noexcept -// -> Result; -// auto parse_element_field(Element::Initializer& initializer) noexcept -// -> Result; -// auto parse_single_line_fields(Element::Initializer& initializer) noexcept -// -> Result; -// auto parse_element_property() noexcept -> Result; -// auto parse_single_line_value() noexcept -> Result; -// auto parse_value() noexcept -> Result, Error>; -// auto parse_object() noexcept -> Result; -// auto parse_object_properties() noexcept -> Result; -// auto parse_object_property() noexcept -> Result; -// auto parse_array() noexcept -> Result; -// auto parse_array_values() noexcept -> Result; -// auto parse_bool() noexcept -> Result; -// auto parse_mandatory_same_line_whitespace() noexcept -> Result; auto parse_optional_same_line_whitespace() noexcept -> -// Result; auto parse_mandatory_linebreak() noexcept -> -// Result; auto parse_single_line_whitespace() noexcept -> -// Result; auto parse_line_breaker() noexcept -> Result; auto parse_whitespace_and_line_break() noexcept -> Result; auto parse_optional_whitespace() noexcept -> Result; -// auto parse_mandatory_whitespace() noexcept -> Result; -// auto parse_singular_whitespace() noexcept -> Result; + auto parse_top_level() noexcept -> Result, Error>; + auto parse_element() noexcept -> Result, Error>; + auto parse_element_body(Element::Initializer& initializer) noexcept + -> Result; + auto parse_element_fields(Element::Initializer& initializer) noexcept + -> Result; + auto parse_element_field(Element::Initializer& initializer) noexcept + -> Result; + auto parse_element_property() noexcept -> Result; + auto parse_single_line_fields(Element::Initializer& initializer) noexcept + -> Result; + auto parse_single_line_fields_starts_id( + Element::Initializer& initializer) noexcept -> Result; + auto parse_single_line_fields_starts_class( + Element::Initializer& initializer) noexcept -> Result; + auto parse_single_line_fields_starts_with_property_or_value( + Element::Initializer& initializer) noexcept -> Result; + auto parse_single_line_fields_tail( + Element::Initializer& initializer) noexcept -> Result; + auto parse_single_line_value() noexcept + -> Result, Error>; + auto parse_value() noexcept -> Result, Error>; + auto parse_object() noexcept -> Result; + auto parse_object_properties() noexcept -> Result; + auto parse_object_property() noexcept -> Result; + auto parse_array() noexcept -> Result; + auto parse_array_values() noexcept -> Result; + auto parse_bool() noexcept -> Result; + auto parse_mandatory_same_line_whitespace() noexcept -> Result; + auto parse_optional_same_line_whitespace() noexcept -> Result; + auto parse_mandatory_linebreak() noexcept -> Result; + auto parse_single_line_whitespace() noexcept -> Result; + auto parse_line_breaker() noexcept -> Result; + auto parse_whitespace_and_line_break() noexcept -> Result; + auto parse_optional_whitespace() noexcept -> Result; + auto parse_mandatory_whitespace() noexcept -> Result; + auto parse_singular_whitespace() noexcept -> Result; -// private: -// Lexer lexer; -// }; +private: + Lexer lexer; +}; }