Skip to content

Commit

Permalink
modified to throw a parse_error object when an error occurs while par…
Browse files Browse the repository at this point in the history
…sing
  • Loading branch information
fktn-k committed Nov 23, 2023
1 parent 584d630 commit 56ef03a
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 122 deletions.
1 change: 1 addition & 0 deletions docs/mkdocs/docs/api/exception/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ A basic exception class used in the fkYAML library.
| Type | Description |
| --------------------------------------- | ---------------------------------------------------- |
| [invalid_encoding](invalid_encoding.md) | The exception indicating an encoding error. |
| [parse_error](parse_error.md) | The exception indicating an error in parsing. |
| [type_error](type_error.md) | The exception indicating an invalid type conversion. |
## Member Functions
Expand Down
19 changes: 19 additions & 0 deletions docs/mkdocs/docs/api/exception/parse_error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<small>Defined in header [`<fkYAML/exception.hpp>`](https://github.com/fktn-k/fkYAML/blob/develop/include/fkYAML/exception.hpp)</small>

# <small>fkyaml::</small>parse_error

```cpp
class parse_error : public exception;
```

A exception class indicating an error in parsing.
This class extends the [`fkyaml::exception`](index.md) class and the [`what()`](what.md) function emits an error message in the following format.

```
parse_error: [error message] (at line [LINE], column [COLUMN])
```

## **See Also**

* [exception](index.md)
* [what](what.md)
1 change: 1 addition & 0 deletions docs/mkdocs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ nav:
- (destructor): api/exception/destructor.md
- what: api/exception/what.md
- invalid_encoding: api/exception/invalid_encoding.md
- parse_error: api/exception/parse_error.md
- type_error: api/exception/type_error.md
- macros: api/macros.md
- node_value_converter:
Expand Down
53 changes: 34 additions & 19 deletions include/fkYAML/detail/input/deserializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class basic_deserializer

lexical_token_t type = lexer.get_next_token();
std::size_t cur_indent = lexer.get_last_token_begin_pos();
std::size_t cur_line = lexer.get_lines_processed();

while (type != lexical_token_t::END_OF_BUFFER)
{
Expand All @@ -78,7 +79,7 @@ class basic_deserializer
bool is_stack_empty = m_node_stack.empty();
if (is_stack_empty)
{
throw fkyaml::exception("A key separator found without key.");
throw fkyaml::parse_error("A key separator found without key.", cur_line, cur_indent);
}
break;
}
Expand All @@ -94,7 +95,8 @@ class basic_deserializer
auto itr = m_anchor_table.find(alias_name);
if (itr == m_anchor_table.end())
{
throw fkyaml::exception("The given anchor name must appear prior to the alias node.");
throw fkyaml::parse_error(
"The given anchor name must appear prior to the alias node.", cur_line, cur_indent);
}
assign_node_value(BasicNodeType::alias_of(m_anchor_table.at(alias_name)));
break;
Expand Down Expand Up @@ -135,7 +137,7 @@ class basic_deserializer
// if the current node is a mapping.
if (m_node_stack.empty())
{
throw fkyaml::exception("Invalid sequence block prefix(- ) found.");
throw fkyaml::parse_error("Invalid sequence block prefix(- ) found.", cur_line, cur_indent);
}

// move back to the previous sequence if necessary.
Expand Down Expand Up @@ -167,12 +169,14 @@ class basic_deserializer
*m_current_node = BasicNodeType::sequence();
set_yaml_version(*m_current_node);
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

*m_current_node = BasicNodeType::mapping();
set_yaml_version(*m_current_node);
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
case lexical_token_t::MAPPING_FLOW_BEGIN:
*m_current_node = BasicNodeType::mapping();
Expand All @@ -181,15 +185,15 @@ class basic_deserializer
case lexical_token_t::MAPPING_FLOW_END:
if (!m_current_node->is_mapping())
{
throw fkyaml::exception("Invalid mapping flow ending found.");
throw fkyaml::parse_error("Invalid mapping flow ending found.", cur_line, cur_indent);
}
m_current_node = m_node_stack.back();
m_node_stack.pop_back();
break;
case lexical_token_t::NULL_VALUE: {
if (m_current_node->is_mapping())
{
add_new_key(lexer.get_string(), cur_indent);
add_new_key(lexer.get_string(), cur_indent, cur_line);
break;
}

Expand All @@ -201,13 +205,15 @@ class basic_deserializer
// check if the current target token is a key or not.
if (type == lexical_token_t::KEY_SEPARATOR || type == lexical_token_t::MAPPING_BLOCK_PREFIX)
{
add_new_key(str, cur_indent);
add_new_key(str, cur_indent, cur_line);
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

assign_node_value(BasicNodeType());
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

Expand All @@ -217,7 +223,7 @@ class basic_deserializer
case lexical_token_t::BOOLEAN_VALUE: {
if (m_current_node->is_mapping())
{
add_new_key(lexer.get_string(), cur_indent);
add_new_key(lexer.get_string(), cur_indent, cur_line);
break;
}

Expand All @@ -230,13 +236,15 @@ class basic_deserializer
// check if the current target token is a key or not.
if (type == lexical_token_t::KEY_SEPARATOR || type == lexical_token_t::MAPPING_BLOCK_PREFIX)
{
add_new_key(str, cur_indent);
add_new_key(str, cur_indent, cur_line);
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

assign_node_value(BasicNodeType(boolean));
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

Expand All @@ -246,7 +254,7 @@ class basic_deserializer
case lexical_token_t::INTEGER_VALUE: {
if (m_current_node->is_mapping())
{
add_new_key(lexer.get_string(), cur_indent);
add_new_key(lexer.get_string(), cur_indent, cur_line);
break;
}

Expand All @@ -259,13 +267,15 @@ class basic_deserializer
// check if the current target token is a key or not.
if (type == lexical_token_t::KEY_SEPARATOR || type == lexical_token_t::MAPPING_BLOCK_PREFIX)
{
add_new_key(str, cur_indent);
add_new_key(str, cur_indent, cur_line);
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

assign_node_value(BasicNodeType(integer));
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

Expand All @@ -275,7 +285,7 @@ class basic_deserializer
case lexical_token_t::FLOAT_NUMBER_VALUE: {
if (m_current_node->is_mapping())
{
add_new_key(lexer.get_string(), cur_indent);
add_new_key(lexer.get_string(), cur_indent, cur_line);
break;
}

Expand All @@ -288,13 +298,15 @@ class basic_deserializer
// check if the current target token is a key or not.
if (type == lexical_token_t::KEY_SEPARATOR || type == lexical_token_t::MAPPING_BLOCK_PREFIX)
{
add_new_key(str, cur_indent);
add_new_key(str, cur_indent, cur_line);
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

assign_node_value(BasicNodeType(float_val));
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

Expand All @@ -304,7 +316,7 @@ class basic_deserializer
case lexical_token_t::STRING_VALUE: {
if (m_current_node->is_mapping())
{
add_new_key(lexer.get_string(), cur_indent);
add_new_key(lexer.get_string(), cur_indent, cur_line);
break;
}

Expand All @@ -316,13 +328,15 @@ class basic_deserializer
// check if the current target token is a key or not.
if (type == lexical_token_t::KEY_SEPARATOR || type == lexical_token_t::MAPPING_BLOCK_PREFIX)
{
add_new_key(str, cur_indent);
add_new_key(str, cur_indent, cur_line);
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

assign_node_value(BasicNodeType(str));
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
continue;
}

Expand All @@ -334,12 +348,13 @@ class basic_deserializer
case lexical_token_t::END_OF_DOCUMENT:
// TODO: This token should be handled to support multiple documents.
break;
default: // LCOV_EXCL_LINE
throw fkyaml::exception("Unsupported lexical token found."); // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
throw fkyaml::parse_error("Unsupported lexical token found.", cur_line, cur_indent); // LCOV_EXCL_LINE
}

type = lexer.get_next_token();
cur_indent = lexer.get_last_token_begin_pos();
cur_line = lexer.get_lines_processed();
}

m_current_node = nullptr;
Expand All @@ -354,15 +369,15 @@ class basic_deserializer
private:
/// @brief Add new key string to the current YAML node.
/// @param key a key string to be added to the current YAML node.
void add_new_key(const string_type& key, const std::size_t indent)
void add_new_key(const string_type& key, const std::size_t indent, const std::size_t line)
{
if (!m_indent_stack.empty() && indent < m_indent_stack.back())
{
auto target_itr = std::find(m_indent_stack.rbegin(), m_indent_stack.rend(), indent);
bool is_indent_valid = (target_itr != m_indent_stack.rend());
if (!is_indent_valid)
{
throw fkyaml::exception("Detected invalid indentaion.");
throw fkyaml::parse_error("Detected invalid indentaion.", line, indent);
}

auto pop_num = std::distance(m_indent_stack.rbegin(), target_itr);
Expand Down Expand Up @@ -394,7 +409,7 @@ class basic_deserializer
auto itr = map.find(key);
if (itr != map.end())
{
throw fkyaml::exception("Detected duplication in mapping keys.");
throw fkyaml::parse_error("Detected duplication in mapping keys.", line, indent);
}
}

Expand Down
Loading

0 comments on commit 56ef03a

Please sign in to comment.