mirror of
https://github.com/jorenchik/mdemory.git
synced 2026-03-22 00:26:21 +00:00
base functional unit tests for transpiler
This commit is contained in:
@@ -6,8 +6,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|||||||
|
|
||||||
set(
|
set(
|
||||||
CMAKE_CXX_FLAGS_DEBUG
|
CMAKE_CXX_FLAGS_DEBUG
|
||||||
"${CMAKE_CXX_FLAGS_DEBUG} -g3 -O0 -ggdb -fvar-tracking-assignments -fno-inline"
|
"${CMAKE_CXX_FLAGS_DEBUG} -g3 -O0 -ggdb -fno-inline"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(src/transpiler)
|
add_subdirectory(src/transpiler)
|
||||||
add_subdirectory(src/qtapp)
|
add_subdirectory(src/qtapp)
|
||||||
|
add_subdirectory(src/test)
|
||||||
|
|||||||
23
src/test/CMakeLists.txt
Normal file
23
src/test/CMakeLists.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
project(MdemoryTest)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
find_package(GTest REQUIRED)
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
testTranspiler
|
||||||
|
testTranspiler.cpp
|
||||||
|
|
||||||
|
)
|
||||||
|
target_link_libraries(
|
||||||
|
testTranspiler
|
||||||
|
GTest::gtest_main
|
||||||
|
api
|
||||||
|
)
|
||||||
|
|
||||||
|
include(GoogleTest)
|
||||||
|
gtest_discover_tests(testTranspiler)
|
||||||
|
|
||||||
363
src/test/testTranspiler.cpp
Normal file
363
src/test/testTranspiler.cpp
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
#include "api.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "result.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestSimpleQuestion) {
|
||||||
|
std::string questionText = "- A question front >\n"
|
||||||
|
"- An answer\n"
|
||||||
|
"- Another answer";
|
||||||
|
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
|
||||||
|
auto questions = res.value.questions;
|
||||||
|
EXPECT_EQ(questions.size(), 1);
|
||||||
|
EXPECT_EQ(questions[0]->questionText, "A question front");
|
||||||
|
|
||||||
|
auto meQuestion = dynamic_cast<MultiElementQuestion*>(questions[0]);
|
||||||
|
EXPECT_EQ(meQuestion->type, Regular);
|
||||||
|
EXPECT_EQ(meQuestion->choices.size(), 2);
|
||||||
|
EXPECT_EQ(meQuestion->choices[0].answer, "An answer");
|
||||||
|
EXPECT_EQ(meQuestion->choices[1].answer, "Another answer");
|
||||||
|
EXPECT_EQ(meQuestion->choices[0].isCorrect, false);
|
||||||
|
EXPECT_EQ(meQuestion->choices[1].isCorrect, false);
|
||||||
|
delete meQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestChoiceQuestion) {
|
||||||
|
std::string questionText = "- A question front >\n"
|
||||||
|
"+ An answer\n"
|
||||||
|
"- Another answer";
|
||||||
|
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
|
||||||
|
auto questions = res.value.questions;
|
||||||
|
EXPECT_EQ(questions.size(), 1);
|
||||||
|
EXPECT_EQ(questions[0]->questionText, "A question front");
|
||||||
|
|
||||||
|
auto meQuestion = dynamic_cast<MultiElementQuestion*>(questions[0]);
|
||||||
|
EXPECT_EQ(meQuestion->type, MultiChoice);
|
||||||
|
EXPECT_EQ(meQuestion->choices.size(), 2);
|
||||||
|
EXPECT_EQ(meQuestion->choices[0].answer, "An answer");
|
||||||
|
EXPECT_EQ(meQuestion->choices[1].answer, "Another answer");
|
||||||
|
EXPECT_EQ(meQuestion->choices[0].isCorrect, true);
|
||||||
|
EXPECT_EQ(meQuestion->choices[1].isCorrect, false);
|
||||||
|
delete meQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestOrderQuestion) {
|
||||||
|
std::string questionText = "- A question front >\n"
|
||||||
|
"- An answer\n"
|
||||||
|
"-^ Another answer";
|
||||||
|
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
|
||||||
|
auto questions = res.value.questions;
|
||||||
|
EXPECT_EQ(questions.size(), 1);
|
||||||
|
EXPECT_EQ(questions[0]->questionText, "A question front");
|
||||||
|
|
||||||
|
auto meQuestion = dynamic_cast<MultiElementQuestion*>(questions[0]);
|
||||||
|
EXPECT_EQ(meQuestion->type, Order);
|
||||||
|
EXPECT_EQ(meQuestion->choices.size(), 2);
|
||||||
|
EXPECT_EQ(meQuestion->choices[0].answer, "An answer");
|
||||||
|
EXPECT_EQ(meQuestion->choices[1].answer, "Another answer");
|
||||||
|
EXPECT_EQ(meQuestion->choices[0].isCorrect, false);
|
||||||
|
EXPECT_EQ(meQuestion->choices[1].isCorrect, false);
|
||||||
|
delete meQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestGroupQuestion) {
|
||||||
|
std::string questionText = "- A question front >\n"
|
||||||
|
"- Group 1:\n"
|
||||||
|
"- Element 1"
|
||||||
|
"- Element 2"
|
||||||
|
"- Group 2:\n"
|
||||||
|
"- Group 3:\n"
|
||||||
|
"- Element 1";
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
|
||||||
|
auto questions = res.value.questions;
|
||||||
|
EXPECT_EQ(questions.size(), 1);
|
||||||
|
EXPECT_EQ(questions[0]->questionText, "A question front");
|
||||||
|
|
||||||
|
auto grQuestion = dynamic_cast<GroupQuestion*>(questions[0]);
|
||||||
|
EXPECT_EQ(grQuestion->groups.size(), 3);
|
||||||
|
EXPECT_EQ(grQuestion->groups[0].name, "Group 1");
|
||||||
|
EXPECT_EQ(grQuestion->groups[1].name, "Group 2");
|
||||||
|
EXPECT_EQ(grQuestion->groups[2].name, "Group 3");
|
||||||
|
EXPECT_EQ(grQuestion->groups[0].elements.size(), 2);
|
||||||
|
EXPECT_EQ(grQuestion->groups[1].elements.size(), 0);
|
||||||
|
EXPECT_EQ(grQuestion->groups[2].elements.size(), 1);
|
||||||
|
delete grQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestConflictingElements) {
|
||||||
|
std::string questionText;
|
||||||
|
Result<ParseInfo> res;
|
||||||
|
|
||||||
|
// Iespējamie elementu modifikatori:
|
||||||
|
// -^ secības
|
||||||
|
// + izvēles (pareiza atbilde)
|
||||||
|
// : grupas
|
||||||
|
// Apskatīsim visas konfliktējošas kombinācijas.
|
||||||
|
|
||||||
|
// -^ un :
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- An answer 1\n"
|
||||||
|
"-^ An answer 2\n"
|
||||||
|
"- An answer 3\n"
|
||||||
|
"- An answer 4:\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
|
||||||
|
// : un -^
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- An answer 1\n"
|
||||||
|
"- An answer 2:\n"
|
||||||
|
"- An answer 3\n"
|
||||||
|
"-^ An answer 4\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
|
||||||
|
// + un :
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- An answer 1\n"
|
||||||
|
"+ An answer 2\n"
|
||||||
|
"- An answer 3\n"
|
||||||
|
"- An answer 4:\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
|
||||||
|
// : un +
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- An answer 1\n"
|
||||||
|
"- An answer 2:\n"
|
||||||
|
"- An answer 3\n"
|
||||||
|
"+ An answer 4\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
|
||||||
|
// -^ un +
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- An answer 1\n"
|
||||||
|
"-^ An answer 2\n"
|
||||||
|
"- An answer 3\n"
|
||||||
|
"+ An answer 4\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
|
||||||
|
// + un -^
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- An answer 1\n"
|
||||||
|
"+ An answer 2\n"
|
||||||
|
"- An answer 3\n"
|
||||||
|
"-^ An answer 4\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestGroupQuestionWithLeadingElements) {
|
||||||
|
std::string questionText = "- A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n"
|
||||||
|
"- Group 1:\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n"
|
||||||
|
"- Element 3\n";
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestIncorrectTimestamp) {
|
||||||
|
// Kontrole.
|
||||||
|
std::string questionText = "- A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
|
||||||
|
// Pārbaude.
|
||||||
|
questionText = "Incorrect timestamp\n"
|
||||||
|
"- A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestUnexpectedCooldown) {
|
||||||
|
std::string questionText;
|
||||||
|
Result<ParseInfo> res;
|
||||||
|
|
||||||
|
// Kontrole.
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
|
||||||
|
// Pārbaude.
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2 [0.12]\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestCooldownParse) {
|
||||||
|
std::string questionText;
|
||||||
|
Result<ParseInfo> res;
|
||||||
|
Question *question;
|
||||||
|
|
||||||
|
// Ar punktu.
|
||||||
|
questionText = "- [12.21] A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
question = res.value.questions[0];
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
EXPECT_EQ(question->cooldown, 12.21);
|
||||||
|
delete question;
|
||||||
|
|
||||||
|
// Bez punkta.
|
||||||
|
questionText = "- [12] A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
question = res.value.questions[0];
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
EXPECT_EQ(question->cooldown, 12);
|
||||||
|
delete question;
|
||||||
|
|
||||||
|
// Negatīvs.
|
||||||
|
questionText = "- [-12.21] A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
|
||||||
|
// Nav skaitlis.
|
||||||
|
questionText = "- [NotANumber] A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestParsesTime) {
|
||||||
|
std::string questionText = "12.02.2022 12\\:25\n"
|
||||||
|
"- A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
const time_t expectedTime = 1644668700;
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
EXPECT_EQ(res.value.lastTrainedAt, expectedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestOrderQuestionDuplicates) {
|
||||||
|
std::string questionText;
|
||||||
|
Result<ParseInfo> res;
|
||||||
|
|
||||||
|
// Kontrole.
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n"
|
||||||
|
"- Element 3\n"
|
||||||
|
"- Element 4\n"
|
||||||
|
"-^ Element 5\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
|
||||||
|
// Pārbaude.
|
||||||
|
questionText = "- A question front >\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n"
|
||||||
|
"- Element 3\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"-^ Element 5\n";
|
||||||
|
res = transpile(questionText);
|
||||||
|
EXPECT_NE(res.error, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestRemovesExcessiveWhitespace) {
|
||||||
|
std::string questionText = "- \n\t A question\n\t front\n\t >\n"
|
||||||
|
"-\n\t An\n\t answer\n\t "
|
||||||
|
"-\n\t Another\n\t answer\n\t ";
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
|
||||||
|
auto questions = res.value.questions;
|
||||||
|
EXPECT_EQ(questions[0]->questionText, "A question front");
|
||||||
|
|
||||||
|
auto meQuestion = dynamic_cast<MultiElementQuestion*>(questions[0]);
|
||||||
|
EXPECT_EQ(meQuestion->choices[0].answer, "An answer");
|
||||||
|
EXPECT_EQ(meQuestion->choices[1].answer, "Another answer");
|
||||||
|
delete meQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranspilerTest, TestTranspilesMultipleQuestions) {
|
||||||
|
std::string questionText = "- Question 1 >\n"
|
||||||
|
"- Answer 1\n"
|
||||||
|
"- Answer 2\n"
|
||||||
|
"- Question 2 >\n"
|
||||||
|
"- Answer 1\n"
|
||||||
|
"+ Answer 2\n"
|
||||||
|
"- Question 3 >\n"
|
||||||
|
"- Answer 1\n"
|
||||||
|
"-^ Answer 2\n"
|
||||||
|
"- Question 4 >\n"
|
||||||
|
"- Group 1:\n"
|
||||||
|
"- Element 1\n"
|
||||||
|
"- Element 2\n";
|
||||||
|
auto res = transpile(questionText);
|
||||||
|
EXPECT_EQ(res.error, "");
|
||||||
|
|
||||||
|
auto questions = res.value.questions;
|
||||||
|
EXPECT_EQ(questions.size(), 4);
|
||||||
|
|
||||||
|
EXPECT_EQ(questions[0]->questionText, "Question 1");
|
||||||
|
EXPECT_EQ(questions[1]->questionText, "Question 2");
|
||||||
|
EXPECT_EQ(questions[2]->questionText, "Question 3");
|
||||||
|
EXPECT_EQ(questions[3]->questionText, "Question 4");
|
||||||
|
|
||||||
|
auto question = dynamic_cast<MultiElementQuestion*>(questions[0]);
|
||||||
|
EXPECT_EQ(question->type, Regular);
|
||||||
|
EXPECT_EQ(question->choices.size(), 2);
|
||||||
|
EXPECT_EQ(question->choices[0].answer, "Answer 1");
|
||||||
|
EXPECT_EQ(question->choices[1].answer, "Answer 2");
|
||||||
|
EXPECT_EQ(question->choices[0].isCorrect, false);
|
||||||
|
EXPECT_EQ(question->choices[1].isCorrect, false);
|
||||||
|
delete question;
|
||||||
|
|
||||||
|
question = dynamic_cast<MultiElementQuestion*>(questions[1]);
|
||||||
|
EXPECT_EQ(question->type, MultiChoice);
|
||||||
|
EXPECT_EQ(question->choices.size(), 2);
|
||||||
|
EXPECT_EQ(question->choices[0].answer, "Answer 1");
|
||||||
|
EXPECT_EQ(question->choices[1].answer, "Answer 2");
|
||||||
|
EXPECT_EQ(question->choices[0].isCorrect, false);
|
||||||
|
EXPECT_EQ(question->choices[1].isCorrect, true);
|
||||||
|
delete question;
|
||||||
|
|
||||||
|
question = dynamic_cast<MultiElementQuestion*>(questions[2]);
|
||||||
|
EXPECT_EQ(question->type, Order);
|
||||||
|
EXPECT_EQ(question->choices.size(), 2);
|
||||||
|
EXPECT_EQ(question->choices[0].answer, "Answer 1");
|
||||||
|
EXPECT_EQ(question->choices[1].answer, "Answer 2");
|
||||||
|
EXPECT_EQ(question->choices[0].isCorrect, false);
|
||||||
|
EXPECT_EQ(question->choices[1].isCorrect, false);
|
||||||
|
delete question;
|
||||||
|
|
||||||
|
auto groupQuestion = dynamic_cast<GroupQuestion*>(questions[3]);
|
||||||
|
EXPECT_EQ(groupQuestion->groups.size(), 1);
|
||||||
|
auto group = groupQuestion->groups[0];
|
||||||
|
EXPECT_EQ(group.name, "Group 1");
|
||||||
|
EXPECT_EQ(group.elements[0], "Element 1");
|
||||||
|
EXPECT_EQ(group.elements[1], "Element 2");
|
||||||
|
delete groupQuestion;
|
||||||
|
}
|
||||||
@@ -23,14 +23,14 @@ bool sof;
|
|||||||
/*
|
/*
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
void trimString(std::string &str, std::string trimChars) {
|
void trimString(std::string *str, std::string trimChars) {
|
||||||
|
|
||||||
// Noņem kreisās puses simbolus.
|
// Noņem kreisās puses simbolus.
|
||||||
int padSize = 0;
|
int padSize = 0;
|
||||||
bool pad = false;
|
bool pad = false;
|
||||||
for (size_t i = 0; i < str.size(); ++i) {
|
for (size_t i = 0; i < str->size(); ++i) {
|
||||||
for (size_t k = 0; k < trimChars.size(); ++k) {
|
for (size_t k = 0; k < trimChars.size(); ++k) {
|
||||||
if (str[i] == trimChars[k]) {
|
if ((*str)[i] == trimChars[k]) {
|
||||||
padSize++;
|
padSize++;
|
||||||
pad = true;
|
pad = true;
|
||||||
break;
|
break;
|
||||||
@@ -42,15 +42,15 @@ void trimString(std::string &str, std::string trimChars) {
|
|||||||
pad = false;
|
pad = false;
|
||||||
}
|
}
|
||||||
if (padSize > 0) {
|
if (padSize > 0) {
|
||||||
str.erase(0, padSize);
|
str->erase(0, padSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Noņem labās puses simbolus.
|
// Noņem labās puses simbolus.
|
||||||
padSize = 0;
|
padSize = 0;
|
||||||
pad = false;
|
pad = false;
|
||||||
for (size_t i = str.size(); i-- > 0;) {
|
for (size_t i = str->size(); i-- > 0;) {
|
||||||
for (size_t k = 0; k < trimChars.size(); ++k) {
|
for (size_t k = 0; k < trimChars.size(); ++k) {
|
||||||
if (str[i] == trimChars[k]) {
|
if ((*str)[i] == trimChars[k]) {
|
||||||
padSize++;
|
padSize++;
|
||||||
pad = true;
|
pad = true;
|
||||||
break;
|
break;
|
||||||
@@ -62,7 +62,7 @@ void trimString(std::string &str, std::string trimChars) {
|
|||||||
pad = false;
|
pad = false;
|
||||||
}
|
}
|
||||||
if (padSize > 0) {
|
if (padSize > 0) {
|
||||||
str.erase(str.end() - padSize, str.end());
|
str->erase(str->end() - padSize, str->end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ void tokenWithBuffer(
|
|||||||
std::string token(buffer.end() - tokenLen, buffer.end());
|
std::string token(buffer.end() - tokenLen, buffer.end());
|
||||||
if (buffer.size() > tokenLen) {
|
if (buffer.size() > tokenLen) {
|
||||||
std::string prevFragment(buffer.begin(), buffer.end() - tokenLen);
|
std::string prevFragment(buffer.begin(), buffer.end() - tokenLen);
|
||||||
trimString(prevFragment, " \n\t");
|
trimString(&prevFragment, " \n\t");
|
||||||
if (prevFragment.length() > 0) {
|
if (prevFragment.length() > 0) {
|
||||||
tokens.push_back(Token{
|
tokens.push_back(Token{
|
||||||
textType,
|
textType,
|
||||||
|
|||||||
14
src/transpiler/lexer.plist
Normal file
14
src/transpiler/lexer.plist
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>clang_version</key>
|
||||||
|
<string>clang version 18.1.8</string>
|
||||||
|
<key>diagnostics</key>
|
||||||
|
<array>
|
||||||
|
</array>
|
||||||
|
<key>files</key>
|
||||||
|
<array>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
14
src/transpiler/main.plist
Normal file
14
src/transpiler/main.plist
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>clang_version</key>
|
||||||
|
<string>clang version 18.1.8</string>
|
||||||
|
<key>diagnostics</key>
|
||||||
|
<array>
|
||||||
|
</array>
|
||||||
|
<key>files</key>
|
||||||
|
<array>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -144,25 +144,18 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (isInBounds(i) && tokens[i].tokenType == TokenType::TextFragment) {
|
if (isInBounds(i) && tokens[i].tokenType == TokenType::TextFragment) {
|
||||||
try {
|
const std::string format = "%d.%m.%Y %H:%M";
|
||||||
auto parseToUTCTime = [](const std::string datetime, std::string format) {
|
const std::string datetime = tokens[i].content.c_str();
|
||||||
std::tm tm = {};
|
std::tm tm = {};
|
||||||
std::istringstream ss(datetime);
|
std::istringstream ss(datetime);
|
||||||
ss >> std::get_time(&tm, format.c_str());
|
ss >> std::get_time(&tm, format.c_str());
|
||||||
if (ss.fail()) {
|
if (ss.fail()) {
|
||||||
throw std::runtime_error("Neizdevās nolasīt datuma un laiku");
|
|
||||||
}
|
|
||||||
std::time_t time = timegm(&tm);
|
|
||||||
return time;
|
|
||||||
};
|
|
||||||
|
|
||||||
time = parseToUTCTime(tokens[i].content.c_str(), "%d.%m.%Y %H:%M");
|
|
||||||
} catch (std::exception e) {
|
|
||||||
return makeResult(
|
return makeResult(
|
||||||
e.what(),
|
"Neizdevās nolasīt datuma un laiku",
|
||||||
tokens[i]
|
tokens[i]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
time = timegm(&tm);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,14 +167,14 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
bool isOrderQuestion = false;
|
bool isOrderQuestion = false;
|
||||||
bool isGroupQuestion = false;
|
bool isGroupQuestion = false;
|
||||||
bool isPlusQuestion = false;
|
bool isPlusQuestion = false;
|
||||||
|
bool hasGroupEncountered = false;
|
||||||
Token questionStartToken;
|
Token questionStartToken;
|
||||||
|
|
||||||
// Start element parsing & add to the offset.
|
// Start element parsing & add to the offset.
|
||||||
if (isInBounds(i + 1) && tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
if (isInBounds(i + 1) && tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
||||||
return makeResult(
|
return makeResult(
|
||||||
"Nevar izmantot secības modifikatoru ('^') jautājuma sākumā",
|
"Nevar izmantot secības modifikatoru ('^') jautājuma sākumā",
|
||||||
tokens[i + 1]
|
tokens[i + 1]);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
questionStartToken = tokens[i];
|
questionStartToken = tokens[i];
|
||||||
@@ -235,6 +228,18 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
} else {
|
} else {
|
||||||
isDash = false;
|
isDash = false;
|
||||||
isPlusQuestion = true;
|
isPlusQuestion = true;
|
||||||
|
if (isGroupQuestion) {
|
||||||
|
return makeResult(
|
||||||
|
"jautājumos ar grupām nevar būt secības elementu ('+' and ':')",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isOrderQuestion) {
|
||||||
|
return makeResult(
|
||||||
|
"secības jautājumos nevar būt izvēles elementu ('-^' and '+')",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isInBounds(i+1) && tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
if (isInBounds(i+1) && tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
||||||
isOrder = true;
|
isOrder = true;
|
||||||
@@ -251,6 +256,12 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
tokens[i]
|
tokens[i]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (isPlusQuestion) {
|
||||||
|
return makeResult(
|
||||||
|
"izvēles jautājumos nevar būt secības elementu ('+' and '-^')",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
if (isInBounds(i + 3) && tokens[i + 3].tokenType == TokenType::MatchGroupEnd) {
|
if (isInBounds(i + 3) && tokens[i + 3].tokenType == TokenType::MatchGroupEnd) {
|
||||||
return makeResult(
|
return makeResult(
|
||||||
"secības jautājumā nevar būt grupas ('-^' and ':')",
|
"secības jautājumā nevar būt grupas ('-^' and ':')",
|
||||||
@@ -267,6 +278,15 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
tokens[i]
|
tokens[i]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (!hasGroupEncountered) {
|
||||||
|
if (questionElements.size() > 0) {
|
||||||
|
return makeResult(
|
||||||
|
"elementi grupas jautājumā nevar eksistēt bez grupas",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hasGroupEncountered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QuestionElement questionElement;
|
QuestionElement questionElement;
|
||||||
|
|||||||
14
src/transpiler/parser.plist
Normal file
14
src/transpiler/parser.plist
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>clang_version</key>
|
||||||
|
<string>clang version 18.1.8</string>
|
||||||
|
<key>diagnostics</key>
|
||||||
|
<array>
|
||||||
|
</array>
|
||||||
|
<key>files</key>
|
||||||
|
<array>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
Reference in New Issue
Block a user