From f7b745abb02293d93914f5651b3fe1bc899032ef Mon Sep 17 00:00:00 2001 From: adamska <2639980868@qq.com> Date: Thu, 5 Sep 2024 14:28:15 +0800 Subject: [PATCH] refactor: naming parser, buffer and cdata --- docs/examples.md | 3 + include/myxml/buffer.hpp | 34 +++--- include/myxml/cdata.hpp | 32 +++-- include/myxml/error.hpp | 20 ++-- include/myxml/parser.hpp | 60 +++++----- include/myxml/xmlfile.hpp | 4 +- src/buffer.cpp | 38 +++--- src/cdata.cpp | 37 +++--- src/document.cpp | 4 +- src/element.cpp | 4 +- src/error.cpp | 26 ++--- src/parser.cpp | 238 +++++++++++++++++++------------------- src/xmlfile.cpp | 6 +- tests/buffer_test.cpp | 30 ++--- tests/parser_test.cpp | 14 +-- 15 files changed, 291 insertions(+), 259 deletions(-) diff --git a/docs/examples.md b/docs/examples.md index 70571c3..e26d8af 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -32,6 +32,7 @@ root->set_name("far"); #### Attributes ```C++ +using namespace myxml; // create an element with name 'root' element elem("root"); // or get an element from parsing @@ -49,6 +50,7 @@ elem["hello"]; // == elem["hello"] = ""; #### Children ```C++ +using namespace myxml; // element root; element child = root.first_elem(); // or first element with name "child" @@ -62,6 +64,7 @@ std::vector children = root.elems("child"); ### Text ```C++ +using namespace myxml; // create from string text txt = "Hello"; // or from query diff --git a/include/myxml/buffer.hpp b/include/myxml/buffer.hpp index 6d11035..9631799 100644 --- a/include/myxml/buffer.hpp +++ b/include/myxml/buffer.hpp @@ -8,10 +8,10 @@ namespace myxml { /** - * ADT. Used by Parser. + * ADT. Used by parser. * Implement by StringBuffer and XMLFile */ - class Buffer + class buffer { private: std::size_t offset = 0; @@ -21,34 +21,34 @@ namespace myxml // @returns {pointer to data, data length} virtual std::tuple base() const = 0; // update line and column - void updateLocation(char); + void update_loc(char); // update line and column - void updateLocation(std::string_view); + void update_loc(std::string_view); public: - virtual ~Buffer() = default; - std::optional Peek() const; - std::optional PeekN(int) const; - std::optional AfterN(int) const; - std::optional AfterNM(int, int) const; - std::optional Take(); - std::optional TakeN(int); + virtual ~buffer() = default; + std::optional peek() const; + std::optional peek_n(int) const; + std::optional after_n(int) const; + std::optional after_n_m(int, int) const; + std::optional take(); + std::optional take_n(int); // @returns {line, column} - std::tuple CurrentLocation(); + std::tuple cur_loc(); }; - class StringBuffer : public Buffer + class string_buffer : public buffer { private: std::variant inner; - std::string_view getView() const; + std::string_view view() const; /** Implement Buffer */ virtual std::tuple base() const override; public: - StringBuffer(std::string_view); - StringBuffer(std::string &&); - StringBuffer(const char *); + string_buffer(std::string_view); + string_buffer(std::string &&); + string_buffer(const char *); }; } \ No newline at end of file diff --git a/include/myxml/cdata.hpp b/include/myxml/cdata.hpp index eed6394..7c94e2e 100644 --- a/include/myxml/cdata.hpp +++ b/include/myxml/cdata.hpp @@ -1,20 +1,38 @@ #pragma once #include "myxml/node.hpp" +#include "myxml/printable.hpp" namespace myxml { - class CData : public Node + class cdata_impl; + + class cdata : public printable { private: - std::string inner; + std::shared_ptr _impl; + + cdata(std::shared_ptr); + + public: + cdata(std::string &&); + cdata(std::string_view); + + virtual void entity_encoding(bool) override {} + virtual void platform_specific_newline(bool) override {} + virtual void print(std::ostream &) const override; + }; + class cdata_impl : public Node + { public: - explicit CData(std::string); + std::string inner; + + cdata_impl() {}; + explicit cdata_impl(std::string_view); + explicit cdata_impl(std::string &&); + virtual ~cdata_impl() = default; - virtual ~CData() = default; - // virtual std::string ExportRaw() const override; - // virtual std::string ExportFormatted(int indentLevel = 0, int indentSize = 4) const override; - virtual void entity_encoding(bool) override; + virtual void entity_encoding(bool) override {} virtual void platform_specific_newline(bool) override {} virtual void print(std::ostream &) const override; }; diff --git a/include/myxml/error.hpp b/include/myxml/error.hpp index f46fb19..ea7ae3a 100644 --- a/include/myxml/error.hpp +++ b/include/myxml/error.hpp @@ -3,7 +3,7 @@ namespace myxml { - class ParseError : public std::exception + class parse_error : public std::exception { private: virtual const char *prefix() const = 0; @@ -16,7 +16,7 @@ namespace myxml std::size_t column; public: - ParseError(std::string message, std::size_t line, std::size_t column); + parse_error(std::string message, std::size_t line, std::size_t column); virtual const char *what() const noexcept override; }; @@ -27,46 +27,46 @@ namespace myxml * 2. Unexpected token. Encounter a token that is not expected in the context. For example: extra semicolon. * ... */ - class SyntaxError : public ParseError + class syntax_error : public parse_error { private: virtual const char *prefix() const; public: - SyntaxError(std::string, std::size_t line, std::size_t column); + syntax_error(std::string, std::size_t line, std::size_t column); }; /** * */ - class SemanticError : public ParseError + class semantic_error : public parse_error { private: virtual const char *prefix() const; public: - SemanticError(std::string, std::size_t line, std::size_t column); + semantic_error(std::string, std::size_t line, std::size_t column); }; /** * e.g. EOF */ - class UnexpectedEndOfInput : public ParseError + class unexpected_eof : public parse_error { private: virtual const char *prefix() const; public: - UnexpectedEndOfInput(std::size_t line, std::size_t column); + unexpected_eof(std::size_t line, std::size_t column); }; - class IOError : public std::exception + class io_error : public std::exception { private: std::string message; public: - IOError(std::string); + io_error(std::string); virtual const char *what() const noexcept override; }; diff --git a/include/myxml/parser.hpp b/include/myxml/parser.hpp index 6d9bc5b..d79f00a 100644 --- a/include/myxml/parser.hpp +++ b/include/myxml/parser.hpp @@ -6,9 +6,9 @@ namespace myxml { - struct ElementTag + struct element_tag { - enum class ClosingType + enum class closing_type { Open, // Closed, // @@ -16,25 +16,26 @@ namespace myxml }; std::string name; - ElementTag::ClosingType type = ClosingType::Open; - std::map attris; + element_tag::closing_type type = closing_type::Open; + std::map attrs; }; - class Parser + class parser { private: - std::shared_ptr buffer; + std::shared_ptr _buffer; std::optional peek(); - std::optional peekN(int); - std::optional afterN(int); + std::optional peek_n(int); + std::optional after_n(int); // m characters after n characters - std::optional afterNM(int, int); + std::optional after_n_m(int, int); std::optional take(); - std::optional takeN(int); - void skipWhiteSpaces(); - std::tuple currentLoc(); + std::optional take_n(int); + void skip_whitespaces(); + std::tuple cur_loc(); + public: /** * For all parsing method, * return std::nullopt means `not this one` and will not consume buffer. @@ -46,66 +47,65 @@ namespace myxml * @throws `UnexpectedEndOfInput` * @throws `SyntaxError` if an invalid character occurs. */ - std::string parseIdent(); + std::string parse_ident(); /** * Parse a string literal * @throws `UnexpectedEndOfInput` * @throws `SyntaxError` if missing any of `"` */ - std::string parseStringLiteral(); + std::string parse_str_literal(); /** * @returns std::nullopt if find no attribute * @throws `UnexpectedEndOfInput` * @throws `SyntaxError` if the following chars do not confront to `key="value"` format */ - std::optional> parseAttribute(); + std::optional> parse_attribute(); /** * @throws `SyntaxError` if faild to find `<` */ - std::shared_ptr parseText(); + std::shared_ptr parse_text(); /** * @returns `std::nullopt` if not start with ` parseCData(); + std::shared_ptr parse_cdata(); /** * @throws `UnexpectedEndOfInput` * @throws `SyntaxError` * @throws `SemanticError` */ - std::shared_ptr parseElementWithHeader(ElementTag header); + std::shared_ptr parse_element_with_header(element_tag header); /** * @returns std::nullopt if not starts with ` parseDeclaration(); + std::optional parse_declaration(); - public: - std::shared_ptr ParseElement(); + std::shared_ptr parse_element(); /** * @returns std::nullopt if no heading `<` * @throws `SyntaxError` if the heading character is `<` and the trailing characters are in incorrect format * @throws `UnexpectedEndOfInput` if missing name */ - std::optional ParseElementTag(); + std::optional parse_element_tag(); /** * @throws `UnexpectedEndOfInput` * @throws `SyntaxError` * @throws `SemanticError` */ - document ParseDocument(); - Parser() = delete; - explicit Parser(std::string_view); - explicit Parser(std::string &&); + document parse_document(); + parser() = delete; + explicit parser(std::string_view); + explicit parser(std::string &&); - template >> - explicit Parser(std::shared_ptr buffer) - : buffer(buffer) {} + template >> + explicit parser(std::shared_ptr buffer) + : _buffer(buffer) {} }; namespace util { - bool isValidXmlChar(char ch); + bool is_valid_xml_char(char ch); } } diff --git a/include/myxml/xmlfile.hpp b/include/myxml/xmlfile.hpp index bbd25dc..31dca07 100644 --- a/include/myxml/xmlfile.hpp +++ b/include/myxml/xmlfile.hpp @@ -6,7 +6,7 @@ namespace myxml { - class XMLFile : public Buffer + class XMLFile : public buffer { private: XMLFile(); @@ -18,7 +18,7 @@ namespace myxml std::size_t offset; - /* Implement Buffer*/ + /* Implement buffer*/ virtual std::tuple base() const; public: diff --git a/src/buffer.cpp b/src/buffer.cpp index dc16df5..3a51084 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -2,7 +2,7 @@ namespace myxml { - void Buffer::updateLocation(char ch) + void buffer::update_loc(char ch) { if (ch == '\n') { @@ -15,15 +15,15 @@ namespace myxml } } - void Buffer::updateLocation(std::string_view strv) + void buffer::update_loc(std::string_view strv) { for (auto ch : strv) { - this->updateLocation(ch); + this->update_loc(ch); } } - std::optional Buffer::Peek() const + std::optional buffer::peek() const { auto [ptr, len] = this->base(); if (this->offset >= len) @@ -33,7 +33,7 @@ namespace myxml return ptr[this->offset]; } - std::optional Buffer::PeekN(int n) const + std::optional buffer::peek_n(int n) const { auto [ptr, len] = this->base(); if (this->offset >= len) @@ -43,7 +43,7 @@ namespace myxml return std::string_view(ptr + this->offset, n); } - std::optional Buffer::AfterN(int n) const + std::optional buffer::after_n(int n) const { auto [ptr, len] = this->base(); if (this->offset + n > len) @@ -53,7 +53,7 @@ namespace myxml return ptr[this->offset + n]; } - std::optional Buffer::AfterNM(int n, int m) const + std::optional buffer::after_n_m(int n, int m) const { auto [ptr, len] = this->base(); if (this->offset + n + m > len) @@ -63,7 +63,7 @@ namespace myxml return std::string_view(ptr + this->offset + n, m); } - std::optional Buffer::Take() + std::optional buffer::take() { auto [ptr, len] = this->base(); if (this->offset >= len) @@ -71,11 +71,11 @@ namespace myxml return std::nullopt; } auto ch = ptr[this->offset++]; - this->updateLocation(ch); + this->update_loc(ch); return ch; } - std::optional Buffer::TakeN(int n) + std::optional buffer::take_n(int n) { auto [ptr, len] = this->base(); if (offset + n >= len) @@ -83,38 +83,38 @@ namespace myxml return std::nullopt; } std::string_view strv(ptr + this->offset, n); - this->updateLocation(strv); + this->update_loc(strv); offset += n; return strv; } - std::tuple Buffer::CurrentLocation() + std::tuple buffer::cur_loc() { return {this->line, this->column}; } - StringBuffer::StringBuffer(std::string_view inner) + string_buffer::string_buffer(std::string_view inner) : inner(inner) { } - StringBuffer::StringBuffer(std::string &&inner) + string_buffer::string_buffer(std::string &&inner) : inner(inner) { } - StringBuffer::StringBuffer(const char *ptr) - : StringBuffer(std::string_view(ptr)) + string_buffer::string_buffer(const char *ptr) + : string_buffer(std::string_view(ptr)) { } - std::tuple StringBuffer::base() const + std::tuple string_buffer::base() const { - auto view = this->getView(); + auto view = this->view(); return {view.data(), view.length()}; } - std::string_view StringBuffer::getView() const + std::string_view string_buffer::view() const { if (std::holds_alternative(this->inner)) { diff --git a/src/cdata.cpp b/src/cdata.cpp index d4c239b..f79542c 100644 --- a/src/cdata.cpp +++ b/src/cdata.cpp @@ -4,26 +4,37 @@ namespace myxml { - CData::CData(std::string str) - : inner(str) + cdata::cdata(std::shared_ptr impl) + : _impl(impl) + { + } + + cdata::cdata(std::string_view str) + : _impl(std::make_shared(str)) + { + } + + cdata::cdata(std::string &&str) + : _impl(std::make_shared(str)) { } - // std::string CData::ExportRaw() const - // { - // return fmt::format("\n", this->inner); - // } + void cdata::print(std::ostream &os) const + { + _impl->print(os); + } - // std::string CData::ExportFormatted(int indentLevel, int indentSize) const - // { - // return std::string(indentLevel * indentSize, ' ') + this->ExportRaw(); - // } + cdata_impl::cdata_impl(std::string_view str) + : inner(str) + { + } - void CData::entity_encoding(bool) - { // do nothing + cdata_impl::cdata_impl(std::string &&str) + : inner(str) + { } - void CData::print(std::ostream &os) const + void cdata_impl::print(std::ostream &os) const { os << "inner << "]]>\n"; } diff --git a/src/document.cpp b/src/document.cpp index e3f2aa4..519e04d 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -54,13 +54,13 @@ namespace myxml document document::parse(std::string_view input) { - return Parser(input).ParseDocument(); + return parser(input).parse_document(); } document document::load(std::string fileName) { auto f = XMLFile::Open(fileName); - return Parser(f).ParseDocument(); + return parser(f).parse_document(); } // std::string document::ExportRaw() const // { diff --git a/src/element.cpp b/src/element.cpp index 4551e15..52c38b9 100644 --- a/src/element.cpp +++ b/src/element.cpp @@ -80,13 +80,13 @@ namespace myxml std::shared_ptr element_impl::parse(std::string_view buf) { - return Parser(buf).ParseElement(); + return parser(buf).parse_element(); } std::shared_ptr element_impl::load(std::string_view path) { auto f = XMLFile::Open(path); - return Parser(f).ParseElement(); + return parser(f).parse_element(); } void element_impl::extend_attributes(std::map attris) diff --git a/src/error.cpp b/src/error.cpp index 8dc02ee..aef71b7 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -3,54 +3,54 @@ namespace myxml { - ParseError::ParseError(std::string message, std::size_t line, std::size_t column) + parse_error::parse_error(std::string message, std::size_t line, std::size_t column) : message(message), line(line), column(column) { } - const char *ParseError::what() const noexcept + const char *parse_error::what() const noexcept { this->fullMessage = fmt::format("{}{}\nin line: {} column: {}", this->prefix(), this->message, this->line, this->column); return this->fullMessage.c_str(); } - const char *SyntaxError::prefix() const + const char *syntax_error::prefix() const { return "Syntax Error: "; } - SyntaxError::SyntaxError(std::string, std::size_t line, std::size_t column) - : ParseError(message, line, column) + syntax_error::syntax_error(std::string, std::size_t line, std::size_t column) + : parse_error(message, line, column) { } - const char *SemanticError::prefix() const + const char *semantic_error::prefix() const { return "Sematic Error: "; } - SemanticError::SemanticError(std::string, std::size_t line, std::size_t column) - : ParseError(message, line, column) + semantic_error::semantic_error(std::string, std::size_t line, std::size_t column) + : parse_error(message, line, column) { } - const char *UnexpectedEndOfInput::prefix() const + const char *unexpected_eof::prefix() const { return "Unexpected End of Input: "; } - UnexpectedEndOfInput::UnexpectedEndOfInput(std::size_t line, std::size_t column) - : ParseError("End of input", line, column) + unexpected_eof::unexpected_eof(std::size_t line, std::size_t column) + : parse_error("End of input", line, column) { } - IOError::IOError(std::string message) + io_error::io_error(std::string message) : message(message) { } - const char *IOError::what() const noexcept + const char *io_error::what() const noexcept { return message.c_str(); } diff --git a/src/parser.cpp b/src/parser.cpp index 08e31e0..23a67c5 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5,7 +5,7 @@ namespace myxml { - void Parser::skipWhiteSpaces() + void parser::skip_whitespaces() { while (this->peek() && std::isspace(*this->peek())) { @@ -13,200 +13,200 @@ namespace myxml } } - std::tuple Parser::currentLoc() + std::tuple parser::cur_loc() { - return this->buffer->CurrentLocation(); + return this->_buffer->cur_loc(); } - std::optional Parser::peek() + std::optional parser::peek() { - return this->buffer->Peek(); + return this->_buffer->peek(); } - std::optional Parser::peekN(int n) + std::optional parser::peek_n(int n) { - return this->buffer->PeekN(n); + return this->_buffer->peek_n(n); } - std::optional Parser::afterN(int n) + std::optional parser::after_n(int n) { - return this->buffer->AfterN(n); + return this->_buffer->after_n(n); } - std::optional Parser::afterNM(int n, int m) + std::optional parser::after_n_m(int n, int m) { - return this->buffer->AfterNM(n, m); + return this->_buffer->after_n_m(n, m); } - std::optional Parser::take() + std::optional parser::take() { - return this->buffer->Take(); + return this->_buffer->take(); } - std::optional Parser::takeN(int n) + std::optional parser::take_n(int n) { - return this->buffer->TakeN(n); + return this->_buffer->take_n(n); } - std::string Parser::parseIdent() + std::string parser::parse_ident() { if (this->peek() == std::nullopt) { - auto [line, col] = this->currentLoc(); - throw UnexpectedEndOfInput(line, col); + auto [line, col] = this->cur_loc(); + throw unexpected_eof(line, col); } // validate heading character if (auto head = this->peek(); !head || (!std::isalpha(*head) && head != '_')) { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("element name which starts with {} is invalid.", *head), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("element name which starts with {} is invalid.", *head), line, col); } std::size_t len = 0; - while (this->afterN(len) && util::isValidXmlChar(*this->afterN(len))) + while (this->after_n(len) && util::is_valid_xml_char(*this->after_n(len))) { len++; } - return std::string(*this->takeN(len)); + return std::string(*this->take_n(len)); } - std::string Parser::parseStringLiteral() + std::string parser::parse_str_literal() { if (!this->peek()) { - auto [line, col] = this->currentLoc(); - throw UnexpectedEndOfInput(line, col); + auto [line, col] = this->cur_loc(); + throw unexpected_eof(line, col); } if (this->peek() != '"') { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("expected '\"' at the beginning of string literal, find {}", *this->peek()), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("expected '\"' at the beginning of string literal, find {}", *this->peek()), line, col); } this->take(); std::size_t len = 0; - while (this->afterN(len) != '"') + while (this->after_n(len) != '"') { len++; } - if (!this->afterN(len)) + if (!this->after_n(len)) { // if jump out due to length limit - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("missing closing double quote for string literal"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("missing closing double quote for string literal"), line, col); } - auto it = this->takeN(len); + auto it = this->take_n(len); this->take(); // skip " return std::string(*it); } - std::optional> Parser::parseAttribute() + std::optional> parser::parse_attribute() { - this->skipWhiteSpaces(); + this->skip_whitespaces(); std::pair attr; std::string key; try { - key = this->parseIdent(); + key = this->parse_ident(); } - catch (SyntaxError e) + catch (syntax_error e) { // Only SyntaxError in parseIdent is incorrect heading character return std::nullopt; } - catch (UnexpectedEndOfInput e) + catch (unexpected_eof e) { // There must be `>` or else after all attributes throw e; } if (this->take() != '=') { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("expected '=' after attribute name"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("expected '=' after attribute name"), line, col); } attr.first = key; - auto value = this->parseStringLiteral(); + auto value = this->parse_str_literal(); attr.second = value; return attr; } - std::shared_ptr Parser::parseText() + std::shared_ptr parser::parse_text() { if (!this->peek()) { - auto [line, col] = this->currentLoc(); - throw UnexpectedEndOfInput(line, col); + auto [line, col] = this->cur_loc(); + throw unexpected_eof(line, col); } std::size_t len = 0; - while (this->afterN(len) != '<') + while (this->after_n(len) != '<') { len++; } - if (!this->afterN(len)) + if (!this->after_n(len)) { // if jump out of while loop due to length limit - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("expected '<' after text"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("expected '<' after text"), line, col); } - return std::shared_ptr(new text_impl(*this->takeN(len))); + return std::shared_ptr(new text_impl(*this->take_n(len))); } - std::shared_ptr Parser::parseCData() + std::shared_ptr parser::parse_cdata() { - if (this->peekN(9) != "peek_n(9) != "takeN(9); + this->take_n(9); std::size_t len = 0; - while (this->afterNM(len, 3) != "]]>") + while (this->after_n_m(len, 3) != "]]>") { len++; } - if (!this->afterN(len + 2)) + if (!this->after_n(len + 2)) { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("expected \"]]>\" after CDATA"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("expected \"]]>\" after CDATA"), line, col); } - auto it = std::string(*this->takeN(len)); - this->takeN(2); - return std::make_shared(it); + auto it = std::string(*this->take_n(len)); + this->take_n(2); + return std::make_shared(it); } - std::optional Parser::ParseElementTag() + std::optional parser::parse_element_tag() { if (this->take() != '<') { return std::nullopt; } - ElementTag tag; + element_tag tag; if (this->peek() == '/') { - tag.type = ElementTag::ClosingType::Closing; + tag.type = element_tag::closing_type::Closing; this->take(); } - this->skipWhiteSpaces(); - auto name = this->parseIdent(); + this->skip_whitespaces(); + auto name = this->parse_ident(); tag.name = name; - this->skipWhiteSpaces(); - while (auto attr = this->parseAttribute()) + this->skip_whitespaces(); + while (auto attr = this->parse_attribute()) { - tag.attris.insert(*attr); + tag.attrs.insert(*attr); } - this->skipWhiteSpaces(); + this->skip_whitespaces(); if (this->peek() == '/') { - if (tag.type != ElementTag::ClosingType::Open) + if (tag.type != element_tag::closing_type::Open) { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("unexpected ending '/' found in closing tag"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("unexpected ending '/' found in closing tag"), line, col); } - tag.type = ElementTag::ClosingType::Closed; + tag.type = element_tag::closing_type::Closed; this->take(); } if (this->take() != '>') { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("expected '>' at the end of the tag"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("expected '>' at the end of the tag"), line, col); } return tag; } - std::shared_ptr Parser::parseElementWithHeader(ElementTag header) + std::shared_ptr parser::parse_element_with_header(element_tag header) { auto elem = element_impl::_new(); elem->name = header.name; @@ -216,41 +216,41 @@ namespace myxml { case '<': { - if (auto cdata = this->parseCData(); cdata) + if (auto cdata = this->parse_cdata(); cdata) { elem->InsertAtEnd(cdata); continue; } - auto tag = this->ParseElementTag(); // impossible to be std::nullopt + auto tag = this->parse_element_tag(); // impossible to be std::nullopt assert(tag); switch (tag->type) { - case ElementTag::ClosingType::Open: + case element_tag::closing_type::Open: { - auto child = this->parseElementWithHeader(*tag); + auto child = this->parse_element_with_header(*tag); elem->InsertAtEnd(child); break; } - case ElementTag::ClosingType::Closed: + case element_tag::closing_type::Closed: { auto child = element_impl::_new(); child->name = tag->name; - if (!tag->attris.empty()) + if (!tag->attrs.empty()) { - child->extend_attributes(tag->attris); + child->extend_attributes(tag->attrs); } elem->InsertAtEnd(child); break; } - case ElementTag::ClosingType::Closing: + case element_tag::closing_type::Closing: if (tag->name != elem->name) { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("elem name in closing tag is mismatched with the header"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("elem name in closing tag is mismatched with the header"), line, col); } - if (!header.attris.empty()) + if (!header.attrs.empty()) { - elem->extend_attributes(header.attris); + elem->extend_attributes(header.attrs); } return elem; default: @@ -259,38 +259,38 @@ namespace myxml break; } default: - auto text = this->parseText(); + auto text = this->parse_text(); elem->InsertAtEnd(text); break; } } - auto [line, col] = this->currentLoc(); - throw UnexpectedEndOfInput(line, col); + auto [line, col] = this->cur_loc(); + throw unexpected_eof(line, col); } - std::shared_ptr Parser::ParseElement() + std::shared_ptr parser::parse_element() { - this->skipWhiteSpaces(); - if (auto tag = this->ParseElementTag(); tag) + this->skip_whitespaces(); + if (auto tag = this->parse_element_tag(); tag) { - if (tag->type == ElementTag::ClosingType::Closed) + if (tag->type == element_tag::closing_type::Closed) { auto elem = element_impl::_new(); elem->name = tag->name; - if (!tag->attris.empty()) + if (!tag->attrs.empty()) { - elem->extend_attributes(tag->attris); + elem->extend_attributes(tag->attrs); } return elem; } - else if (tag->type == ElementTag::ClosingType::Open) + else if (tag->type == element_tag::closing_type::Open) { - return this->parseElementWithHeader(*tag); + return this->parse_element_with_header(*tag); } else // Closing { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("unexpected closing tag"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("unexpected closing tag"), line, col); } } else @@ -299,23 +299,23 @@ namespace myxml } } - std::optional Parser::parseDeclaration() + std::optional parser::parse_declaration() { - if (this->peekN(5) != "peek_n(5) != "takeN(5); + this->take_n(5); std::map attrs; - while (auto attr = this->parseAttribute()) + while (auto attr = this->parse_attribute()) { attrs.insert(*attr); } - this->skipWhiteSpaces(); - if (this->takeN(2) != "?>") + this->skip_whitespaces(); + if (this->take_n(2) != "?>") { - auto [line, col] = this->currentLoc(); - throw SyntaxError(fmt::format("expected \"?>\" at end of xml declaration"), line, col); + auto [line, col] = this->cur_loc(); + throw syntax_error(fmt::format("expected \"?>\" at end of xml declaration"), line, col); } if (auto decl = declaration::from_attrs(attrs); decl) { @@ -323,41 +323,41 @@ namespace myxml } else { - auto [line, col] = this->currentLoc(); - throw SemanticError(fmt::format("declaration has incorrect attributes"), line, col); + auto [line, col] = this->cur_loc(); + throw semantic_error(fmt::format("declaration has incorrect attributes"), line, col); } } - document Parser::ParseDocument() + document parser::parse_document() { document document; - if (auto decl = this->parseDeclaration(); decl) + if (auto decl = this->parse_declaration(); decl) { document.set_declaration(*decl); } - if (auto root = this->ParseElement(); root) + if (auto root = this->parse_element(); root) { document.set_root(root); } else { - auto [line, col] = this->currentLoc(); - throw SemanticError(fmt::format("missing root element in xml document"), line, col); + auto [line, col] = this->cur_loc(); + throw semantic_error(fmt::format("missing root element in xml document"), line, col); } return document; } - Parser::Parser(std::string_view buffer) - : buffer(std::make_shared(buffer)) + parser::parser(std::string_view buffer) + : _buffer(std::make_shared(buffer)) { } - Parser::Parser(std::string &&buffer) - : buffer(std::make_shared(buffer)) + parser::parser(std::string &&buffer) + : _buffer(std::make_shared(buffer)) { } - bool util::isValidXmlChar(char ch) + bool util::is_valid_xml_char(char ch) { return std::isalnum(ch) || ch == '_' || ch == '-' || ch == '.' || ch == ':'; } diff --git a/src/xmlfile.cpp b/src/xmlfile.cpp index 66d3941..207635e 100644 --- a/src/xmlfile.cpp +++ b/src/xmlfile.cpp @@ -22,18 +22,18 @@ namespace myxml xfile->fd = open(fpath.data(), O_RDONLY); if (xfile->fd == -1) { - throw IOError(fmt::format("failed to open file: {}", fpath)); + throw io_error(fmt::format("failed to open file: {}", fpath)); } struct stat fileInfo; if (fstat(xfile->fd, &fileInfo) == -1) { - throw IOError(fmt::format("failed to get info of file: {}", fpath)); + throw io_error(fmt::format("failed to get info of file: {}", fpath)); } xfile->fileSize = fileInfo.st_size; void *mappedRegion = mmap(nullptr, xfile->fileSize, PROT_READ, MAP_PRIVATE, xfile->fd, 0); if (mappedRegion == MAP_FAILED) { - throw IOError(fmt::format("failed to map memory for file: {}", fpath)); + throw io_error(fmt::format("failed to map memory for file: {}", fpath)); } xfile->inner = static_cast(mappedRegion); return xfile; diff --git a/tests/buffer_test.cpp b/tests/buffer_test.cpp index 8131164..26428d4 100644 --- a/tests/buffer_test.cpp +++ b/tests/buffer_test.cpp @@ -6,25 +6,25 @@ TEST_CASE("String Buffer", "[buffer]") { SECTION("Simple String Buffer") { - myxml::StringBuffer sb = "Hello, world!"; - REQUIRE(sb.Peek() == 'H'); - REQUIRE(sb.PeekN(3) == "Hel"); - REQUIRE(sb.TakeN(3) == "Hel"); - REQUIRE(sb.AfterN(1) == 'o'); - REQUIRE(sb.AfterNM(1, 2) == "o,"); + myxml::string_buffer sb = "Hello, world!"; + REQUIRE(sb.peek() == 'H'); + REQUIRE(sb.peek_n(3) == "Hel"); + REQUIRE(sb.take_n(3) == "Hel"); + REQUIRE(sb.after_n(1) == 'o'); + REQUIRE(sb.after_n_m(1, 2) == "o,"); } SECTION("Location", "[buffer]") { - myxml::StringBuffer sb = "Hello, world!\nLine2"; + myxml::string_buffer sb = "Hello, world!\nLine2"; - REQUIRE(sb.TakeN(3) == "Hel"); - REQUIRE(sb.CurrentLocation() == std::make_tuple(0, 3)); - REQUIRE(sb.TakeN(4) == "lo, "); - REQUIRE(sb.CurrentLocation() == std::make_tuple(0, 7)); - REQUIRE(sb.TakeN(7) == "world!\n"); - REQUIRE(sb.CurrentLocation() == std::make_tuple(1, 0)); - REQUIRE(sb.TakeN(3) == "Lin"); - REQUIRE(sb.CurrentLocation() == std::make_tuple(1, 3)); + REQUIRE(sb.take_n(3) == "Hel"); + REQUIRE(sb.cur_loc() == std::make_tuple(0, 3)); + REQUIRE(sb.take_n(4) == "lo, "); + REQUIRE(sb.cur_loc() == std::make_tuple(0, 7)); + REQUIRE(sb.take_n(7) == "world!\n"); + REQUIRE(sb.cur_loc() == std::make_tuple(1, 0)); + REQUIRE(sb.take_n(3) == "Lin"); + REQUIRE(sb.cur_loc() == std::make_tuple(1, 3)); } } \ No newline at end of file diff --git a/tests/parser_test.cpp b/tests/parser_test.cpp index a80338f..80bbab8 100644 --- a/tests/parser_test.cpp +++ b/tests/parser_test.cpp @@ -7,19 +7,19 @@ TEST_CASE("Parsing tag", "parser") { std::string open = ""; - auto tag = myxml::Parser(open).ParseElementTag(); + auto tag = myxml::parser(open).parse_element_tag(); REQUIRE(tag->name == "tag"); - REQUIRE(tag->type == myxml::ElementTag::ClosingType::Open); + REQUIRE(tag->type == myxml::element_tag::closing_type::Open); std::string closed = ""; - tag = myxml::Parser(closed).ParseElementTag(); + tag = myxml::parser(closed).parse_element_tag(); REQUIRE(tag->name == "tag"); - REQUIRE(tag->type == myxml::ElementTag::ClosingType::Closed); + REQUIRE(tag->type == myxml::element_tag::closing_type::Closed); std::string closing = ""; - tag = myxml::Parser(closing).ParseElementTag(); + tag = myxml::parser(closing).parse_element_tag(); REQUIRE(tag->name == "tag"); - REQUIRE(tag->type == myxml::ElementTag::ClosingType::Closing); + REQUIRE(tag->type == myxml::element_tag::closing_type::Closing); } TEST_CASE("Parsing simple xml elements", "[parser]") @@ -200,7 +200,7 @@ TEST_CASE("Parsing simple xml elements", "[parser]") std::string cdata = ""; auto elem = myxml::element_impl::parse(cdata); - REQUIRE(elem->FirstChild()->As()->str() == "\n"); + REQUIRE(elem->FirstChild()->As()->str() == "\n"); } SECTION("Newline Normalization")