Skip to content

Commit

Permalink
(#271) regex lexer tests
Browse files Browse the repository at this point in the history
  • Loading branch information
xendalm committed Nov 10, 2023
1 parent 3ba9ca3 commit 6978ad8
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 21 deletions.
3 changes: 2 additions & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ AllowShortIfStatementsOnASingleLine: Never
SpaceBeforeParens: ControlStatements
AllowShortFunctionsOnASingleLine: Empty
AlignAfterOpenBracket: Align
ColumnLimit: 100
ColumnLimit: 100
BinPackArguments: false
57 changes: 47 additions & 10 deletions apps/UnitTestsApp/src/UnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,44 @@
#include "gtest/gtest.h"
#include <functional>

TEST(TestCaseName, Test_regex_minus) {
string str = "^(c^(a^(b)d))e";
Regex r1(str);
string r1_str = r1.to_txt();
Regex r2(r1_str);
ASSERT_EQ(true, Regex::equivalent(r1, r2));
TEST(ParseStringTest, Test_regex_lexer) {

Check warning on line 13 in apps/UnitTestsApp/src/UnitTests.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/apps/UnitTestsApp/src/UnitTests.cpp:13:1 [modernize-use-trailing-return-type]

use a trailing return type for this function

Check warning on line 13 in apps/UnitTestsApp/src/UnitTests.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/apps/UnitTestsApp/src/UnitTests.cpp:13:21 [readability-named-parameter]

all parameters should be named in a function
using L = AlgExpression::Lexeme::Type;

struct Test {

Check warning on line 16 in apps/UnitTestsApp/src/UnitTests.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/apps/UnitTestsApp/src/UnitTests.cpp:16:9 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: regex_str, want_err
string regex_str;
bool want_err;
int lexemes_len = 0;
};

vector<Test> tests = {

Check warning on line 22 in apps/UnitTestsApp/src/UnitTests.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/apps/UnitTestsApp/src/UnitTests.cpp:22:15 [cppcoreguidelines-init-variables]

variable 'tests' is not initialized
{"[]", true},
{"[]:", true},
{"[a]", true},
{"[a]:", true},
{"[[a]:1", true},
{"a]:1", true},
{"[a]:1", false, 3},
{"&", true},
{"&1", false, 1},
{"[b[a]:1&1]:2&2", false, 11},
};

for (const auto& t : tests) {
stringstream message;
message << "Case: " << t.regex_str << ", WantErr: " << t.want_err;
SCOPED_TRACE(message.str());

vector<AlgExpression::Lexeme> l = AlgExpression::parse_string(t.regex_str);
ASSERT_FALSE(l.empty());

if (t.want_err) {
ASSERT_EQ(L::error, l[0].type);
} else {
ASSERT_NE(L::error, l[0].type);
ASSERT_EQ(t.lexemes_len, l.size());
// TODO: добавить проверку содержимого l
}
}
}

TEST(TestCaseName, Test_random_regex_parsing) {

Check warning on line 53 in apps/UnitTestsApp/src/UnitTests.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/apps/UnitTestsApp/src/UnitTests.cpp:53:1 [modernize-use-trailing-return-type]

use a trailing return type for this function

Check warning on line 53 in apps/UnitTestsApp/src/UnitTests.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/apps/UnitTestsApp/src/UnitTests.cpp:53:18 [readability-named-parameter]

all parameters should be named in a function
Expand Down Expand Up @@ -246,14 +278,19 @@ TEST(TestCaseName, Test_ambiguity) {
{16, "(a|b|c)*(a|b|c|d)(a|b|c)*|(ac*|ad*)*", glushkov, FiniteAutomaton::almost_unambigious},
{17,
"(ab)*ab(ab)*|(ac)*(ac)*|(d|c)*", // (abab)*abab(abab)*|(aac)*(aac)*|(b|d|c)*
glushkov, FiniteAutomaton::almost_unambigious},
glushkov,
FiniteAutomaton::almost_unambigious},
{18, "(abab)*abab(abab)*|(aac)*(aac)*", glushkov, FiniteAutomaton::polynomially_ambigious},
{19, "(ab)*ab(ab)*", // (abab)*abab(abab)*
glushkov, FiniteAutomaton::polynomially_ambigious},
{19,
"(ab)*ab(ab)*", // (abab)*abab(abab)*
glushkov,
FiniteAutomaton::polynomially_ambigious},
{20, "(ab)*ab(ab)*|(ac)*(ac)*", glushkov, FiniteAutomaton::polynomially_ambigious},
// {21, "(a|b)*(f*)*q", thompson,
// FiniteAutomaton::exponentially_ambiguous},
{22, "((bb*c|c)c*b|bb*b|b)(b|(c|bb*c)c*b|bb*b)*", glushkov,
{22,
"((bb*c|c)c*b|bb*b|b)(b|(c|bb*c)c*b|bb*b)*",
glushkov,
FiniteAutomaton::exponentially_ambiguous},
};

Expand Down
10 changes: 10 additions & 0 deletions libs/Objects/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Set the project name
project(Objects)

include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

# Create a sources variable with a link to all cpp files to compile
set(SOURCES
src/TransformationMonoid.cpp
Expand All @@ -26,4 +35,5 @@ target_include_directories(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME}
Fraction
AutomatonToImage
gtest
)
5 changes: 4 additions & 1 deletion libs/Objects/include/Objects/AlgExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

#include "BaseObject.h"
#include "iLogTemplate.h"
#include "gtest/gtest.h"
#include <map>
#include <unordered_map>

class AlgExpression : public BaseObject {
FRIEND_TEST(ParseStringTest, Test_regex_lexer);

protected:
struct Lexeme {
enum Type {
Expand All @@ -15,7 +18,7 @@ class AlgExpression : public BaseObject {
alt, // |
conc, // .
star, // *
minus, // ^
minus, // ^
symb, // alphabet symbol
eps, // Epsilon
squareBrL, // [
Expand Down
21 changes: 12 additions & 9 deletions libs/Objects/src/AlgExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ bool AlgExpression::from_string(const string& str) {
return true;
}

vector<Regex::Lexeme> l = parse_string(str);
vector<Lexeme> l = parse_string(str);
AlgExpression* root = expr(l, 0, l.size());

if (root == nullptr || root->type == eps) {
Expand Down Expand Up @@ -440,7 +440,7 @@ AlgExpression* AlgExpression::expr(const vector<AlgExpression::Lexeme>& lexemes,
if (!p) {
p = scan_par(lexemes, index_start, index_end);
}

return p;
}

Expand All @@ -451,11 +451,10 @@ void AlgExpression::update_balance(const AlgExpression::Lexeme& l, int& balance)
if (l.type == Lexeme::Type::parR || l.type == Lexeme::Type::squareBrR) {
balance--;
}
return;
}

AlgExpression* AlgExpression::scan_minus(const vector<AlgExpression::Lexeme>& lexemes,
int index_start, int index_end) {
int index_start, int index_end) {
AlgExpression* p = nullptr;

if (lexemes[index_start].type != Lexeme::Type::minus) {
Expand All @@ -473,7 +472,7 @@ AlgExpression* AlgExpression::scan_minus(const vector<AlgExpression::Lexeme>& le
p->type = minus;

p->alphabet = l->alphabet;
return p;
return p;
}

AlgExpression* AlgExpression::scan_conc(const vector<AlgExpression::Lexeme>& lexemes,
Expand Down Expand Up @@ -638,15 +637,19 @@ bool AlgExpression::contains_eps() const {
}

bool AlgExpression::equality_checker(const AlgExpression* expr1, const AlgExpression* expr2) {
if (expr1 == nullptr && expr2 == nullptr) return true;
if (expr1 == nullptr || expr2 == nullptr) return false;
if (expr1->value.type != expr2->value.type) return false;
if (expr1 == nullptr && expr2 == nullptr)
return true;
if (expr1 == nullptr || expr2 == nullptr)
return false;
if (expr1->value.type != expr2->value.type)
return false;

if (expr1->value.type == Lexeme::Type::symb) {
alphabet_symbol r1_symb, r2_symb;
r1_symb = expr1->value.symbol;
r2_symb = expr2->value.symbol;
if (r1_symb != r2_symb) return false;
if (r1_symb != r2_symb)
return false;
}

if (equality_checker(expr1->term_l, expr2->term_l) &&
Expand Down

0 comments on commit 6978ad8

Please sign in to comment.