Skip to content

Commit

Permalink
Test errors reported for empty literals and regular expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles Baker committed Jul 16, 2023
1 parent db13bbe commit feb0030
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 8 deletions.
119 changes: 119 additions & 0 deletions src/lalr/lalr_test/TestParsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,26 @@ SUITE( Parsers )
}
};

struct CollectErrorPolicy : public ErrorPolicy
{
std::vector<int> errors;

CollectErrorPolicy()
: errors{}
{
}

int error( int index ) const
{
return index >= 0 && index < int(errors.size()) ? errors[index] : PARSER_ERROR_NONE;
}

void lalr_error( int /*line*/, int /*column*/, int error, const char* /*format*/, va_list /*args*/ )
{
errors.push_back( error );
}
};

TEST( OrOperator )
{
const char* or_grammar =
Expand Down Expand Up @@ -1274,4 +1294,103 @@ SUITE( Parsers )
CHECK( parser.accepted() );
CHECK( parser.full() );
}

TEST( UnterminatedLiteral )
{
const char* unterminated_literal =
"UnterminatedLiteral {\n"
" unterminated: 'abc;\n"
"}\n"
;

CheckErrorPolicy error_policy{ LALR_ERROR_UNTERMINATED_LITERAL };
GrammarCompiler compiler;
int errors = compiler.compile( unterminated_literal, unterminated_literal + strlen(unterminated_literal), &error_policy );
CHECK( errors > 0 );
Parser<const char*> parser( compiler.parser_state_machine() );
CHECK( !parser.valid() );
}

TEST( UnterminatedRegularExpression )
{
const char* unterminated_regex =
"UnterminatedRegularExpression {\n"
" unterminated: \"abc;\n"
"}\n"
;

CheckErrorPolicy error_policy{ LALR_ERROR_UNTERMINATED_LITERAL };
GrammarCompiler compiler;
int errors = compiler.compile( unterminated_regex, unterminated_regex + strlen(unterminated_regex), &error_policy );
CHECK( errors > 0 );
Parser<const char*> parser( compiler.parser_state_machine() );
CHECK( !parser.valid() );
}

TEST( UnterminatedWhitespace )
{
const char* unterminate_whitespace =
"UnterminatedWhitespace {\n"
" %whitespace \"abc;\n"
"}\n"
;

CheckErrorPolicy error_policy{ LALR_ERROR_UNTERMINATED_LITERAL };
GrammarCompiler compiler;
int errors = compiler.compile( unterminate_whitespace, unterminate_whitespace + strlen(unterminate_whitespace), &error_policy );
CHECK( errors > 0 );
Parser<const char*> parser( compiler.parser_state_machine() );
CHECK( !parser.valid() );
}

TEST( EmptyLiteral )
{
const char* empty_literal =
"EmptyLiteral {\n"
" empty: '';\n"
"}\n"
;

CollectErrorPolicy error_policy;
GrammarCompiler compiler;
int errors = compiler.compile( empty_literal, empty_literal + strlen(empty_literal), &error_policy );
CHECK( errors > 0 );
CHECK_EQUAL( LALR_ERROR_EMPTY_LITERAL, error_policy.error(0) );
Parser<const char*> parser( compiler.parser_state_machine() );
CHECK( !parser.valid() );
}

TEST( EmptyRegularExpression )
{
const char* empty_regex =
"EmptyRegularExpression {\n"
" empty: \"\";\n"
"}\n"
;

CollectErrorPolicy error_policy;
GrammarCompiler compiler;
int errors = compiler.compile( empty_regex, empty_regex + strlen(empty_regex), &error_policy );
CHECK( errors > 0 );
CHECK_EQUAL( LALR_ERROR_EMPTY_LITERAL, error_policy.error(0) );
Parser<const char*> parser( compiler.parser_state_machine() );
CHECK( !parser.valid() );
}

TEST( EmptyWhitespace )
{
const char* empty_whitespace =
"EmptyWhitespace {\n"
" %whitespace \"\";\n"
"}\n"
;

CollectErrorPolicy error_policy;
GrammarCompiler compiler;
int errors = compiler.compile( empty_whitespace, empty_whitespace + strlen(empty_whitespace), &error_policy );
CHECK( errors > 0 );
CHECK_EQUAL( LALR_ERROR_EMPTY_LITERAL, error_policy.error(0) );
Parser<const char*> parser( compiler.parser_state_machine() );
CHECK( !parser.valid() );
}
}
28 changes: 20 additions & 8 deletions src/lalr/lalr_test/TestPrecedenceDirectives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <lalr/ErrorPolicy.hpp>
#include <lalr/ErrorCode.hpp>
#include <UnitTest++/UnitTest++.h>
#include <vector>
#include <initializer_list>
#include <stdio.h>
#include <string.h>

Expand All @@ -17,22 +19,31 @@ SUITE( PrecedenceDirectives )
{
struct EventSink : public ErrorPolicy
{
int expected_error_;
std::vector<int> expected_errors_;
int errors_;

EventSink( int expected_error )
: expected_error_( expected_error )
: expected_errors_()
, errors_( 0 )
{
expected_errors_.push_back( expected_error );
}

EventSink( std::initializer_list<int> expected_errors )
: expected_errors_()
, errors_( 0 )
{
expected_errors_.insert( expected_errors_.end(), expected_errors.begin(), expected_errors.end() );
}

void lalr_error( int /*line*/, int /*column*/, int error, const char* /*format*/, va_list /*args*/ )
{
CHECK( errors_ < int(expected_errors_.size()) );
if ( errors_ < int(expected_errors_.size()) )
{
CHECK_EQUAL( expected_errors_[errors_], error );
}
++errors_;
// char message [1024];
// vsnprintf( message, sizeof(message), format, args );
// printf( "%s\n", message );
CHECK( error == expected_error_ );
}
};

Expand Down Expand Up @@ -92,8 +103,9 @@ SUITE( PrecedenceDirectives )
"%left 'return' 'break' 'continue' 'if' 'while' 'for' identifier '{'; \n"
"} \n"
;
EventSink event_sink( LALR_ERROR_UNTERMINATED_LITERAL );
EventSink event_sink{ LALR_ERROR_UNTERMINATED_LITERAL, LALR_ERROR_SYNTAX, LALR_ERROR_SYNTAX };
GrammarCompiler compiler;
compiler.compile( grammar, grammar + strlen(grammar), &event_sink );
int errors = compiler.compile( grammar, grammar + strlen(grammar), &event_sink );
CHECK( errors > 0 );
}
}

0 comments on commit feb0030

Please sign in to comment.