mirror of
https://github.com/jorenchik/mdemory.git
synced 2026-03-22 00:26:21 +00:00
comments and error message improvements
This commit is contained in:
@@ -17,11 +17,12 @@ int32_t column;
|
|||||||
int32_t previousRow;
|
int32_t previousRow;
|
||||||
int32_t previousColumn;
|
int32_t previousColumn;
|
||||||
bool textStarted = false;
|
bool textStarted = false;
|
||||||
bool identifierStarted = false;
|
bool cooldownStarted = false;
|
||||||
bool sof;
|
bool sof;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO
|
* Noņem norādītos simbolus no simbolu virknes kreisās un labās pusēs.
|
||||||
|
* Simboli tiek noņemti līdz tiek sastapts simbols, kas nav norādīts.
|
||||||
*/
|
*/
|
||||||
void trimString(std::string *str, std::string trimChars) {
|
void trimString(std::string *str, std::string trimChars) {
|
||||||
|
|
||||||
@@ -123,12 +124,14 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& content) {
|
|||||||
for (size_t i = 0; i < content.size(); ++i) {
|
for (size_t i = 0; i < content.size(); ++i) {
|
||||||
char c = content[i];
|
char c = content[i];
|
||||||
|
|
||||||
// Apstrādā īpašos simbolus un tekstu.
|
// Pavirza faila norādi un papildina buferi.
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
row += 1;
|
row += 1;
|
||||||
column = 0;
|
column = 0;
|
||||||
}
|
}
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
|
// Simbolus, kas abilst citām tekstvienībām, var ievadīt,
|
||||||
|
// ja pirms tiem ieliek '\' simbolu.
|
||||||
i += 1;
|
i += 1;
|
||||||
if (i < content.size()) {
|
if (i < content.size()) {
|
||||||
buffer.push_back(content[i]);
|
buffer.push_back(content[i]);
|
||||||
@@ -137,6 +140,7 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& content) {
|
|||||||
} else {
|
} else {
|
||||||
buffer.push_back(c);
|
buffer.push_back(c);
|
||||||
}
|
}
|
||||||
|
// Iepriekšējā tekstvienības pozīcijas uzturēšana.
|
||||||
if (!textStarted) {
|
if (!textStarted) {
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
previousRow += 1;
|
previousRow += 1;
|
||||||
@@ -150,7 +154,7 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& content) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emitē tekstvienības.
|
// Izveido viena simbola tekstvienības, ja tāda ir sastapta.
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '[': {
|
case '[': {
|
||||||
tokenWithBuffer(
|
tokenWithBuffer(
|
||||||
@@ -161,13 +165,16 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& content) {
|
|||||||
previousRow = row;
|
previousRow = row;
|
||||||
previousColumn = column;
|
previousColumn = column;
|
||||||
textStarted = false;
|
textStarted = false;
|
||||||
identifierStarted = true;
|
|
||||||
|
// Karodziņš, lai zinātu, kad ir jānosaka pārtraukuma
|
||||||
|
// tekstvienību.
|
||||||
|
cooldownStarted = true;
|
||||||
} break;
|
} break;
|
||||||
case ']': {
|
case ']': {
|
||||||
if (!identifierStarted) {
|
if (!cooldownStarted) {
|
||||||
return {
|
return {
|
||||||
tokens,
|
tokens,
|
||||||
"Nevar beigt identifikatoru, ja tas nav iesākts",
|
"Nevar beigt pārtraukuma norādīšanu, ja tas nav iesākts",
|
||||||
tokens[i].row,
|
tokens[i].row,
|
||||||
tokens[i].column
|
tokens[i].column
|
||||||
};
|
};
|
||||||
@@ -180,7 +187,7 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& content) {
|
|||||||
previousRow = row;
|
previousRow = row;
|
||||||
previousColumn = column;
|
previousColumn = column;
|
||||||
textStarted = false;
|
textStarted = false;
|
||||||
identifierStarted = false;
|
cooldownStarted = false;
|
||||||
} break;
|
} break;
|
||||||
case '-': {
|
case '-': {
|
||||||
tokenWithBuffer(
|
tokenWithBuffer(
|
||||||
@@ -255,9 +262,13 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& content) {
|
|||||||
std::cout << "SECTION END: LEXER\n";
|
std::cout << "SECTION END: LEXER\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Leksiskā analīze ir veiksmīga - neatgriež kļūdu.
|
||||||
return {tokens, ""};
|
return {tokens, ""};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tekstvienības nosaukums latviešu valodā.
|
||||||
|
*/
|
||||||
std::string Token::toString(const TokenType* ttype) {
|
std::string Token::toString(const TokenType* ttype) {
|
||||||
switch (*ttype) {
|
switch (*ttype) {
|
||||||
case TokenType::TextFragment: return "teksta fragments";
|
case TokenType::TextFragment: return "teksta fragments";
|
||||||
@@ -275,6 +286,9 @@ std::string Token::toString(const TokenType* ttype) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tekstvienību reprezentējoša simbolu virkne atkļūdošanai.
|
||||||
|
*/
|
||||||
std::string Token::toString() const {
|
std::string Token::toString() const {
|
||||||
std::string contentStr = content;
|
std::string contentStr = content;
|
||||||
static const std::regex nextLineExp("\n", std::regex_constants::ECMAScript);
|
static const std::regex nextLineExp("\n", std::regex_constants::ECMAScript);
|
||||||
|
|||||||
@@ -10,80 +10,81 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "result.h"
|
#include "result.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "stringUtils.h"
|
#include "stringUtils.h"
|
||||||
|
|
||||||
typedef std::map<TokenType, std::vector<TokenType>> TokenAutomata;
|
typedef std::map<TokenType, std::vector<TokenType>> TokenTransitions;
|
||||||
|
|
||||||
TokenAutomata *automata = nullptr;
|
TokenTransitions *transitions = nullptr;
|
||||||
/*
|
/*
|
||||||
* Tekstvienību secības pārejas, kas nosaka, kādā secībā tekstvienības var būt.
|
* Tekstvienību secības pārejas, kas nosaka, kādā secībā tekstvienības var būt.
|
||||||
|
* Pāreja no tekstvienības A uz tekstvienību B ir atļauta, tikai ja sarakstā ar
|
||||||
|
* atslēgu tekstvienībā A ir tekstvienība B.
|
||||||
* */
|
* */
|
||||||
void initParserAutomata() {
|
void initTransitions() {
|
||||||
automata = new TokenAutomata;
|
transitions = new TokenTransitions;
|
||||||
(*automata)[TokenType::TextFragment] = {
|
(*transitions)[TokenType::TextFragment] = {
|
||||||
TokenType::QuestionEnd,
|
TokenType::QuestionEnd,
|
||||||
TokenType::ElementDashStart,
|
TokenType::ElementDashStart,
|
||||||
TokenType::ElementPlusStart,
|
TokenType::ElementPlusStart,
|
||||||
TokenType::MatchGroupEnd,
|
TokenType::MatchGroupEnd,
|
||||||
TokenType::EndOfFile,
|
TokenType::EndOfFile,
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::MatchGroupEnd] = {
|
(*transitions)[TokenType::MatchGroupEnd] = {
|
||||||
TokenType::ElementDashStart
|
TokenType::ElementDashStart
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::QuestionEnd] = {
|
(*transitions)[TokenType::QuestionEnd] = {
|
||||||
TokenType::ElementDashStart,
|
TokenType::ElementDashStart,
|
||||||
TokenType::ElementPlusStart
|
TokenType::ElementPlusStart
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::ElementDashStart] = {
|
(*transitions)[TokenType::ElementDashStart] = {
|
||||||
TokenType::CooldownStart,
|
TokenType::CooldownStart,
|
||||||
TokenType::TextFragment,
|
TokenType::TextFragment,
|
||||||
TokenType::ElementOrderModifier
|
TokenType::ElementOrderModifier
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::ElementOrderModifier] = {
|
(*transitions)[TokenType::ElementOrderModifier] = {
|
||||||
TokenType::TextFragment
|
TokenType::TextFragment
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::ElementPlusStart] = {
|
(*transitions)[TokenType::ElementPlusStart] = {
|
||||||
TokenType::TextFragment
|
TokenType::TextFragment
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::Cooldown] = {
|
(*transitions)[TokenType::Cooldown] = {
|
||||||
TokenType::CooldownEnd,
|
TokenType::CooldownEnd,
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::CooldownStart] = {
|
(*transitions)[TokenType::CooldownStart] = {
|
||||||
TokenType::Cooldown
|
TokenType::Cooldown
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::CooldownEnd] = {
|
(*transitions)[TokenType::CooldownEnd] = {
|
||||||
TokenType::TextFragment
|
TokenType::TextFragment
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::StartOfFile] = {
|
(*transitions)[TokenType::StartOfFile] = {
|
||||||
TokenType::TextFragment,
|
TokenType::TextFragment,
|
||||||
TokenType::ElementDashStart,
|
TokenType::ElementDashStart,
|
||||||
TokenType::EndOfFile
|
TokenType::EndOfFile
|
||||||
};
|
};
|
||||||
(*automata)[TokenType::EndOfFile] = {};
|
(*transitions)[TokenType::EndOfFile] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pārbauda, vai vai tekstvienību sarakstu akceptē atbilst atbilst valodas
|
* Pārbauda, vai tekstvienību saraksts atbilst valodas
|
||||||
* automāts.
|
* definētām pieļaujamām pārejām.
|
||||||
* */
|
* */
|
||||||
Result<NoneType> ValidateGrammar(const std::vector<Token>& tokens) {
|
Result<NoneType> ValidateGrammar(const std::vector<Token>& tokens) {
|
||||||
if (!automata) {
|
if (!transitions) {
|
||||||
initParserAutomata();
|
initTransitions();
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < tokens.size() - 1; ++i) {
|
for (size_t i = 0; i < tokens.size() - 1; ++i) {
|
||||||
Token token = tokens[i];
|
Token token = tokens[i];
|
||||||
Token nextToken = tokens[i + 1];
|
Token nextToken = tokens[i + 1];
|
||||||
if (
|
if (
|
||||||
std::find(
|
std::find(
|
||||||
(*automata)[token.tokenType].begin(),
|
(*transitions)[token.tokenType].begin(),
|
||||||
(*automata)[token.tokenType].end(),
|
(*transitions)[token.tokenType].end(),
|
||||||
nextToken.tokenType
|
nextToken.tokenType
|
||||||
) == (*automata)[token.tokenType].end()) {
|
) == (*transitions)[token.tokenType].end()) {
|
||||||
|
|
||||||
auto capitalize = [](const std::string& str) {
|
auto capitalize = [](const std::string& str) {
|
||||||
if (str.empty()) return str;
|
if (str.empty()) return str;
|
||||||
@@ -105,13 +106,24 @@ Result<NoneType> ValidateGrammar(const std::vector<Token>& tokens) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Fix: Prevent duplicate group names and questions in ordered question (to
|
// @Fix: before EOF is acceptable
|
||||||
// simplify checking in practice).
|
// @Fix: remove section from questions
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apstrādā tekstvienības, iegūstot datumu un laiku un vienu vai vairākus
|
||||||
|
* dažāda veida jautājumus. Veiksmes gadījumā atgriež jautājumu norādes un
|
||||||
|
* datumu un laiku, ja tāds bija norādīts. Kļūdas gadījumā atgriež jautājumu
|
||||||
|
* norādes un kļūdu ar to atrašanos vietu failā. Atrašanās vieta ir nosakāma no
|
||||||
|
* atrašanās informācijas tekstvienību objektos.
|
||||||
|
* */
|
||||||
Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
||||||
auto questions = std::vector<Question*>();
|
auto questions = std::vector<Question*>();
|
||||||
time_t time = 0;
|
time_t time = 0;
|
||||||
|
|
||||||
auto makeResult = [&questions, &time](std::string error, Token token) -> Result<ParseInfo> {
|
// Palīgfunkcija - atgriež jautājumus un laiku ar norādītu tekstvienības
|
||||||
|
// kļūdas informāciju.
|
||||||
|
auto makeResult = [&questions, &time](std::string error, Token token)
|
||||||
|
-> Result<ParseInfo> {
|
||||||
return {
|
return {
|
||||||
{ questions, time },
|
{ questions, time },
|
||||||
error,
|
error,
|
||||||
@@ -120,10 +132,10 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sākotnējā validācija.
|
||||||
if (tokens.size() == 0) {
|
if (tokens.size() == 0) {
|
||||||
return makeResult("", Token());
|
return makeResult("", Token());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = ValidateGrammar(tokens);
|
auto result = ValidateGrammar(tokens);
|
||||||
if (result.error.length() > 0) {
|
if (result.error.length() > 0) {
|
||||||
return makeResult(
|
return makeResult(
|
||||||
@@ -139,10 +151,13 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
std::cout << "SECTION: PARSER:\n";
|
std::cout << "SECTION: PARSER:\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Palīgfunkcija - pārbauda, vai tekstvienības saraksta indeksā ir
|
||||||
|
// elements, kas nav faila beigas.
|
||||||
auto isInBounds = [tokens](size_t i) {
|
auto isInBounds = [tokens](size_t i) {
|
||||||
return i < tokens.size() && tokens[i].tokenType != TokenType::EndOfFile;
|
return i < tokens.size() && tokens[i].tokenType != TokenType::EndOfFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sākuma datumu un laiku mēģina nolasīt, ja tāds ir norādīts.
|
||||||
if (isInBounds(i) && tokens[i].tokenType == TokenType::TextFragment) {
|
if (isInBounds(i) && tokens[i].tokenType == TokenType::TextFragment) {
|
||||||
const std::string format = "%d.%m.%Y %H:%M";
|
const std::string format = "%d.%m.%Y %H:%M";
|
||||||
const std::string datetime = tokens[i].content.c_str();
|
const std::string datetime = tokens[i].content.c_str();
|
||||||
@@ -159,6 +174,7 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pamata parsēšana.
|
||||||
while (i < tokens.size()) {
|
while (i < tokens.size()) {
|
||||||
if (tokens[i].tokenType == TokenType::ElementDashStart) {
|
if (tokens[i].tokenType == TokenType::ElementDashStart) {
|
||||||
std::string questionText;
|
std::string questionText;
|
||||||
@@ -170,14 +186,18 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
bool hasGroupEncountered = false;
|
bool hasGroupEncountered = false;
|
||||||
Token questionStartToken;
|
Token questionStartToken;
|
||||||
|
|
||||||
// Start element parsing & add to the offset.
|
// Šajā momentā ir sagaidāms jautājuma sākums - tam nevar būt secības modifikators.
|
||||||
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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Piefiksē sākumu, lai varētu sniegt labāku kļūdas
|
||||||
|
// atrašanos vietu kļūdas gadījumā.
|
||||||
questionStartToken = tokens[i];
|
questionStartToken = tokens[i];
|
||||||
|
|
||||||
|
// Apstrādā pārtraukumu, ja tāds ir.
|
||||||
if (isInBounds(i + 1) && tokens[i + 1].tokenType == TokenType::CooldownStart) {
|
if (isInBounds(i + 1) && tokens[i + 1].tokenType == TokenType::CooldownStart) {
|
||||||
try {
|
try {
|
||||||
cooldown = std::stod(tokens[i + 2].content);
|
cooldown = std::stod(tokens[i + 2].content);
|
||||||
@@ -195,12 +215,13 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse elements of a question.
|
// Jautājumu elementu parsēšana.
|
||||||
while (isInBounds(i)) {
|
while (isInBounds(i)) {
|
||||||
|
|
||||||
// Check question end.
|
// Pārbauda, vai nav sastapts cits jautājuma sākums, un noslēdz, ja tas tā ir.
|
||||||
if (isInBounds(i + 3) && tokens[i].tokenType == TokenType::ElementDashStart) {
|
if (isInBounds(i + 3) && tokens[i].tokenType == TokenType::ElementDashStart) {
|
||||||
// Distance to the possible question end.
|
|
||||||
|
// Jautājumam var būt un var nebūt pārtraukums - nosaka vai tas būtu.
|
||||||
size_t offset;
|
size_t offset;
|
||||||
if (tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
if (tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
||||||
offset = tokens[i + 2].tokenType == TokenType::CooldownStart ? 6 : 3;
|
offset = tokens[i + 2].tokenType == TokenType::CooldownStart ? 6 : 3;
|
||||||
@@ -210,19 +231,21 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
if (isInBounds(i + offset) && tokens[i + offset].tokenType == TokenType::QuestionEnd) {
|
if (isInBounds(i + offset) && tokens[i + offset].tokenType == TokenType::QuestionEnd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == 5 && tokens[i + 5].tokenType != TokenType::QuestionEnd) {
|
if (offset == 5 && tokens[i + 5].tokenType != TokenType::QuestionEnd) {
|
||||||
// Cannot place the identifier on the ordinary element.
|
|
||||||
return makeResult(
|
return makeResult(
|
||||||
"Nepareiza idenfikatora izvietošana",
|
"Jautājuma elementam nevar būt pārtraukums",
|
||||||
tokens[i]
|
tokens[i]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine element type.
|
// Jautājuma elementa noteikšana un ar to saistītās kļūdas.
|
||||||
bool isDash;
|
bool isDash;
|
||||||
bool isGroup = false;
|
bool isGroup = false;
|
||||||
bool isOrder = false;
|
bool isOrder = false;
|
||||||
|
|
||||||
|
// Elementa sākums.
|
||||||
if (tokens[i].tokenType == TokenType::ElementDashStart) {
|
if (tokens[i].tokenType == TokenType::ElementDashStart) {
|
||||||
isDash = true;
|
isDash = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -241,6 +264,8 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Elementa secības modifikators.
|
||||||
if (isInBounds(i+1) && tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
if (isInBounds(i+1) && tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
||||||
isOrder = true;
|
isOrder = true;
|
||||||
isOrderQuestion = true;
|
isOrderQuestion = true;
|
||||||
@@ -269,6 +294,8 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Elementa grupas modifikators.
|
||||||
if (isInBounds(i + 2) && tokens[i + 2].tokenType == TokenType::MatchGroupEnd) {
|
if (isInBounds(i + 2) && tokens[i + 2].tokenType == TokenType::MatchGroupEnd) {
|
||||||
isGroup = true;
|
isGroup = true;
|
||||||
isGroupQuestion = true;
|
isGroupQuestion = true;
|
||||||
@@ -289,6 +316,7 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
hasGroupEncountered = true;
|
hasGroupEncountered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Izveido atbilstoša veida jautājuma elementu.
|
||||||
QuestionElement questionElement;
|
QuestionElement questionElement;
|
||||||
questionElement.isDash = isDash;
|
questionElement.isDash = isDash;
|
||||||
questionElement.isGroup = isGroup;
|
questionElement.isGroup = isGroup;
|
||||||
@@ -299,23 +327,28 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
}
|
}
|
||||||
questionElements.push_back(questionElement);
|
questionElements.push_back(questionElement);
|
||||||
|
|
||||||
size_t offset = 2;
|
// Nākamā elementa atrašanās vieta ir atkarīga no elementu
|
||||||
|
// veida, kas ir sastapts.
|
||||||
|
size_t offset = 2;
|
||||||
if (isOrder) {
|
if (isOrder) {
|
||||||
offset += 1;
|
offset += 1;
|
||||||
}
|
}
|
||||||
if (isGroup) {
|
if (isGroup) {
|
||||||
offset += 1;
|
offset += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += offset;
|
i += offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Izveido jautājuma objektu.
|
||||||
|
// Fix: else block - jautājums bez elementiem.
|
||||||
if (questionElements.size() > 0) {
|
if (questionElements.size() > 0) {
|
||||||
if (isGroupQuestion) {
|
if (isGroupQuestion) {
|
||||||
auto *question = new GroupQuestion();
|
auto *question = new GroupQuestion();
|
||||||
question->cooldown = cooldown;
|
question->cooldown = cooldown;
|
||||||
question->questionText = questionText;
|
question->questionText = questionText;
|
||||||
question->section = section;
|
question->section = section;
|
||||||
|
|
||||||
|
// Izveido grupas; i - elementu iterators; k - grupu iterators.
|
||||||
int32_t k = -1;
|
int32_t k = -1;
|
||||||
for (size_t i = 0; i < questionElements.size(); ++i) {
|
for (size_t i = 0; i < questionElements.size(); ++i) {
|
||||||
auto questionElement = questionElements[i];
|
auto questionElement = questionElements[i];
|
||||||
@@ -344,12 +377,14 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
question->questionText = cleanContent(questionText);
|
question->questionText = cleanContent(questionText);
|
||||||
question->section = section;
|
question->section = section;
|
||||||
|
|
||||||
|
// Izveido vairāku elementu jautājumu.
|
||||||
auto existingElements = std::set<std::string>();
|
auto existingElements = std::set<std::string>();
|
||||||
for (const auto& elem : questionElements) {
|
for (const auto& elem : questionElements) {
|
||||||
Choice choice;
|
Choice choice;
|
||||||
choice.answer = cleanContent(elem.content);
|
choice.answer = cleanContent(elem.content);
|
||||||
choice.isCorrect = !elem.isDash;
|
choice.isCorrect = !elem.isDash;
|
||||||
|
|
||||||
|
// Secības elementiem nedrīkst būt vienādi elementi.
|
||||||
if (isOrderQuestion) {
|
if (isOrderQuestion) {
|
||||||
if (existingElements.contains(choice.answer)) {
|
if (existingElements.contains(choice.answer)) {
|
||||||
return makeResult(
|
return makeResult(
|
||||||
@@ -366,6 +401,7 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
}
|
}
|
||||||
questions.push_back(question);
|
questions.push_back(question);
|
||||||
|
|
||||||
|
// Uzstāda vairāku elementu jautājuma specializēto veidu.
|
||||||
if (isPlusQuestion) {
|
if (isPlusQuestion) {
|
||||||
question->type = MultiElementType::MultiChoice;
|
question->type = MultiElementType::MultiChoice;
|
||||||
} else if (isOrderQuestion) {
|
} else if (isOrderQuestion) {
|
||||||
@@ -400,6 +436,9 @@ Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simbolu virkne, kas attēlo jautājumu atkļūdošanai.
|
||||||
|
*/
|
||||||
std::string MultiElementQuestion::toString() const {
|
std::string MultiElementQuestion::toString() const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
for (const auto& choice : choices) {
|
for (const auto& choice : choices) {
|
||||||
@@ -422,6 +461,9 @@ std::string MultiElementQuestion::toString() const {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simbolu virkne, kas attēlo jautājumu atkļūdošanai.
|
||||||
|
*/
|
||||||
std::string GroupQuestion::toString() const {
|
std::string GroupQuestion::toString() const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
for (auto group: groups) {
|
for (auto group: groups) {
|
||||||
|
|||||||
Reference in New Issue
Block a user