Skip to content

Commit

Permalink
perf: Provide specialized parser recovery for lookahead mode
Browse files Browse the repository at this point in the history
  • Loading branch information
slavek-kucera authored Oct 2, 2023
1 parent 5e06750 commit cace56e
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 8 deletions.
23 changes: 22 additions & 1 deletion parser_library/src/parsing/error_strategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ namespace hlasm_plugin::parser_library::parsing {
void error_strategy::reset(antlr4::Parser* recognizer)
{
m_error_reported = false;
m_lookahead_recovery = false;
antlr4::DefaultErrorStrategy::reset(recognizer);
}

void error_strategy::reportError(antlr4::Parser* recognizer, const antlr4::RecognitionException& e)
{
if (m_error_reported && inErrorRecoveryMode(recognizer))
if (m_lookahead_recovery || m_error_reported && inErrorRecoveryMode(recognizer))
{
return; // don't report spurious errors
}
Expand Down Expand Up @@ -64,4 +65,24 @@ antlr4::Token* error_strategy::getMissingSymbol(antlr4::Parser*)
std::abort();
}

void error_strategy::enable_lookahead_recovery() { m_lookahead_recovery = true; }

void error_strategy::disable_lookahead_recovery() { m_lookahead_recovery = true; }

void error_strategy::recover(antlr4::Parser* recognizer, std::exception_ptr e)
{
if (m_lookahead_recovery)
std::rethrow_exception(std::move(e));

DefaultErrorStrategy::recover(recognizer, std::move(e));
}

antlr4::Token* error_strategy::recoverInline(antlr4::Parser* recognizer)
{
if (m_lookahead_recovery)
throw antlr4::InputMismatchException(recognizer);

return DefaultErrorStrategy::recoverInline(recognizer);
}

} // namespace hlasm_plugin::parser_library::parsing
7 changes: 7 additions & 0 deletions parser_library/src/parsing/error_strategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,21 @@ namespace hlasm_plugin::parser_library::parsing {
class error_strategy final : public antlr4::DefaultErrorStrategy
{
bool m_error_reported = false;
bool m_lookahead_recovery = false;

void reset(antlr4::Parser* recognizer) override;
void reportError(antlr4::Parser* recognizer, const antlr4::RecognitionException& e) override;
antlr4::Token* getMissingSymbol(antlr4::Parser*) override;
antlr4::Token* singleTokenDeletion(antlr4::Parser*) override { return nullptr; }
bool singleTokenInsertion(antlr4::Parser*) override { return false; }
void recover(antlr4::Parser* recognizer, std::exception_ptr e) override;
antlr4::Token* recoverInline(antlr4::Parser* recognizer) override;

public:
bool error_reported() const { return m_error_reported; }

void enable_lookahead_recovery();
void disable_lookahead_recovery();
};

} // namespace hlasm_plugin::parser_library::parsing
Expand Down
31 changes: 24 additions & 7 deletions parser_library/src/parsing/grammar/lookahead_rules.g4
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ lookahead_operands_and_remarks_dat
};

lookahead_operand_list_asm returns [operand_list operands] locals [bool failed = false]
: f=lookahead_operand_asm[&$failed]
:
{
enable_lookahead_recovery();
}
f=lookahead_operand_asm[&$failed]
{
{$operands.push_back(std::move($f.op));}
}
Expand All @@ -140,6 +144,10 @@ lookahead_operand_list_asm returns [operand_list operands] locals [bool failed =
$operands.push_back(std::move($n.op));
}
)*;
finally
{
disable_lookahead_recovery();
}

lookahead_operand_asm[bool* failed] returns [operand_ptr op]
:
Expand All @@ -151,11 +159,20 @@ lookahead_operand_asm[bool* failed] returns [operand_ptr op]
|
{$op = std::make_unique<semantics::empty_operand>(provider.get_empty_range( _localctx->getStart()));}
)
(
(~(COMMA|SPACE|EOF))+
;
catch[RecognitionException &e]
{
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
if (auto t = _input->LA(1); t != COMMA && t != SPACE && t != EOF)
{
*$failed = true;
$op = std::make_unique<semantics::empty_operand>(provider.get_empty_range( _localctx->getStart()));
*_localctx->failed = true;
_localctx->op = std::make_unique<semantics::empty_operand>(provider.get_empty_range(_localctx->getStart()));
do {
_input->consume();
t = _input->LA(1);
} while (t != COMMA && t != SPACE && t != EOF);
}
)?
;
}
10 changes: 10 additions & 0 deletions parser_library/src/parsing/parser_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,16 @@ std::unique_ptr<parser_holder> parser_holder::create(semantics::source_info_proc
return std::make_unique<parser_holder_impl<false>>(lsp_proc, hl_ctx, d);
}

void parser_impl::enable_lookahead_recovery()
{
static_cast<error_strategy*>(_errHandler.get())->enable_lookahead_recovery();
}

void parser_impl::disable_lookahead_recovery()
{
static_cast<error_strategy*>(_errHandler.get())->disable_lookahead_recovery();
}

void parser_impl::enable_continuation() { input.enable_continuation(); }

void parser_impl::disable_continuation() { input.disable_continuation(); }
Expand Down
2 changes: 2 additions & 0 deletions parser_library/src/parsing/parser_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ class parser_impl : public antlr4::Parser
}
};

void enable_lookahead_recovery();
void disable_lookahead_recovery();
void enable_continuation();
void disable_continuation();
bool is_self_def();
Expand Down

0 comments on commit cace56e

Please sign in to comment.