diff --git a/include/ast.hpp b/include/ast.hpp index 03a7cfe..e36956f 100644 --- a/include/ast.hpp +++ b/include/ast.hpp @@ -162,11 +162,17 @@ namespace broma { std::string inner; ///< The inline body of the function as a raw string. }; + /// @brief Comment field + struct CommentField { + std::string inner; ///< The comment content. + bool trailing = false; ///< Whether the comment is trailing (i.e., appears after code on the same line). + }; + /// @brief A class field. struct Field { size_t field_id; ///< The index of the field. This starts from 0 and counts up across all classes. std::string parent; ///< The name of the parent class. - std::variant inner; + std::variant inner; /// @brief Cast the field into a variant type. This is useful to extract data from the field. template diff --git a/src/basic_components.hpp b/src/basic_components.hpp index 2403104..990cd8a 100644 --- a/src/basic_components.hpp +++ b/src/basic_components.hpp @@ -12,7 +12,7 @@ namespace broma { >> {}; /// @brief Noisy filler grammar elements we want to ignore when parsing. - struct ignore : sor> {}; + struct ignore : sor> {}; /// @brief Separator (zero or more ignoreable elements). struct sep : star {}; diff --git a/src/class.hpp b/src/class.hpp index 70829a5..5701666 100644 --- a/src/class.hpp +++ b/src/class.hpp @@ -31,7 +31,39 @@ namespace broma { } }; - struct field : sor {}; + struct comment_expr : sor< + seq, not_at>>, until>, + seq, until>>> + > {}; + + template <> + struct run_action { + template + static void apply(T& input, Root* root, ScratchData* scratch) { + CommentField cf; + cf.inner = input.string(); + + auto start = input.begin(); + auto end = input.input().begin(); + while (start != end && *start != '\n') { + --start; + if (*start == '\n') { + break; + } + if (*start != ' ' && *start != '\t') { + cf.trailing = true; + break; + } + } + + cf.inner.erase(0, cf.inner.find_first_not_of(" \t\n\r")); + cf.inner.erase(cf.inner.find_last_not_of(" \t\n\r") + 1); + + scratch->wip_field.inner = std::move(cf); + } + }; + + struct field : sor {}; template <> struct run_action {