mirror of
https://github.com/jorenchik/mdemory.git
synced 2026-03-22 00:26:21 +00:00
docs, added help window, CMakeLists in root dir, other small changes
This commit is contained in:
@@ -9,5 +9,5 @@ set(
|
|||||||
"${CMAKE_CXX_FLAGS_DEBUG} -g3 -O0 -ggdb -fvar-tracking-assignments -fno-inline"
|
"${CMAKE_CXX_FLAGS_DEBUG} -g3 -O0 -ggdb -fvar-tracking-assignments -fno-inline"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(transpiler)
|
add_subdirectory(src/transpiler)
|
||||||
add_subdirectory(qtapp)
|
add_subdirectory(src/qtapp)
|
||||||
4
docs/img/conceptualER.svg
Normal file
4
docs/img/conceptualER.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 341 KiB |
4
docs/img/parsing_activity.svg
Normal file
4
docs/img/parsing_activity.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 784 KiB |
4
docs/img/parsing_answer_activity.svg
Normal file
4
docs/img/parsing_answer_activity.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 787 KiB |
BIN
docs/img/screens/help.png
Normal file
BIN
docs/img/screens/help.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
780
docs/main.typst
780
docs/main.typst
@@ -50,6 +50,11 @@
|
|||||||
īpašībām, piemēram, saturu, izcelsmi un struktūru;
|
īpašībām, piemēram, saturu, izcelsmi un struktūru;
|
||||||
|
|
||||||
*CSV* -- formāts, kas satur vērtības, kas ir atdalīti ar komatiem;
|
*CSV* -- formāts, kas satur vērtības, kas ir atdalīti ar komatiem;
|
||||||
|
|
||||||
|
*Parsēšana* -- TODO;
|
||||||
|
|
||||||
|
*Buferis* -- TODO;
|
||||||
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -67,17 +72,6 @@
|
|||||||
|
|
||||||
== Darbības sfēra
|
== Darbības sfēra
|
||||||
|
|
||||||
// 1) identificēt programmatūras produkta nosaukumu, piemēram, "Pārskatu ģenerators", utt.,
|
|
||||||
// 2) paskaidrot kas programmatūras produktam jādara un, ja nepieciešams, kas
|
|
||||||
// nav jādara;
|
|
||||||
// 3) aprakstīt programmatūras produkta pielietojumu.
|
|
||||||
// a) Aprakstīt, cik iespējams precīzi, iespējas, centienus un mērķi. Piemēram,
|
|
||||||
// teikums: iespēja efektīvi izstrādāt pārskatus nav tik labs, kā parametrizēti,
|
|
||||||
// lietotāja vadīti un definēti pārskati divu stundu laikā, ar iespēju ievadīt
|
|
||||||
// lietotāja parametrus dialoga režīmā.
|
|
||||||
// b) Nepieļaut pretrunas, lietojot terminus, kas līdzīgi terminiem augstāka
|
|
||||||
// līmeņa LVS 68:1996 lpp. 15. (22) specifikācijā (piemēram, Sistēmprasību
|
|
||||||
|
|
||||||
#indent-par([
|
#indent-par([
|
||||||
// Kas ir atmiņas kartes
|
// Kas ir atmiņas kartes
|
||||||
Atmiņas kartītes (angl. flashcards) ir izplatīts veids, kā skolēni,
|
Atmiņas kartītes (angl. flashcards) ir izplatīts veids, kā skolēni,
|
||||||
@@ -218,14 +212,34 @@ slēptā formātā, kas apgrūtina kartīšu pārvaldību un pārnešanu.
|
|||||||
|
|
||||||
== Risinājuma lietotāji
|
== Risinājuma lietotāji
|
||||||
|
|
||||||
|
// TODO Spelling
|
||||||
#indent-par([
|
#indent-par([
|
||||||
Risinājumam ir viena lietotāju grupa, kam ir pieejamas visas risinājuma
|
Risinājumam ir viena lietotāju grupa, kam ir pieejamas visas risinājuma
|
||||||
iespējas un funkcijas.
|
iespējas un funkcijas.
|
||||||
])
|
|
||||||
|
|
||||||
Risinājuma augsta līmeņa datu plūsmas ir attēlota 0. līmeņa datu plūsmas
|
Risinājuma augsta līmeņa datu plūsmas ir attēlota 0. līmeņa datu plūsmas
|
||||||
diagrammā (DPD; skat. @fig:dpd0 attēls). Lietotāju galvenā datu apmaiņa ir
|
diagrammā (DPD; skat. @fig:dpd0 attēls). Lietotāju galvenā datu apmaiņa ir
|
||||||
atmiņas kartīšu dati un dati par saskarni ar kartītēm.
|
atmiņas kartīšu dati un dati par saskarni ar kartītēm. DPD ir iekļautas trīs
|
||||||
|
datu glabātuves: failu glabātuve, pagaidu kartīšu glabātuve un konfigurācijas
|
||||||
|
glabātuve.
|
||||||
|
])
|
||||||
|
|
||||||
|
Failu glabātuve ir vieta, kur tiek glabātas kartītes vienkārša teskta formātā.
|
||||||
|
Tas ir direktorijs ar noteikta formāta failiem (skat. attēlu @fig:conceptual-er
|
||||||
|
un tabulas 2.1-2.6). Šo glabātuvi pārvalda lietotājs -- brīvi pievieno,
|
||||||
|
modificē un pārstrukturē direktorijā esošos failus un apakšdirektorijus.
|
||||||
|
|
||||||
|
Pagaidu kartīšu glabātuve glabā apskatāmās kartītes un visus izmainītos atmiņas
|
||||||
|
failiem atbilstošus kartīšu sarakstus. Glabātuve ir spēkā risinājuma programmas
|
||||||
|
darba laikā. Sākot darbu ar risinājumu, kartītes tiek ielādētas no failu
|
||||||
|
glabātuves pagaidu glabātuvē. Darbu beidzot vai pēc lietotāja izvēles, kartītes
|
||||||
|
tiek saglabātas failos, no kuriem katītes tika ielādētas. Izmaiņas pagaidu
|
||||||
|
glabātuves datos notiek ar risinājuma saskarni.
|
||||||
|
|
||||||
|
Konfigurācijas glabātuve ir fails(/-i), kuros tiek glabātas konfigurācijas
|
||||||
|
vērtības, ko uzstāda un saglabā lietotājs. Konfigurācijas glabātuvi pārvalda
|
||||||
|
lietotājs -- ir iespējams mainīt konfigurācijas faila saturu ar nosacījumu, ka
|
||||||
|
faila formāts paliek korekts un ievadītās vertības ir korektas un ir pieejamā
|
||||||
|
vērtību diapazonā.
|
||||||
|
|
||||||
#figure(
|
#figure(
|
||||||
caption: "0.līmeņa datu plūsmas diagramma",
|
caption: "0.līmeņa datu plūsmas diagramma",
|
||||||
@@ -260,6 +274,42 @@ atmiņas kartīšu dati un dati par saskarni ar kartītēm.
|
|||||||
#pagebreak(weak: true)
|
#pagebreak(weak: true)
|
||||||
= Programmatūras prasību specifikācija
|
= Programmatūras prasību specifikācija
|
||||||
|
|
||||||
|
// Šajā sadaļā tiks aprakstīts TODO??
|
||||||
|
|
||||||
|
== Konceptuālais entitāšu-relāciju modelis
|
||||||
|
|
||||||
|
// TODO spelling
|
||||||
|
Risinājuma glabātie dati iekļauj atmiņas kartīšu un konfigurācijas datus, kas
|
||||||
|
tiek glabāti vienkāršos failos. Risinājums neizmantos datubāzi datu glabāšanai.
|
||||||
|
Risinājumā entitātes ir attēlotas konceptuālā entitāšu-relāciju modelī (skat. attēlu
|
||||||
|
@fig:conceptual-er).
|
||||||
|
|
||||||
|
Atmiņas kartītes tiek organizētas noteikta paplašinājuma failos, kas satur
|
||||||
|
kartītes noteiktā formātā. Kartītes ir dažādu veidu jautājumi, kas ietver
|
||||||
|
sākuma -- jautājuma tekstu un vairākus saistītus jautājuma atbildes elementus.
|
||||||
|
Ir atbildes jautājumi, kas satur vairākus vienlīdzīgus elementus, un ir grupas
|
||||||
|
jautājumi, kas satur vairākas grupas ar vairākiem tai piederošiem elementiem.
|
||||||
|
Atbildes elementiem piemīt veids, katrs atšķiras ar to, kā elements sākas, ko
|
||||||
|
nosaka sākuma simboli. Grupas elementi sastāv no teksta un pieder kādai grupai,
|
||||||
|
kam ir nosaukums.
|
||||||
|
|
||||||
|
Modelī ir iekļauti metadati, kā pēdējās mācīšanās laiks, jautājuma pārtraukuma
|
||||||
|
laiks un faila nosaukums. Pēdējās mācīšanās laiks tiek izmantots intervālu
|
||||||
|
metodē, lai reģistrētu laiku un pielietot intervālu metodi turpmākās mācību
|
||||||
|
reizēs. Jautājuma pārtraukuma laiks nosaka, cik ilgam laikam jāpaiet, lai
|
||||||
|
jautājums atkal būtu iekļauts intervālu metodes mācīšanās.
|
||||||
|
Faila nosaukums tiek izmantots kā kartīšu saraksta nosaukums -- to var izmanot,
|
||||||
|
lai nosauktu failā esošās kartītes, piemēram, to tēmu vai nolūku.
|
||||||
|
|
||||||
|
|
||||||
|
Papildus datetime TODO
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
caption: "Konceptuālais entitāšu-relāciju modelis",
|
||||||
|
placement: auto,
|
||||||
|
image("img/conceptualER.svg"),
|
||||||
|
) <conceptual-er>
|
||||||
|
|
||||||
== Funkcionālās prasības
|
== Funkcionālās prasības
|
||||||
|
|
||||||
#let ref_df01 = [(skat. tabulu 2.1)]
|
#let ref_df01 = [(skat. tabulu 2.1)]
|
||||||
@@ -1165,8 +1215,6 @@ Pirmkodam jābūt izstrādātam ar sekojošiem nosacījumiem:
|
|||||||
|
|
||||||
+ Risinājuma pirmkods ir realizēts galvenokārt procedurālā stilā;
|
+ Risinājuma pirmkods ir realizēts galvenokārt procedurālā stilā;
|
||||||
+ Transpilatora funkcionalitātes testu pārklājums ir 90%;
|
+ Transpilatora funkcionalitātes testu pārklājums ir 90%;
|
||||||
// + Saskarnes funkcionalitāte ir notestēta svarīgākās vietās (svarīgākās vietas
|
|
||||||
// ir subjektīvs jēdziens, tāpēc to definēsim kā 20%).
|
|
||||||
|
|
||||||
==== Pārnesamība
|
==== Pārnesamība
|
||||||
|
|
||||||
@@ -1190,10 +1238,22 @@ Uz drošību risinājumam ir sekojošas prasības:
|
|||||||
== Daļējs funkciju projektējums
|
== Daļējs funkciju projektējums
|
||||||
|
|
||||||
#figure(
|
#figure(
|
||||||
caption: "Leksiskās analīzes aktivitāšu diagramma",
|
caption: "Leksiskās analīzes aktivitātes diagramma",
|
||||||
placement: none,
|
placement: none,
|
||||||
image("img/lexer_activity.svg"),
|
image("img/lexer_activity.svg"),
|
||||||
) <mdem-list-view>
|
) <lexing-activity>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
caption: "Parsēšanas aktivitātes diagramma",
|
||||||
|
placement: none,
|
||||||
|
image("img/parsing_activity.svg"),
|
||||||
|
) <parsing-acticity>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
caption: "Atbildes parsēšanas aktivitātes diagramma",
|
||||||
|
placement: none,
|
||||||
|
image("img/parsing_answer_activity.svg"),
|
||||||
|
) <parsing-answer-activity>
|
||||||
|
|
||||||
== Saskarnes projektējums
|
== Saskarnes projektējums
|
||||||
|
|
||||||
@@ -1233,6 +1293,29 @@ Uz drošību risinājumam ir sekojošas prasības:
|
|||||||
image("img/screens/config.png"),
|
image("img/screens/config.png"),
|
||||||
) <config-view>
|
) <config-view>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
caption: "Apmācības skats",
|
||||||
|
placement: none,
|
||||||
|
image("img/screens/help.png"),
|
||||||
|
) <help-view>
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
|
= Testēšanas dokumentācija
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
|
= Projekta organizācija
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
|
= Kvalitātes nodrošināšana
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
|
= Konfigurācijas pārvaldība
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
|
= Darbietiplības novērtējums
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
|
= Secinājumi
|
||||||
|
|
||||||
#pagebreak(weak: true)
|
#pagebreak(weak: true)
|
||||||
#heading(numbering: none, "Izmantotā literatūra un avoti")
|
#heading(numbering: none, "Izmantotā literatūra un avoti")
|
||||||
@@ -1284,3 +1367,664 @@ Uz drošību risinājumam ir sekojošas prasības:
|
|||||||
day: 21,
|
day: 21,
|
||||||
),
|
),
|
||||||
)<quizlet>
|
)<quizlet>
|
||||||
|
|
||||||
|
|
||||||
|
+ TODO UML 2.5. spec
|
||||||
|
|
||||||
|
#pagebreak(weak: true)
|
||||||
|
#heading(numbering: none, "Pielikumi")
|
||||||
|
|
||||||
|
// TODO caption
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::vector<Token> tokens;
|
||||||
|
std::vector<char> buffer;
|
||||||
|
int32_t row;
|
||||||
|
int32_t column;
|
||||||
|
int32_t previousRow;
|
||||||
|
int32_t previousColumn;
|
||||||
|
bool textStarted = false;
|
||||||
|
bool identifierStarted = false;
|
||||||
|
bool sof;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
void trimString(std::string &str, std::string trimChars) {
|
||||||
|
|
||||||
|
// Noņem kreisās puses simbolus.
|
||||||
|
int padSize = 0;
|
||||||
|
bool pad = false;
|
||||||
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
|
for (size_t k = 0; k < trimChars.size(); ++k) {
|
||||||
|
if (str[i] == trimChars[k]) {
|
||||||
|
padSize++;
|
||||||
|
pad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pad) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pad = false;
|
||||||
|
}
|
||||||
|
if (padSize > 0) {
|
||||||
|
str.erase(0, padSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Noņem labās puses simbolus.
|
||||||
|
padSize = 0;
|
||||||
|
pad = false;
|
||||||
|
for (size_t i = str.size(); i-- > 0;) {
|
||||||
|
for (size_t k = 0; k < trimChars.size(); ++k) {
|
||||||
|
if (str[i] == trimChars[k]) {
|
||||||
|
padSize++;
|
||||||
|
pad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pad) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pad = false;
|
||||||
|
}
|
||||||
|
if (padSize > 0) {
|
||||||
|
str.erase(str.end() - padSize, str.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Izveido tekstvienību, iegūstot to no bufera beigām.
|
||||||
|
* Ja buferī ir teksta vienība pirms tekstvienības, pievieno to pirms beigu
|
||||||
|
* tekstvienības.
|
||||||
|
*/
|
||||||
|
void tokenWithBuffer(
|
||||||
|
TokenType ttype,
|
||||||
|
size_t tokenLen,
|
||||||
|
TokenType textType
|
||||||
|
) {
|
||||||
|
std::string token(buffer.end() - tokenLen, buffer.end());
|
||||||
|
if (buffer.size() > tokenLen) {
|
||||||
|
std::string prevFragment(buffer.begin(), buffer.end() - tokenLen);
|
||||||
|
trimString(prevFragment, " \n\t");
|
||||||
|
if (prevFragment.length() > 0) {
|
||||||
|
tokens.push_back(Token{
|
||||||
|
textType,
|
||||||
|
prevFragment,
|
||||||
|
previousRow,
|
||||||
|
previousColumn
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.clear();
|
||||||
|
|
||||||
|
tokens.push_back(Token{
|
||||||
|
ttype,
|
||||||
|
token,
|
||||||
|
row,
|
||||||
|
column
|
||||||
|
});
|
||||||
|
|
||||||
|
previousRow = row;
|
||||||
|
previousColumn = column;
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pārveido simbolu virkni tekstvienību sarakstā.
|
||||||
|
* */
|
||||||
|
Result<std::vector<Token>> tokenizeMdem(const std::string& content) {
|
||||||
|
row = 1;
|
||||||
|
column = 1;
|
||||||
|
previousRow = 1;
|
||||||
|
previousColumn = 1;
|
||||||
|
textStarted = false;
|
||||||
|
tokens.clear();
|
||||||
|
buffer.clear();
|
||||||
|
|
||||||
|
// Beidz, ja satur tikai tukšumus vai neko.
|
||||||
|
if (content.find_first_not_of(" \n\t") == std::string::npos) {
|
||||||
|
return {tokens, ""};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < content.size(); ++i) {
|
||||||
|
char c = content[i];
|
||||||
|
|
||||||
|
// Apstrādā īpašos simbolus un tekstu.
|
||||||
|
if (c == '\n') {
|
||||||
|
row += 1;
|
||||||
|
column = 0;
|
||||||
|
}
|
||||||
|
if (c == '\\') {
|
||||||
|
i += 1;
|
||||||
|
if (i < content.size()) {
|
||||||
|
buffer.push_back(content[i]);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
buffer.push_back(c);
|
||||||
|
}
|
||||||
|
if (!textStarted) {
|
||||||
|
if (c == '\n') {
|
||||||
|
previousRow += 1;
|
||||||
|
previousColumn = 1;
|
||||||
|
} else if (c == ' ') {
|
||||||
|
previousColumn += 1;
|
||||||
|
} else if (c == '\t') {
|
||||||
|
previousColumn += 4;
|
||||||
|
} else {
|
||||||
|
textStarted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emitē tekstvienības.
|
||||||
|
switch (c) {
|
||||||
|
case '[': {
|
||||||
|
tokenWithBuffer(
|
||||||
|
TokenType::CooldownStart,
|
||||||
|
1,
|
||||||
|
TokenType::TextFragment
|
||||||
|
);
|
||||||
|
previousRow = row;
|
||||||
|
previousColumn = column;
|
||||||
|
textStarted = false;
|
||||||
|
identifierStarted = true;
|
||||||
|
} break;
|
||||||
|
case ']': {
|
||||||
|
if (!identifierStarted) {
|
||||||
|
return {
|
||||||
|
tokens,
|
||||||
|
"Cannot end identifier if it is not started",
|
||||||
|
tokens[i].row,
|
||||||
|
tokens[i].column
|
||||||
|
};
|
||||||
|
}
|
||||||
|
tokenWithBuffer(
|
||||||
|
TokenType::CooldownEnd,
|
||||||
|
1,
|
||||||
|
TokenType::Cooldown
|
||||||
|
);
|
||||||
|
previousRow = row;
|
||||||
|
previousColumn = column;
|
||||||
|
textStarted = false;
|
||||||
|
identifierStarted = false;
|
||||||
|
} break;
|
||||||
|
case '-': {
|
||||||
|
tokenWithBuffer(
|
||||||
|
TokenType::ElementDashStart,
|
||||||
|
1,
|
||||||
|
TokenType::TextFragment
|
||||||
|
);
|
||||||
|
previousRow = row;
|
||||||
|
previousColumn = column;
|
||||||
|
textStarted = false;
|
||||||
|
} break;
|
||||||
|
case '^': {
|
||||||
|
tokenWithBuffer(
|
||||||
|
TokenType::ElementOrderModifier,
|
||||||
|
1,
|
||||||
|
TokenType::TextFragment
|
||||||
|
);
|
||||||
|
previousRow = row;
|
||||||
|
previousColumn = column;
|
||||||
|
textStarted = false;
|
||||||
|
} break;
|
||||||
|
case ':': {
|
||||||
|
tokenWithBuffer(
|
||||||
|
TokenType::MatchGroupEnd,
|
||||||
|
1,
|
||||||
|
TokenType::TextFragment
|
||||||
|
);
|
||||||
|
previousRow = row;
|
||||||
|
previousColumn = column;
|
||||||
|
textStarted = false;
|
||||||
|
} break;
|
||||||
|
case '>': {
|
||||||
|
tokenWithBuffer(
|
||||||
|
TokenType::QuestionEnd,
|
||||||
|
1,
|
||||||
|
TokenType::TextFragment
|
||||||
|
);
|
||||||
|
previousRow = row;
|
||||||
|
previousColumn = column;
|
||||||
|
textStarted = false;
|
||||||
|
} break;
|
||||||
|
case '+': {
|
||||||
|
tokenWithBuffer(
|
||||||
|
TokenType::ElementPlusStart,
|
||||||
|
1,
|
||||||
|
TokenType::TextFragment
|
||||||
|
);
|
||||||
|
previousRow = row;
|
||||||
|
previousColumn = column;
|
||||||
|
textStarted = false;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
column += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pievieno beigu simbolu, lai atvieglotu parsēšanu.
|
||||||
|
tokenWithBuffer(
|
||||||
|
TokenType::EndOfFile,
|
||||||
|
0,
|
||||||
|
TokenType::TextFragment
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
std::cout << "SECTION: Lexer output:\n";
|
||||||
|
std::cout << std::format("Token count: {}", tokens.size()) << std::endl;
|
||||||
|
for (const Token& token : tokens) {
|
||||||
|
std::cout << token.toString();
|
||||||
|
}
|
||||||
|
std::cout << "SECTION END: Lexer output\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {tokens, ""};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Token::toString(const TokenType* ttype) {
|
||||||
|
switch (*ttype) {
|
||||||
|
case TokenType::TextFragment: return "text fragment";
|
||||||
|
case TokenType::QuestionEnd: return "question end symbol";
|
||||||
|
case TokenType::MatchGroupEnd: return "match group end";
|
||||||
|
case TokenType::ElementDashStart: return "dash element start";
|
||||||
|
case TokenType::ElementOrderModifier: return "order element modifier";
|
||||||
|
case TokenType::ElementPlusStart: return "plus element start";
|
||||||
|
case TokenType::Cooldown: return "cooldown";
|
||||||
|
case TokenType::CooldownStart: return "start of cooldown";
|
||||||
|
case TokenType::CooldownEnd: return "end of cooldown";
|
||||||
|
case TokenType::StartOfFile: return "start of the file";
|
||||||
|
case TokenType::EndOfFile: return "end of file";
|
||||||
|
default: return "unrecognized token";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
// TODO caption
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
typedef std::map<TokenType, std::vector<TokenType>> TokenAutomata;
|
||||||
|
|
||||||
|
TokenAutomata *automata = nullptr;
|
||||||
|
/*
|
||||||
|
* Tekstvienību secības pārejas, kas nosaka, kādā secībā tekstvienības var būt.
|
||||||
|
* */
|
||||||
|
void initParserAutomata() {
|
||||||
|
automata = new TokenAutomata;
|
||||||
|
(*automata)[TokenType::TextFragment] = {
|
||||||
|
TokenType::QuestionEnd,
|
||||||
|
TokenType::ElementDashStart,
|
||||||
|
TokenType::ElementPlusStart,
|
||||||
|
TokenType::MatchGroupEnd,
|
||||||
|
TokenType::EndOfFile,
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::MatchGroupEnd] = {
|
||||||
|
TokenType::ElementDashStart
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::QuestionEnd] = {
|
||||||
|
TokenType::ElementDashStart,
|
||||||
|
TokenType::ElementPlusStart
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::ElementDashStart] = {
|
||||||
|
TokenType::CooldownStart,
|
||||||
|
TokenType::TextFragment,
|
||||||
|
TokenType::ElementOrderModifier
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::ElementOrderModifier] = {
|
||||||
|
TokenType::TextFragment
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::ElementPlusStart] = {
|
||||||
|
TokenType::TextFragment
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::Cooldown] = {
|
||||||
|
TokenType::CooldownEnd,
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::CooldownStart] = {
|
||||||
|
TokenType::Cooldown
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::CooldownEnd] = {
|
||||||
|
TokenType::TextFragment
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::StartOfFile] = {
|
||||||
|
TokenType::TextFragment,
|
||||||
|
TokenType::ElementDashStart,
|
||||||
|
TokenType::EndOfFile
|
||||||
|
};
|
||||||
|
(*automata)[TokenType::EndOfFile] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pārbauda, vai vai tekstvienību sarakstu akceptē atbilst atbilst valodas
|
||||||
|
* automāts.
|
||||||
|
* */
|
||||||
|
Result<NoneType> ValidateGrammar(const std::vector<Token>& tokens) {
|
||||||
|
if (!automata) {
|
||||||
|
initParserAutomata();
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < tokens.size() - 1; ++i) {
|
||||||
|
Token token = tokens[i];
|
||||||
|
Token nextToken = tokens[i + 1];
|
||||||
|
if (
|
||||||
|
std::find(
|
||||||
|
(*automata)[token.tokenType].begin(),
|
||||||
|
(*automata)[token.tokenType].end(),
|
||||||
|
nextToken.tokenType
|
||||||
|
) == (*automata)[token.tokenType].end()) {
|
||||||
|
|
||||||
|
auto capitalize = [](const std::string& str) {
|
||||||
|
if (str.empty()) return str;
|
||||||
|
std::string result = str;
|
||||||
|
result[0] = std::towupper(result[0]);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
.error=std::format(
|
||||||
|
"Invalid token sequence: {} cannot precede {}",
|
||||||
|
std::string(capitalize(Token::toString(&token.tokenType))),
|
||||||
|
std::string(capitalize(Token::toString(&nextToken.tokenType)))
|
||||||
|
),
|
||||||
|
.row=token.row,
|
||||||
|
.column=token.column
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Fix: Prevent duplicate group names and questions in ordered question (to
|
||||||
|
// simplify checking in practice).
|
||||||
|
Result<ParseInfo> parseQuestions(const std::vector<Token>& tokens) {
|
||||||
|
auto questions = std::vector<Question*>();
|
||||||
|
time_t time = 0;
|
||||||
|
|
||||||
|
auto makeResult = [&questions, &time](std::string error, Token token) -> Result<ParseInfo> {
|
||||||
|
return {
|
||||||
|
{ questions, time },
|
||||||
|
error,
|
||||||
|
token.row,
|
||||||
|
token.column
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (tokens.size() == 0) {
|
||||||
|
return makeResult("", Token());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = ValidateGrammar(tokens);
|
||||||
|
if (result.error.length() > 0) {
|
||||||
|
return makeResult(
|
||||||
|
result.error,
|
||||||
|
Token{.row=result.row, .column=result.column}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string section;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
std::cout << "SECTION: Parser output:\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto isInBounds = [tokens](size_t i) {
|
||||||
|
return i < tokens.size() && tokens[i].tokenType != TokenType::EndOfFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isInBounds(i) && tokens[i].tokenType == TokenType::TextFragment) {
|
||||||
|
try {
|
||||||
|
auto parseToUTCTime = [](const std::string datetime, std::string format) {
|
||||||
|
std::tm tm = {};
|
||||||
|
std::istringstream ss(datetime);
|
||||||
|
ss >> std::get_time(&tm, format.c_str());
|
||||||
|
if (ss.fail()) {
|
||||||
|
throw std::runtime_error("Failed to parse datetime string");
|
||||||
|
}
|
||||||
|
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(
|
||||||
|
std::format("cannot parse the time - {}", e.what()),
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < tokens.size()) {
|
||||||
|
if (tokens[i].tokenType == TokenType::ElementDashStart) {
|
||||||
|
std::string questionText;
|
||||||
|
std::vector<QuestionElement> questionElements;
|
||||||
|
double cooldown;
|
||||||
|
bool isOrderQuestion = false;
|
||||||
|
bool isGroupQuestion = false;
|
||||||
|
bool isPlusQuestion = false;
|
||||||
|
|
||||||
|
// Start element parsing & add to the offset.
|
||||||
|
if (isInBounds(i + 1) && tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
||||||
|
return makeResult(
|
||||||
|
"cannot have order modifier ('^') in the question definition",
|
||||||
|
tokens[i + 1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isInBounds(i + 1) && tokens[i + 1].tokenType == TokenType::CooldownStart) {
|
||||||
|
try {
|
||||||
|
cooldown = std::stod(tokens[i + 2].content);
|
||||||
|
} catch (std::exception e) {
|
||||||
|
return makeResult(
|
||||||
|
"error parsing cooldown",
|
||||||
|
tokens[i + 1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
questionText = tokens[i + 4].content;
|
||||||
|
i += 6;
|
||||||
|
} else {
|
||||||
|
cooldown = 0;
|
||||||
|
questionText = tokens[i + 1].content;
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse elements of a question.
|
||||||
|
while (isInBounds(i)) {
|
||||||
|
|
||||||
|
// Check question end.
|
||||||
|
if (isInBounds(i + 3) && tokens[i].tokenType == TokenType::ElementDashStart) {
|
||||||
|
// Distance to the possible question end.
|
||||||
|
size_t offset;
|
||||||
|
if (tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
||||||
|
offset = tokens[i + 2].tokenType == TokenType::CooldownStart ? 6 : 3;
|
||||||
|
} else {
|
||||||
|
offset = tokens[i + 1].tokenType == TokenType::CooldownStart ? 5 : 2;
|
||||||
|
}
|
||||||
|
if (isInBounds(i + offset) && tokens[i + offset].tokenType == TokenType::QuestionEnd) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (offset == 5 && tokens[i + 5].tokenType != TokenType::QuestionEnd) {
|
||||||
|
// Cannot place the identifier on the ordinary element.
|
||||||
|
return makeResult(
|
||||||
|
"Invalid identifier placement",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine element type.
|
||||||
|
bool isDash;
|
||||||
|
bool isGroup = false;
|
||||||
|
bool isOrder = false;
|
||||||
|
if (tokens[i].tokenType == TokenType::ElementDashStart) {
|
||||||
|
isDash = true;
|
||||||
|
} else {
|
||||||
|
isDash = false;
|
||||||
|
isPlusQuestion = true;
|
||||||
|
}
|
||||||
|
if (isInBounds(i+1) && tokens[i + 1].tokenType == TokenType::ElementOrderModifier) {
|
||||||
|
isOrder = true;
|
||||||
|
isOrderQuestion = true;
|
||||||
|
if (!isDash) {
|
||||||
|
return makeResult(
|
||||||
|
"order questions can only be used with dashes ('-')",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isGroupQuestion) {
|
||||||
|
return makeResult(
|
||||||
|
"question with groups cannot be ordered ('-^' and ':')",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isInBounds(i + 3) && tokens[i + 3].tokenType == TokenType::MatchGroupEnd) {
|
||||||
|
return makeResult(
|
||||||
|
"cannot have groups in order question('-^' and ':')",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isInBounds(i + 2) && tokens[i + 2].tokenType == TokenType::MatchGroupEnd) {
|
||||||
|
isGroup = true;
|
||||||
|
isGroupQuestion = true;
|
||||||
|
if (!isDash) {
|
||||||
|
return makeResult(
|
||||||
|
"group questions can only be used with dashes ('-')",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestionElement questionElement;
|
||||||
|
questionElement.isDash = isDash;
|
||||||
|
questionElement.isGroup = isGroup;
|
||||||
|
if (isOrder) {
|
||||||
|
questionElement.content = tokens[i + 2].content;
|
||||||
|
} else {
|
||||||
|
questionElement.content = tokens[i + 1].content;
|
||||||
|
}
|
||||||
|
questionElements.push_back(questionElement);
|
||||||
|
|
||||||
|
size_t offset = 2;
|
||||||
|
if (isOrder) {
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
if (isGroup) {
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (questionElements.size() > 0) {
|
||||||
|
if (isGroupQuestion) {
|
||||||
|
auto *question = new GroupQuestion();
|
||||||
|
question->cooldown = cooldown;
|
||||||
|
question->questionText = questionText;
|
||||||
|
question->section = section;
|
||||||
|
int32_t k = -1;
|
||||||
|
for (size_t i = 0; i < questionElements.size(); ++i) {
|
||||||
|
auto questionElement = questionElements[i];
|
||||||
|
if (questionElement.isGroup) {
|
||||||
|
++k;
|
||||||
|
auto group = Group();
|
||||||
|
group.name = cleanContent(questionElement.content);
|
||||||
|
question->groups.push_back(group);
|
||||||
|
} else {
|
||||||
|
if (k >= 0) {
|
||||||
|
question->groups[k].elements.push_back(
|
||||||
|
cleanContent(
|
||||||
|
questionElement.content
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
questions.push_back(question);
|
||||||
|
if (debug) {
|
||||||
|
std::cout << question->toString() << "\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto *question = new MultiElementQuestion();
|
||||||
|
question->cooldown = cooldown;
|
||||||
|
question->questionText = cleanContent(questionText);
|
||||||
|
question->section = section;
|
||||||
|
for (const auto& elem : questionElements) {
|
||||||
|
Choice choice;
|
||||||
|
choice.answer = cleanContent(elem.content);
|
||||||
|
choice.isCorrect = !elem.isDash;
|
||||||
|
question->choices.push_back(choice);
|
||||||
|
}
|
||||||
|
questions.push_back(question);
|
||||||
|
if (isPlusQuestion) {
|
||||||
|
question->type = MultiElementType::MultiChoice;
|
||||||
|
} else if (isOrderQuestion) {
|
||||||
|
question->type = MultiElementType::Order;
|
||||||
|
} else {
|
||||||
|
question->type = MultiElementType::Regular;
|
||||||
|
}
|
||||||
|
if (debug) {
|
||||||
|
std::cout << question->toString() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (tokens[i].tokenType == TokenType::EndOfFile) {
|
||||||
|
if (debug) {
|
||||||
|
std::cout << "File terminated: EndOfFile\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
return makeResult(
|
||||||
|
"Unexpected token encountered",
|
||||||
|
tokens[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
std::cout << "SECTION END: Parser output:\n";
|
||||||
|
}
|
||||||
|
return makeResult(
|
||||||
|
"",
|
||||||
|
Token()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MultiElementQuestion::toString() const {
|
||||||
|
std::stringstream ss;
|
||||||
|
for (const auto& choice : choices) {
|
||||||
|
char opener;
|
||||||
|
if (type == MultiElementType::Order) {
|
||||||
|
opener = '^';
|
||||||
|
} else if (choice.isCorrect) {
|
||||||
|
opener = '+';
|
||||||
|
} else {
|
||||||
|
opener = '-';
|
||||||
|
}
|
||||||
|
ss << opener << " " << choice.answer << "; ";
|
||||||
|
}
|
||||||
|
return std::format(
|
||||||
|
"<Multiple element>\nsection:{}\nid:{}\n{}\n{}",
|
||||||
|
section,
|
||||||
|
cooldown,
|
||||||
|
questionText,
|
||||||
|
ss.str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GroupQuestion::toString() const {
|
||||||
|
std::stringstream ss;
|
||||||
|
for (auto group: groups) {
|
||||||
|
ss << group.name << ": ";
|
||||||
|
for (auto el: group.elements) {
|
||||||
|
ss << el << ", ";
|
||||||
|
}
|
||||||
|
ss << "; ";
|
||||||
|
}
|
||||||
|
return std::format(
|
||||||
|
"<GroupQuestion>\nsection:{}\nid:{}\n{}\n{}",
|
||||||
|
section,
|
||||||
|
cooldown,
|
||||||
|
questionText,
|
||||||
|
ss.str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
20.10.2024 13\:53
|
28.10.2024 17\:07
|
||||||
|
|
||||||
- [20.00] Arrange these events in the order they occurred >
|
- Arrange these events in the order they occurred >
|
||||||
-^ The Fall of the Roman
|
-^ The Fall of the Roman
|
||||||
-^ The Renaissance
|
-^ The Renaissance
|
||||||
-^ The Industrial Revolution
|
-^ The Industrial Revolution
|
||||||
|
-^ Step
|
||||||
|
|
||||||
- [19.70] Match Planets to Their Characteristics >
|
- [20.00] Match Planets to Their Characteristics >
|
||||||
- Earth:
|
- Earth:
|
||||||
- Contains Life
|
- Contains Life
|
||||||
- Mars:
|
- Mars:
|
||||||
@@ -29,14 +30,13 @@
|
|||||||
+ Poland
|
+ Poland
|
||||||
- China
|
- China
|
||||||
|
|
||||||
- [44.91] What is the capital of Latvia? >
|
- [45.13] What is the capital of Latvia? >
|
||||||
- Rīga
|
- Rīga
|
||||||
|
|
||||||
- [44.91] What is the capital of Estonia? >
|
- [19.93] What is the capital of Estonia? >
|
||||||
- Tallin
|
- Tallin
|
||||||
|
|
||||||
- [1.20] Place the following steps of the scientific method in the
|
- Place the following steps of the scientific method in the correct order >
|
||||||
correct order >
|
|
||||||
-^ Ask a Question
|
-^ Ask a Question
|
||||||
-^ Form a Hypothesis
|
-^ Form a Hypothesis
|
||||||
-^ Conduct an Experiment
|
-^ Conduct an Experiment
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
43
memorybase/macibas/dazadi.mdem
Normal file
43
memorybase/macibas/dazadi.mdem
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
28.10.2024 08\:38
|
||||||
|
|
||||||
|
- Kā sauc Lietuvas galvaspilsētu >
|
||||||
|
- Viļņa
|
||||||
|
|
||||||
|
- Kā sauc Latvijas galvaspilsētu >
|
||||||
|
- Rīga
|
||||||
|
|
||||||
|
- Sakārtojiet zinātniskās metodes soļus pareizā secībā >
|
||||||
|
-^ Uzdod jautājumu
|
||||||
|
-^ Izvirza hipotēzi
|
||||||
|
-^ Veic eksperimentu
|
||||||
|
-^ Analizē datus
|
||||||
|
|
||||||
|
- [2.03] Sakārtojiet cilvēka gremošanas sistēmas posmus pareizā
|
||||||
|
secībā >
|
||||||
|
-^ Mutē ēdiens tiek sasmalcināts
|
||||||
|
-^ Norij un nonāk kuņģī
|
||||||
|
-^ Barība tiek sašķelta kuņģī
|
||||||
|
-^ Uzturvielas uzsūcas zarnās
|
||||||
|
-^ Atlikumi izvadīti caur taisno zarnu
|
||||||
|
|
||||||
|
- [10.50] Sakārtojiet fotosintēzes procesa posmus pareizā secībā
|
||||||
|
>
|
||||||
|
-^ Saules gaisma tiek uztverta ar hlorofilu
|
||||||
|
-^ Ūdens molekulas tiek sadalītas
|
||||||
|
-^ Tiek ražots skābeklis un glikoze
|
||||||
|
-^ Enerģija tiek uzkrāta glikozes veidā
|
||||||
|
|
||||||
|
- Sakārtojiet projekta izstrādes posmus pareizā secībā >
|
||||||
|
-^ Identificē prasības
|
||||||
|
-^ Veic plānošanu
|
||||||
|
-^ Īsteno izstrādi
|
||||||
|
-^ Testē un novērš kļūdas
|
||||||
|
-^ Nodod projektu lietošanai
|
||||||
|
|
||||||
|
- Sakārtojiet elektriskās ķēdes projektēšanas soļus pareizā
|
||||||
|
secībā >
|
||||||
|
-^ Izvēlas komponentus
|
||||||
|
-^ Izveido shēmas plānojumu
|
||||||
|
-^ Savieno komponentus shēmā
|
||||||
|
-^ Pārbauda un testē ķēdi
|
||||||
|
|
||||||
53
memorybase/macibas/groupesanas.mdem
Normal file
53
memorybase/macibas/groupesanas.mdem
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
26.10.2024 02\:33
|
||||||
|
|
||||||
|
- [12.50] Savienojiet dzīvniekus ar to īpašībām >
|
||||||
|
- Lauva:
|
||||||
|
- "Džungļu karalis"
|
||||||
|
- Zilonis:
|
||||||
|
- Lielākie sauszemes zīdītāji
|
||||||
|
- Garas ilknas
|
||||||
|
- Žirafe:
|
||||||
|
- Garākais sauszemes dzīvnieks
|
||||||
|
- Delfīns:
|
||||||
|
- Dzīvo ūdenī
|
||||||
|
- Gudri un sabiedriski
|
||||||
|
- Pingvīns:
|
||||||
|
- Dzīvo Antarktīdā
|
||||||
|
- Nespēj lidot
|
||||||
|
|
||||||
|
- Savienojiet valstis ar to ievērojamākajām ēkām >
|
||||||
|
- Francija:
|
||||||
|
- Eifeļa tornis
|
||||||
|
- Ēģipte:
|
||||||
|
- Gīzas piramīdas
|
||||||
|
- Ķīna:
|
||||||
|
- Lielais Ķīnas mūris
|
||||||
|
- Indija:
|
||||||
|
- Tadžmahals
|
||||||
|
- Itālija:
|
||||||
|
- Kolizejs
|
||||||
|
|
||||||
|
- Savienojiet zinātniekus ar to sasniegumiem >
|
||||||
|
- Alberts Einšteins:
|
||||||
|
- Relativitātes teorija
|
||||||
|
- Īzaks Ņūtons:
|
||||||
|
- Kustības likumi
|
||||||
|
- Nikola Tesla:
|
||||||
|
- Maiņstrāvas sistēma
|
||||||
|
- Luijs Pastērs:
|
||||||
|
- Vakcinācija un pasterizācija
|
||||||
|
- Galilejs Galilejs:
|
||||||
|
- Teleskopa uzlabojumi
|
||||||
|
|
||||||
|
- Savienojiet literatūras žanrus ar to īpašībām >
|
||||||
|
- Romāns:
|
||||||
|
- Garš stāstījums, bieži vien sarežģīta sižeta
|
||||||
|
- Dzeja:
|
||||||
|
- Rindas ar ritmisku struktūru
|
||||||
|
- Luga:
|
||||||
|
- Darbs, kas paredzēts izrādīšanai teātrī
|
||||||
|
- Eseja:
|
||||||
|
- Īss darbs ar autora personīgiem uzskatiem
|
||||||
|
- Novela:
|
||||||
|
- Īsāks par romānu, koncentrēts sižets
|
||||||
|
|
||||||
41
memorybase/macibas/valstis.mdem
Normal file
41
memorybase/macibas/valstis.mdem
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
26.10.2024 14\:22
|
||||||
|
|
||||||
|
- [20.00] Kā sauc Igaunijas galvaspilsētu? >
|
||||||
|
- Tallina
|
||||||
|
|
||||||
|
- Nosauciet Skandināvijas valstis >
|
||||||
|
- Zviedrija
|
||||||
|
- Norvēģija
|
||||||
|
- Dānija
|
||||||
|
|
||||||
|
- [12.49] Kā sauc Vācijas galvaspilsētu? >
|
||||||
|
- Berlīne
|
||||||
|
|
||||||
|
- Nosauciet Beneluksa valstis >
|
||||||
|
- Beļģija
|
||||||
|
- Nīderlande
|
||||||
|
- Luksemburga
|
||||||
|
|
||||||
|
- Kā sauc Francijas galvaspilsētu? >
|
||||||
|
- Parīze
|
||||||
|
|
||||||
|
- Nosauciet Apvienotās Karalistes valstis >
|
||||||
|
- Anglija
|
||||||
|
- Skotija
|
||||||
|
- Velsa
|
||||||
|
- Ziemeļīrija
|
||||||
|
|
||||||
|
- Ka sauc Lietuvas galvas pilsētu? >
|
||||||
|
- Viļņa
|
||||||
|
|
||||||
|
- Nosauciet Baltijas valstis >
|
||||||
|
- Latvija
|
||||||
|
- Igaunija
|
||||||
|
- Lietuva
|
||||||
|
|
||||||
|
- Kuras no valstīm ir Baltijas valstis >
|
||||||
|
+ Latvija
|
||||||
|
- Rumānija
|
||||||
|
+ Lietuva
|
||||||
|
- Spānija
|
||||||
|
|
||||||
58
resources/help.html
Normal file
58
resources/help.html
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Apmācība</h1>
|
||||||
|
|
||||||
|
<h2>Lietotnes nolūks</h2>
|
||||||
|
<p>
|
||||||
|
Lietotne "mdemory" ir dod iespēju mācīcies, izmantojot dažāda veida
|
||||||
|
atmiņas kartītes, ko var definēt un glabāt vienkāršā tekstā.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Atmiņas bāze</h2>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Kartīšu saraksts</h2>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Mācīšanās</h2>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Konfigurācija</h2>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Atmiņas kartīšu definēšana</h2>
|
||||||
|
<h3>Jautājumi</h3>
|
||||||
|
<h4>Atbildes jautājums</h4>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
<h4>Izvēles jautājums</h4>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
<h4>Secības jautājums</h4>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
<h4>Grupēšanas jautājums</h4>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
<h3>Datums un laiks</h3>
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
5
resources/resources.qrc
Normal file
5
resources/resources.qrc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/html">
|
||||||
|
<file>help.html</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
@@ -16,13 +16,16 @@ find_package(Qt5 COMPONENTS Widgets REQUIRED)
|
|||||||
# find_package(QScintilla REQUIRED)
|
# find_package(QScintilla REQUIRED)
|
||||||
include_directories(/usr/include/qt/Qsci)
|
include_directories(/usr/include/qt/Qsci)
|
||||||
|
|
||||||
|
qt5_add_resources(RESOURCES ${CMAKE_SOURCE_DIR}/resources/resources.qrc)
|
||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
MdemoryApp
|
MdemoryApp
|
||||||
main.cpp
|
main.cpp
|
||||||
mdemList.cpp
|
mdemList.cpp
|
||||||
trainWindow.cpp
|
trainWindow.cpp
|
||||||
settings.cpp
|
settings.cpp
|
||||||
|
${RESOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(MdemoryApp Qt5::Widgets /usr/lib/libqscintilla2_qt5.so api)
|
target_link_libraries(MdemoryApp Qt5::Widgets /usr/lib/libqscintilla2_qt5.so api)
|
||||||
target_include_directories(MdemoryApp PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
target_include_directories(MdemoryApp PRIVATE ${CMAKE_SOURCE_DIR}/src/include)
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QTextBrowser>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
@@ -780,17 +781,35 @@ QMainWindow *initMdemListWindow() {
|
|||||||
pagination = new Pagination;
|
pagination = new Pagination;
|
||||||
auto *toolbar = new Toolbar();
|
auto *toolbar = new Toolbar();
|
||||||
|
|
||||||
// Setup related windows
|
// Setup the related windows.
|
||||||
auto *settingsWindow = initSettings();
|
auto *settingsWindow = initSettings();
|
||||||
trainWindow = initTrainWindow();
|
trainWindow = initTrainWindow();
|
||||||
|
|
||||||
|
QMainWindow *guideWindow = new QMainWindow;
|
||||||
|
{ // Guide window.
|
||||||
|
auto guideWidget = new QWidget;
|
||||||
|
auto *layout = new QVBoxLayout;
|
||||||
|
auto *textBrowser = new QTextBrowser;
|
||||||
|
textBrowser->setSource(QUrl("qrc:/html/help.html"));
|
||||||
|
textBrowser->zoomIn(2);
|
||||||
|
layout->addWidget(textBrowser);
|
||||||
|
guideWidget->setLayout(layout);
|
||||||
|
guideWindow->setCentralWidget(guideWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction *actionOpen;
|
||||||
|
QAction *openSettings;
|
||||||
|
QAction *actionHelp;
|
||||||
{ // Menu bar.
|
{ // Menu bar.
|
||||||
QMenuBar *menuBar = new QMenuBar;
|
QMenuBar *menuBar = new QMenuBar;
|
||||||
QFileDialog *fileDialog = new QFileDialog;
|
QFileDialog *fileDialog = new QFileDialog;
|
||||||
|
|
||||||
QMenu *menu = new QMenu("File");
|
QMenu *menu = new QMenu("File");
|
||||||
QAction *actionOpen = menu->addAction("Open memorybase");
|
actionOpen = menu->addAction("Open memorybase");
|
||||||
QObject::connect(actionOpen, &QAction::triggered, [fileDialog]() {
|
QObject::connect(
|
||||||
|
actionOpen,
|
||||||
|
&QAction::triggered,
|
||||||
|
[fileDialog]() {
|
||||||
fileDialog->setDirectory(QDir::homePath());
|
fileDialog->setDirectory(QDir::homePath());
|
||||||
fileDialog->setFileMode(QFileDialog::FileMode::Directory);
|
fileDialog->setFileMode(QFileDialog::FileMode::Directory);
|
||||||
fileDialog->open();
|
fileDialog->open();
|
||||||
@@ -800,9 +819,10 @@ QMainWindow *initMdemListWindow() {
|
|||||||
&QFileDialog::fileSelected,
|
&QFileDialog::fileSelected,
|
||||||
pickDirectory
|
pickDirectory
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
QAction *openSettings = menu->addAction("Settings");
|
openSettings = menu->addAction("Settings");
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
openSettings,
|
openSettings,
|
||||||
&QAction::triggered,
|
&QAction::triggered,
|
||||||
@@ -810,6 +830,15 @@ QMainWindow *initMdemListWindow() {
|
|||||||
settingsWindow->show();
|
settingsWindow->show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
actionHelp = menu->addAction("Help");
|
||||||
|
QObject::connect(
|
||||||
|
actionHelp,
|
||||||
|
&QAction::triggered,
|
||||||
|
[guideWindow]() {
|
||||||
|
guideWindow->show();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
menuBar->addMenu(menu);
|
menuBar->addMenu(menu);
|
||||||
window->setMenuBar(menuBar);
|
window->setMenuBar(menuBar);
|
||||||
}
|
}
|
||||||
@@ -1113,8 +1142,14 @@ QMainWindow *initMdemListWindow() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
addShortcut("Ctrl+,", [settingsWindow]() {
|
addShortcut("Ctrl+O", [actionOpen]() {
|
||||||
settingsWindow->show();
|
actionOpen->trigger();
|
||||||
|
});
|
||||||
|
addShortcut("Ctrl+H", [actionHelp]() {
|
||||||
|
actionHelp->trigger();
|
||||||
|
});
|
||||||
|
addShortcut("Ctrl+,", [openSettings]() {
|
||||||
|
openSettings->trigger();
|
||||||
});
|
});
|
||||||
addShortcut("Ctrl+S", [toolbar]() {
|
addShortcut("Ctrl+S", [toolbar]() {
|
||||||
toolbar->btnSave.click();
|
toolbar->btnSave.click();
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ target_link_libraries(transpiler api)
|
|||||||
|
|
||||||
target_compile_options(transpiler PRIVATE -Wall -Wextra -Wpedantic)
|
target_compile_options(transpiler PRIVATE -Wall -Wextra -Wpedantic)
|
||||||
|
|
||||||
target_include_directories(transpiler PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
target_include_directories(transpiler PRIVATE ${CMAKE_SOURCE_DIR}/src/include)
|
||||||
target_include_directories(api PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
target_include_directories(api PUBLIC ${CMAKE_SOURCE_DIR}/src/include)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ typedef std::map<TokenType, std::vector<TokenType>> TokenAutomata;
|
|||||||
|
|
||||||
TokenAutomata *automata = nullptr;
|
TokenAutomata *automata = nullptr;
|
||||||
/*
|
/*
|
||||||
* Galīgs automāts, kas nosaka, kādā secībā ir var būt tekstvienības.
|
* Tekstvienību secības pārejas, kas nosaka, kādā secībā tekstvienības var būt.
|
||||||
* */
|
* */
|
||||||
void initParserAutomata() {
|
void initParserAutomata() {
|
||||||
automata = new TokenAutomata;
|
automata = new TokenAutomata;
|
||||||
|
|||||||
45
tasks.md
45
tasks.md
@@ -1,48 +1,3 @@
|
|||||||
- [x] Augment the lexer for Order and match question;
|
|
||||||
- [x] Parse the questions accordingly;
|
|
||||||
- [x] Escape character;
|
|
||||||
- [ ] Implement order question checking;
|
|
||||||
- [ ] Implement multichoice question checking;
|
|
||||||
- [ ] Implement group question checking;
|
|
||||||
- [ ] Ensure no duplicates in questions where it matters.
|
- [ ] Ensure no duplicates in questions where it matters.
|
||||||
We will need this for checking the answers;
|
We will need this for checking the answers;
|
||||||
- [ ]
|
|
||||||
- [ ]
|
|
||||||
- [ ]
|
|
||||||
- [ ]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 1-N Answer question
|
|
||||||
|
|
||||||
- kfoewf >
|
|
||||||
- fiewfiwe
|
|
||||||
|
|
||||||
- kfoewf >
|
|
||||||
- fiewfiwe
|
|
||||||
- fewpfowe
|
|
||||||
- fweofopew
|
|
||||||
- ofpewpofkew
|
|
||||||
|
|
||||||
## Order question
|
|
||||||
|
|
||||||
- ewjpfwe >
|
|
||||||
^- ewijfew
|
|
||||||
^- ewijfew
|
|
||||||
^- ewijfew
|
|
||||||
^- ewijfew
|
|
||||||
^- ewijfew
|
|
||||||
|
|
||||||
## Match question
|
|
||||||
|
|
||||||
- iowjefew >
|
|
||||||
- fiwfo:
|
|
||||||
- fewfew
|
|
||||||
- ifoewf
|
|
||||||
- ejpfe:
|
|
||||||
- _
|
|
||||||
- fewfw:
|
|
||||||
- fewjpfe
|
|
||||||
- fioewf
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user