diff --git a/bong_grammar.txt b/bong_grammar.txt index 1061a13..bac29da 100644 --- a/bong_grammar.txt +++ b/bong_grammar.txt @@ -16,23 +16,26 @@ element_field -> | element_property | value +element_property -> Name _ ("=" | ":") _ value + single_line_fields -> (first_single_line_field - (__singleline__ single_line_field):*):? __singleline__ + (__singleline__ single_line_field):*):? _singleline_ first_single_line_field -> | Id | Class - | __singleline__ element_property + | __singleline__ single_line_element_property | __singleline__ single_line_value single_line_field -> | Id | Class - | element_property + | single_line_element_property | single_line_value -element_property -> Name _ ("=" | ":") _ value +single_line_element_property -> + Name _singleline_ ("=" | ":") _singleline_ value single_line_value -> | array @@ -77,7 +80,7 @@ mandatory_linebreak -> line_breaker whitespace_and_line_break:* -single_line_whitespace -> SingleLineComment | SingleLineWhitespace +single_line_whitespace -> SingleLineWhitespace | MultiLineComment line_breaker -> MultiLineComment | MultiLineWhitespace | ";" diff --git a/src/bong.cpp b/src/bong.cpp index dc5dce2..3487263 100644 --- a/src/bong.cpp +++ b/src/bong.cpp @@ -342,7 +342,7 @@ auto Lexer::step() noexcept -> void auto Parser::parse_top_level() noexcept -> Result, Error> { if (!lexer.peek()) - return { lexer.peek().unwrap_error() }; + return Error { lexer.peek().unwrap_error() }; else if (lexer.peek()->type == Tokens::Name) return parse_element(); else @@ -358,8 +358,8 @@ auto Parser::parse_element() noexcept -> Result, Error> auto properties = Element::Properties {}; auto values = Element::Values {}; - if (!lexer.next()) - return { lexer.peek().unwrap_error() }; + if (auto result = lexer.next(); !result) + return Error { result.unwrap_error() }; return Result, Error>::create_ok( std::make_unique( Element { std::string { name.value() }, {}, {}, {}, {} })); @@ -368,9 +368,54 @@ auto Parser::parse_element() noexcept -> Result, Error> auto Parser::parse_single_line_fields( Element::Initializer& initializer) noexcept -> Result { - if (auto result = parse_first_single_line_field(initializer); !result) - return result; - return {}; + 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 + } + } } +// auto Parser::parse_single_line_field(Element::Initializer& initializer) +// noexcept +// -> Result +// { + +// } + } diff --git a/src/bong.hpp b/src/bong.hpp index b9cd397..18a1f0b 100644 --- a/src/bong.hpp +++ b/src/bong.hpp @@ -204,10 +204,14 @@ struct Bool final : public Node { class Parser { public: struct Error { - Error(Lexer::Error&& 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; @@ -227,10 +231,6 @@ public: -> Result; auto parse_single_line_fields(Element::Initializer& initializer) noexcept -> Result; - auto parse_first_single_line_field( - Element::Initializer& initializer) noexcept -> Result; - auto parse_single_line_field(Element::Initializer& initializer) noexcept - -> Result; auto parse_element_property() noexcept -> Result; auto parse_single_line_value() noexcept -> Result; auto parse_value() noexcept -> Result, Error>; diff --git a/src/main.cpp b/src/main.cpp index 78b3c76..0f50b67 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -78,14 +78,7 @@ auto read_file_into_string(const std::string& filename) std::istreambuf_iterator(file), std::istreambuf_iterator()); return contents; } -struct Data { - int a, b; -}; -auto func() -> std::unique_ptr -{ - return std::make_unique(Data { 5, 3 }); -} auto main() -> int {