mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 02:12:09 -05:00
JSSpecCompiler: Push ParseError out of AlgorithmStepList
This commit is contained in:
parent
c7369f2f93
commit
1bd1187c92
2 changed files with 46 additions and 32 deletions
|
@ -48,15 +48,18 @@ Location SpecificationParsingContext::location_from_xml_offset(XML::Offset offse
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseErrorOr<AlgorithmStep> AlgorithmStep::create(XML::Node const* node)
|
ParseErrorOr<AlgorithmStep> AlgorithmStep::create(SpecificationParsingContext& ctx, XML::Node const* node)
|
||||||
{
|
{
|
||||||
VERIFY(node->as_element().name == tag_li);
|
VERIFY(node->as_element().name == tag_li);
|
||||||
|
|
||||||
auto [tokens, substeps] = TRY(tokenize_tree(node, true));
|
auto [tokens, substeps] = TRY(tokenize_tree(node, true));
|
||||||
AlgorithmStep result { .m_tokens = move(tokens), .m_node = node };
|
AlgorithmStep result { .m_tokens = move(tokens), .m_node = node };
|
||||||
|
|
||||||
if (substeps)
|
if (substeps) {
|
||||||
result.m_substeps = TRY(AlgorithmStepList::create(substeps->as_element())).m_expression;
|
auto step_list = AlgorithmStepList::create(ctx, substeps);
|
||||||
|
if (step_list.has_value())
|
||||||
|
result.m_substeps = step_list->m_expression;
|
||||||
|
}
|
||||||
|
|
||||||
result.m_expression = TRY(result.parse());
|
result.m_expression = TRY(result.parse());
|
||||||
return result;
|
return result;
|
||||||
|
@ -72,34 +75,49 @@ ParseErrorOr<Tree> AlgorithmStep::parse()
|
||||||
return parser.parse_step_without_substeps();
|
return parser.parse_step_without_substeps();
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseErrorOr<AlgorithmStepList> AlgorithmStepList::create(XML::Node::Element const& element)
|
Optional<AlgorithmStepList> AlgorithmStepList::create(SpecificationParsingContext& ctx, XML::Node const* element)
|
||||||
{
|
{
|
||||||
VERIFY(element.name == tag_ol);
|
VERIFY(element->as_element().name == tag_ol);
|
||||||
|
|
||||||
AlgorithmStepList result;
|
AlgorithmStepList result;
|
||||||
auto& steps = result.m_steps;
|
auto& steps = result.m_steps;
|
||||||
|
|
||||||
Vector<Tree> step_expressions;
|
Vector<Tree> step_expressions;
|
||||||
|
bool all_steps_parsed = true;
|
||||||
|
|
||||||
for (auto const& child : element.children) {
|
for (auto const& child : element->as_element().children) {
|
||||||
TRY(child->content.visit(
|
child->content.visit(
|
||||||
[&](XML::Node::Element const& element) -> ParseErrorOr<void> {
|
[&](XML::Node::Element const& element) {
|
||||||
if (element.name != tag_li)
|
if (element.name == tag_li) {
|
||||||
return ParseError::create("<emu-alg> <ol> > :not(<li>) should not match any elements"sv, child);
|
auto step_creation_result = AlgorithmStep::create(ctx, child);
|
||||||
steps.append(TRY(AlgorithmStep::create(child)));
|
if (step_creation_result.is_error()) {
|
||||||
step_expressions.append(steps.last().m_expression);
|
// TODO: Integrate backtracing parser errors better
|
||||||
return {};
|
ctx.diag().error(ctx.location_from_xml_offset(step_creation_result.error()->offset()),
|
||||||
|
"{}", step_creation_result.error()->to_string());
|
||||||
|
all_steps_parsed = false;
|
||||||
|
} else {
|
||||||
|
steps.append(step_creation_result.release_value());
|
||||||
|
step_expressions.append(steps.last().m_expression);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.diag().error(ctx.location_from_xml_offset(child->offset),
|
||||||
|
"<{}> should not be a child of algorithm step list"sv, element.name);
|
||||||
},
|
},
|
||||||
[&](XML::Node::Text const&) -> ParseErrorOr<void> {
|
[&](XML::Node::Text const&) {
|
||||||
if (!contains_empty_text(child))
|
if (!contains_empty_text(child)) {
|
||||||
return ParseError::create("<emu-alg> <ol> should not have non-empty child text nodes"sv, child);
|
ctx.diag().error(ctx.location_from_xml_offset(child->offset),
|
||||||
return {};
|
"non-empty text node should not be a child of algorithm step list");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
move(ignore_comments)));
|
[&](auto const&) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
result.m_expression = make_ref_counted<TreeList>(move(step_expressions));
|
if (!all_steps_parsed)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
result.m_expression = make_ref_counted<TreeList>(move(step_expressions));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,18 +152,14 @@ Optional<Algorithm> Algorithm::create(SpecificationParsingContext& ctx, XML::Nod
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto steps_creation_result = AlgorithmStepList::create(steps_list[0]->as_element());
|
auto steps_creation_result = AlgorithmStepList::create(ctx, steps_list[0]);
|
||||||
if (steps_creation_result.is_error()) {
|
if (steps_creation_result.has_value()) {
|
||||||
// TODO: Integrate backtracing parser errors better
|
Algorithm algorithm;
|
||||||
ctx.diag().error(ctx.location_from_xml_offset(steps_creation_result.error()->offset()),
|
algorithm.m_steps = steps_creation_result.release_value();
|
||||||
"{}", steps_creation_result.error()->to_string());
|
algorithm.m_tree = algorithm.m_steps.m_expression;
|
||||||
return {};
|
return algorithm;
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
Algorithm algorithm;
|
|
||||||
algorithm.m_steps = steps_creation_result.release_value();
|
|
||||||
algorithm.m_tree = algorithm.m_steps.m_expression;
|
|
||||||
return algorithm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullOwnPtr<SpecificationClause> SpecificationClause::create(SpecificationParsingContext& ctx, XML::Node const* element)
|
NonnullOwnPtr<SpecificationClause> SpecificationClause::create(SpecificationParsingContext& ctx, XML::Node const* element)
|
||||||
|
|
|
@ -43,7 +43,7 @@ private:
|
||||||
|
|
||||||
class AlgorithmStepList {
|
class AlgorithmStepList {
|
||||||
public:
|
public:
|
||||||
static ParseErrorOr<AlgorithmStepList> create(XML::Node::Element const& element);
|
static Optional<AlgorithmStepList> create(SpecificationParsingContext& ctx, XML::Node const* element);
|
||||||
|
|
||||||
Vector<AlgorithmStep> m_steps;
|
Vector<AlgorithmStep> m_steps;
|
||||||
Tree m_expression = error_tree;
|
Tree m_expression = error_tree;
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
|
|
||||||
class AlgorithmStep {
|
class AlgorithmStep {
|
||||||
public:
|
public:
|
||||||
static ParseErrorOr<AlgorithmStep> create(XML::Node const* node);
|
static ParseErrorOr<AlgorithmStep> create(SpecificationParsingContext& ctx, XML::Node const* node);
|
||||||
|
|
||||||
ParseErrorOr<Tree> parse();
|
ParseErrorOr<Tree> parse();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue