Report missing lexical action handlers from Lexer::valid()

This commit is contained in:
Charles Baker 2023-05-21 20:04:14 +12:00
parent e56556f390
commit 184a8b34c0
3 changed files with 41 additions and 0 deletions

View file

@ -12,6 +12,7 @@ enum ErrorCode
PARSER_ERROR_NONE, ///< No %error.
LALR_ERROR_SYNTAX, ///< Syntax %error occured while parsing input.
LALR_ERROR_UNTERMINATED_LITERAL, ///< Unterminated literal in an lalr grammar.
LEXER_ERROR_MISSING_ACTION_HANDLER, ///< A lexer action hasn't been bound to a function.
LEXER_ERROR_SYNTAX, ///< Syntax %error occured while parsing some input.
LEXER_ERROR_SYMBOL_CONFLICT, ///< A lexer state matches more than one symbol.
LEXER_ERROR_LEXICAL_ERROR, ///< A lexical error occured while scanning an input sequence.

View file

@ -54,6 +54,7 @@ public:
const void* symbol() const;
const Iterator& position() const;
bool full() const;
bool valid() const;
void set_action_handler( const char* identifier, LexerActionFunction function );
void reset( Iterator start, Iterator finish );
void advance();

View file

@ -160,6 +160,45 @@ bool Lexer<Iterator, Char, Traits, Allocator>::full() const
return full_;
}
/**
// Is this Lexer valid?
//
// Reports errors for any action handlers that haven't been set.
//
// @return
// True if this Lexer is valid and can be used to split input into tokens
// otherwise false.
*/
template <class Iterator, class Char, class Traits, class Allocator>
bool Lexer<Iterator, Char, Traits, Allocator>::valid() const
{
bool valid = true;
for ( const LexerActionHandler& handler : action_handlers_ )
{
if ( !handler.function_ )
{
const LexerAction* action = handler.action_;
LALR_ASSERT( action );
fire_error( -1, -1, LEXER_ERROR_MISSING_ACTION_HANDLER, "Lexical action '%s' has no handler", action->identifier );
valid = false;
}
}
for ( const LexerActionHandler& handler : whitespace_action_handlers_ )
{
if ( !handler.function_ )
{
const LexerAction* action = handler.action_;
LALR_ASSERT( action );
fire_error( -1, -1, LEXER_ERROR_MISSING_ACTION_HANDLER, "Lexical action '%s' has no handler", action->identifier );
valid = false;
}
}
return valid;
}
/**
// Set the action handler for \e identifier to \e function.
//