Add more tests
This commit is contained in:
parent
7a35d457d9
commit
dfc0fd87d7
@ -4,6 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
enum class TokenType { Type, Identifier, Int, Plus, Minus, DoublePlus, DoubleMinus, Star, Slash, Percent, Equal, Semicolon, LParenthese, RParenthese };
|
enum class TokenType { Type, Identifier, Int, Plus, Minus, DoublePlus, DoubleMinus, Star, Slash, Percent, Equal, Semicolon, LParenthese, RParenthese };
|
||||||
@ -16,6 +17,12 @@ struct Token {
|
|||||||
TokenData data { };
|
TokenData data { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TokenError : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
explicit TokenError(const std::string& message)
|
||||||
|
: std::runtime_error(message) {}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parses a string into a vector of tokens
|
Parses a string into a vector of tokens
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <regex>
|
#include <regex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <bits/stdc++.h>
|
|
||||||
#include "include/tokenize.h"
|
#include "include/tokenize.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -152,8 +151,7 @@ vector<Token> tokenize(string str) {
|
|||||||
str.erase(0, 1);
|
str.erase(0, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cerr << "Unknown token: \"" << str << "\"" << endl;
|
throw TokenError("Unknown token {}");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,17 +17,20 @@ int main() {
|
|||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(execute("10 + 3 * (7 - 2);") == 25),
|
_TEST_NO_EXCEPTION(execute("10 + 3 * (7 - 2);") == 25),
|
||||||
"Priorités"
|
"Priorités",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(execute("12 - 4 - 20;") == -12),
|
_TEST_NO_EXCEPTION(execute("12 - 4 - 20;") == -12),
|
||||||
"Ordre de soustraction"
|
"Ordre de soustraction",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(execute("-7 + 13 + -6;") == 0),
|
_TEST_NO_EXCEPTION(execute("-7 + 13 + -6;") == 0),
|
||||||
"Opérateurs unaires"
|
"Opérateurs unaires",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
#define _TEST_PRESENTATION(description) { printf("\n" BLUE "#### %s:" BOLD "%s" RESET BLUE " #####" RESET "\n", __FILE__, description); }
|
#define _TEST_PRESENTATION(description) { printf("\n" BLUE "#### %s:" BOLD "%s" RESET BLUE " #####" RESET "\n", __FILE__, description); }
|
||||||
|
|
||||||
#define _TEST_ASSERT(condition, description) { \
|
#define _TEST_ASSERT(condition, description, show_ok) { \
|
||||||
if (condition) { \
|
if (condition) { \
|
||||||
printf("[" GREEN "OK" RESET "] %s:%d: %s\n", __FILE__, __LINE__, description); \
|
if (show_ok) printf("[" GREEN "OK" RESET "] %s:%d: %s\n", __FILE__, __LINE__, description); \
|
||||||
} else { \
|
} else { \
|
||||||
printf("[" RED "ERREUR" RESET "] %s:%d: %s\n", __FILE__, __LINE__, description); \
|
printf("[" RED "ERREUR" RESET "] %s:%d: %s\n", __FILE__, __LINE__, description); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
@ -29,5 +29,17 @@
|
|||||||
} \
|
} \
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
#define _TEST_IS_EXCEPTION(expr, excep) \
|
||||||
|
[&]() -> bool { \
|
||||||
|
try { \
|
||||||
|
(expr); \
|
||||||
|
return false; \
|
||||||
|
} catch (const excep& e) { \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
catch (...) { \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
}()
|
||||||
|
|
||||||
#endif
|
#endif
|
107
test/tokenize.cpp
Normal file
107
test/tokenize.cpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "include/test.h"
|
||||||
|
|
||||||
|
#include "../src/include/tokenize.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
_TEST_PRESENTATION("Lexer");
|
||||||
|
|
||||||
|
/* Complex input */
|
||||||
|
{
|
||||||
|
string input = "int a = x+++7;";
|
||||||
|
|
||||||
|
vector<Token> tokens = tokenize(input);
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens.size() == 8),
|
||||||
|
"Il devrait y avoir 8 tokens",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens[0].type == TokenType::Type),
|
||||||
|
"Le premier token devrait être de type 'Type'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(get<Type>(tokens[0].data) == Type::Int),
|
||||||
|
"Les données du premier token devraient être 'Int'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens[1].type == TokenType::Identifier),
|
||||||
|
"Le deuxième token devrait être un 'Identifiant'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(get<string>(tokens[1].data) == "a"),
|
||||||
|
"Les données du deuxième token devraient être 'a'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens[2].type == TokenType::Equal),
|
||||||
|
"Le troisième token devrait être 'Equal'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens[3].type == TokenType::Identifier),
|
||||||
|
"Le quatrième token devrait être un 'Identifiant'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(get<string>(tokens[3].data) == "x"),
|
||||||
|
"Les données du quatrième token devraient être 'x'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens[4].type == TokenType::DoublePlus),
|
||||||
|
"Le cinquième token devrait être 'DoublePlus'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens[5].type == TokenType::Plus),
|
||||||
|
"Le cinquième token devrait être 'Plus'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens[6].type == TokenType::Int),
|
||||||
|
"Le premier token devrait être de type 'Int'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(get<int>(tokens[6].data) == 7),
|
||||||
|
"Les données du premier token devraient être '7'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_NO_EXCEPTION(tokens[7].type == TokenType::Semicolon),
|
||||||
|
"Le cinquième token devrait être 'Semicolon'",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
_TEST_ASSERT(true, "+++", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Incorrect input */
|
||||||
|
{
|
||||||
|
string input = "int a = 10 @;";
|
||||||
|
|
||||||
|
_TEST_ASSERT(
|
||||||
|
_TEST_IS_EXCEPTION(tokenize(input), TokenError),
|
||||||
|
"Token invalide",
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -17,27 +17,32 @@ int main() {
|
|||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(execute("int uneVariableFarfelue__ = 12;") == 12),
|
_TEST_NO_EXCEPTION(execute("int uneVariableFarfelue__ = 12;") == 12),
|
||||||
"Déclaration avec assignement"
|
"Déclaration avec assignement",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(execute("int x = 5; x = x + 3;") == 8),
|
_TEST_NO_EXCEPTION(execute("int x = 5; x = x + 3;") == 8),
|
||||||
"Déclaration puis assignement"
|
"Déclaration puis assignement",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(execute("int a = 27; ++a;") == 28),
|
_TEST_NO_EXCEPTION(execute("int a = 27; ++a;") == 28),
|
||||||
"Incrémentation par la gauche"
|
"Incrémentation par la gauche",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(execute("int a = 27; a--;") == 27),
|
_TEST_NO_EXCEPTION(execute("int a = 27; a--;") == 27),
|
||||||
"Décrémentation par la droite"
|
"Décrémentation par la droite",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(execute("int a = 27; -(+-++a);") == 28),
|
_TEST_NO_EXCEPTION(execute("int a = 27; -(+-++a);") == 28),
|
||||||
"Incrémentation et opérations unaires"
|
"Incrémentation et opérations unaires",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user