SyntaxTutor
Educational app designed to help compiler students understand LL(1) and SLR(1) parsing algorithms.
Loading...
Searching...
No Matches
lltutorwindow.h
Go to the documentation of this file.
1/*
2 * SyntaxTutor - Interactive Tutorial About Syntax Analyzers
3 * Copyright (C) 2025 Jose R. (jose-rzm)
4 *
5 * This program is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#ifndef LLTUTORWINDOW_H
20#define LLTUTORWINDOW_H
21
22#include <QAbstractItemView>
23#include <QDialog>
24#include <QFileDialog>
25#include <QGraphicsColorizeEffect>
26#include <QGraphicsScene>
27#include <QGraphicsTextItem>
28#include <QGraphicsView>
29#include <QListWidgetItem>
30#include <QMainWindow>
31#include <QMessageBox>
32#include <QPainter>
33#include <QPropertyAnimation>
34#include <QPushButton>
35#include <QScrollBar>
36#include <QShortcut>
37#include <QTableWidget>
38#include <QTextDocument>
39#include <QTextEdit>
40#include <QTime>
41#include <QTimer>
42#include <QTreeWidgetItem>
43#include <QVBoxLayout>
44#include <QtPrintSupport/QPrinter>
45
46#include "backend/grammar.hpp"
48#include "lltabledialog.h"
49
50class TutorialManager;
51
52namespace Ui {
53class LLTutorWindow;
54}
55
56// ====== LL(1) Tutor States ===================================
57enum class State { A, A1, A2, A_prime, B, B1, B2, B_prime, C, C_prime, fin };
58
59// ====== LL(1) Tutor Main Class ===============================
79class LLTutorWindow : public QMainWindow {
80 Q_OBJECT
81
82 public:
83 // ====== Derivation Tree (used in TeachFirst) =============
87 struct TreeNode {
88 QString label;
89 std::vector<std::unique_ptr<TreeNode>> children;
90 };
91
92 // ====== Constructor / Destructor =========================
99 explicit LLTutorWindow(const Grammar& grammar,
100 TutorialManager* tm = nullptr,
101 QWidget* parent = nullptr);
103
104 // ====== State Machine & Question Logic ====================
109 QString generateQuestion();
110
115 void updateState(bool isCorrect);
116
122 QString FormatGrammar(const Grammar& grammar);
123
124 // ====== UI Interaction ====================================
125 void addMessage(const QString& text,
126 bool isUser);
127 void addWidgetMessage(QWidget* widget);
128 void
129 exportConversationToPdf(const QString& filePath);
130 void showTable();
131 void showTableForCPrime();
132 void updateProgressPanel(); // Update progress panel
133
134 // ====== Visual Feedback / Animations ======================
135 void animateLabelPop(QLabel* label);
136 void animateLabelColor(QLabel* label, const QColor& flashColor);
137 void wrongAnimation();
138 void
140 void markLastUserIncorrect();
141
142 // ====== Tree Generation (TeachFirst mode) =================
143 void TeachFirstTree(const std::vector<std::string>& symbols,
144 std::unordered_set<std::string>& first_set, int depth,
145 std::unordered_set<std::string>& processing,
146 QTreeWidgetItem* parent);
147
148 std::unique_ptr<TreeNode>
149 buildTreeNode(const std::vector<std::string>& symbols,
150 std::unordered_set<std::string>& first_set, int depth,
151 std::vector<std::pair<std::string, std::vector<std::string>>>&
152 active_derivations);
153
154 int computeSubtreeWidth(const std::unique_ptr<TreeNode>& node,
155 int hSpacing);
156 void drawTree(const std::unique_ptr<TreeNode>& root, QGraphicsScene* scene,
157 QPointF pos, int hSpacing, int vSpacing);
158
159 void showTreeGraphics(
160 std::unique_ptr<TreeNode> root); // Display derivation tree visually
161
162 // ====== User Response Verification ========================
163 bool verifyResponse(const QString& userResponse); // Delegates to current
164 // state's verification
165 bool verifyResponseForA(const QString& userResponse);
166 bool verifyResponseForA1(const QString& userResponse);
167 bool verifyResponseForA2(const QString& userResponse);
168 bool verifyResponseForB(const QString& userResponse);
169 bool verifyResponseForB1(const QString& userResponse);
170 bool verifyResponseForB2(const QString& userResponse);
171 bool verifyResponseForC(); // C is non-textual (checks internal table)
172
173 // ====== Expected Solutions (Auto-generated) ===============
174 QString solution(const std::string& state);
175 QStringList solutionForA();
176 QString solutionForA1();
177 QString solutionForA2();
178 QSet<QString> solutionForB();
179 QSet<QString> solutionForB1();
180 QSet<QString> solutionForB2();
181
182 // ====== Feedback (Corrective Explanations) ================
183 QString feedback(); // Delegates by state
184 QString feedbackForA();
185 QString feedbackForA1();
186 QString feedbackForA2();
187 QString feedbackForAPrime();
188 QString feedbackForB();
189 QString feedbackForB1();
190 QString feedbackForB2();
191 QString feedbackForBPrime();
192 QString feedbackForC();
193 QString feedbackForCPrime();
194 void feedbackForB1TreeWidget(); // TreeWidget of Teach (LL1 TeachFirst)
195 void feedbackForB1TreeGraphics(); // Show derivation tree
196 QString TeachFollow(const QString& nt);
197 QString TeachPredictionSymbols(const QString& ant,
198 const production& conseq);
199 QString TeachLL1Table();
200
201 void handleTableSubmission(const QVector<QVector<QString>>& raw,
202 const QStringList& colHeaders);
203 private slots:
204 void on_confirmButton_clicked();
205 void on_userResponse_textChanged();
206
207 signals:
208 void sessionFinished(int cntRight, int cntWrong);
209
210 protected:
211 void closeEvent(QCloseEvent* event) override {
212 emit sessionFinished(cntRightAnswers, cntWrongAnswers);
213 QWidget::closeEvent(event);
214 }
215
216 bool eventFilter(QObject* obj, QEvent* event) override;
217
218 private:
219 // ====== Core Objects ======================================
220 Ui::LLTutorWindow* ui;
221 Grammar grammar;
222 LL1Parser ll1;
223
224 // ====== State & Grammar Tracking ==========================
225 State currentState;
226 size_t currentRule = 0;
227 const unsigned kMaxHighlightTries = 3;
228 const unsigned kMaxTotalTries = 5;
229 unsigned lltries = 0;
230 unsigned cntRightAnswers = 0, cntWrongAnswers = 0;
231
232 using Cell = std::pair<QString, QString>;
233 std::vector<Cell> lastWrongCells;
234 LLTableDialog* currentDlg = nullptr;
235
236 QVector<QString> sortedNonTerminals;
237 QVector<QPair<QString, QVector<QString>>> sortedGrammar;
238 QString formattedGrammar;
239
240 QMap<QString, QMap<QString, QVector<QString>>> lltable;
241 QVector<QVector<QString>> rawTable;
242 QSet<QString> solutionSet;
243
244 // ====== Conversation Logging ==============================
245 struct MessageLog {
246 QString message;
247 bool isUser;
248 bool isCorrect = true;
249 MessageLog(const QString& message, bool isUser)
250 : message(message), isUser(isUser) {}
251 void toggleIsCorrect() { isCorrect = false; }
252 };
253
254 QVector<MessageLog> conversationLog;
255 QWidget* lastUserMessage = nullptr;
256 qsizetype lastUserMessageLogIdx = -1;
257
258 QMap<QString, QString> userCAB;
259 QMap<QString, QString> userSIG;
260 QMap<QString, QString> userSD;
261
262 // ====== Helper Conversions ================================
263 std::vector<std::string> qvectorToStdVector(const QVector<QString>& qvec);
264 QVector<QString> stdVectorToQVector(const std::vector<std::string>& vec);
265 QSet<QString>
266 stdUnorderedSetToQSet(const std::unordered_set<std::string>& uset);
267 std::unordered_set<std::string>
268 qsetToStdUnorderedSet(const QSet<QString>& qset);
269
270 void setupTutorial();
271
272 void
273 fillSortedGrammar(); // Populate sortedGrammar from internal representation
274
275 QPropertyAnimation* m_shakeAnimation =
276 nullptr; // For interrupting userResponse animation if they spam enter
277 // key
278
279 TutorialManager* tm = nullptr;
280
281 QRegularExpression re{"^\\s+|\\s+$"};
282};
283
284#endif // LLTUTORWINDOW_H
Definition ll1_parser.hpp:28
Dialog for filling and submitting an LL(1) parsing table.
Definition lltabledialog.h:41
void wrongAnimation()
Visual shake/flash for incorrect answer.
Definition lltutorwindow.cpp:548
QString feedbackForCPrime()
Definition lltutorwindow.cpp:1441
void showTableForCPrime()
Display the full LL(1) table in C' ex.
Definition lltutorwindow.cpp:342
void wrongUserResponseAnimation()
Animation specific to user chat input.
Definition lltutorwindow.cpp:580
void sessionFinished(int cntRight, int cntWrong)
QString TeachLL1Table()
Definition lltutorwindow.cpp:2096
~LLTutorWindow()
Definition lltutorwindow.cpp:99
void showTreeGraphics(std::unique_ptr< TreeNode > root)
Definition lltutorwindow.cpp:1866
void markLastUserIncorrect()
Marks last message as incorrect.
Definition lltutorwindow.cpp:675
void animateLabelColor(QLabel *label, const QColor &flashColor)
Definition lltutorwindow.cpp:645
void drawTree(const std::unique_ptr< TreeNode > &root, QGraphicsScene *scene, QPointF pos, int hSpacing, int vSpacing)
Definition lltutorwindow.cpp:1781
bool verifyResponseForB(const QString &userResponse)
Definition lltutorwindow.cpp:996
QString feedbackForA2()
Definition lltutorwindow.cpp:1229
LLTutorWindow(const Grammar &grammar, TutorialManager *tm=nullptr, QWidget *parent=nullptr)
Constructs the LL(1) tutor window with a given grammar.
Definition lltutorwindow.cpp:27
void showTable()
< Export chat to PDF
Definition lltutorwindow.cpp:430
void feedbackForB1TreeGraphics()
Definition lltutorwindow.cpp:1306
QString solutionForA1()
Definition lltutorwindow.cpp:1081
bool verifyResponseForA1(const QString &userResponse)
Definition lltutorwindow.cpp:988
QString feedbackForB2()
Definition lltutorwindow.cpp:1353
QString feedbackForB1()
Definition lltutorwindow.cpp:1318
bool verifyResponseForC()
Definition lltutorwindow.cpp:1026
void closeEvent(QCloseEvent *event) override
Definition lltutorwindow.h:211
void addWidgetMessage(QWidget *widget)
< Add text message to chat
Definition lltutorwindow.cpp:1445
QString solution(const std::string &state)
QString feedbackForA1()
Definition lltutorwindow.cpp:1219
bool verifyResponseForB1(const QString &userResponse)
Definition lltutorwindow.cpp:1006
bool verifyResponse(const QString &userResponse)
Definition lltutorwindow.cpp:950
QString TeachPredictionSymbols(const QString &ant, const production &conseq)
Definition lltutorwindow.cpp:2024
QString feedbackForAPrime()
Definition lltutorwindow.cpp:1255
void handleTableSubmission(const QVector< QVector< QString > > &raw, const QStringList &colHeaders)
Definition lltutorwindow.cpp:494
QString feedbackForA()
Definition lltutorwindow.cpp:1176
bool verifyResponseForA2(const QString &userResponse)
Definition lltutorwindow.cpp:992
void updateState(bool isCorrect)
Updates the tutor state after verifying user response.
Definition lltutorwindow.cpp:846
QString solutionForA2()
Definition lltutorwindow.cpp:1087
QSet< QString > solutionForB1()
Definition lltutorwindow.cpp:1104
QString feedback()
Definition lltutorwindow.cpp:1141
int computeSubtreeWidth(const std::unique_ptr< TreeNode > &node, int hSpacing)
Definition lltutorwindow.cpp:1769
QString TeachFollow(const QString &nt)
Definition lltutorwindow.cpp:1887
QStringList solutionForA()
Definition lltutorwindow.cpp:1073
void TeachFirstTree(const std::vector< std::string > &symbols, std::unordered_set< std::string > &first_set, int depth, std::unordered_set< std::string > &processing, QTreeWidgetItem *parent)
Definition lltutorwindow.cpp:1625
QString feedbackForC()
Definition lltutorwindow.cpp:1432
QSet< QString > solutionForB2()
Definition lltutorwindow.cpp:1127
QString FormatGrammar(const Grammar &grammar)
Formats a grammar for display in the chat interface.
Definition lltutorwindow.cpp:1474
void animateLabelPop(QLabel *label)
Definition lltutorwindow.cpp:610
bool verifyResponseForB2(const QString &userResponse)
Definition lltutorwindow.cpp:1016
QString feedbackForB()
Definition lltutorwindow.cpp:1265
bool verifyResponseForA(const QString &userResponse)
Definition lltutorwindow.cpp:983
QString feedbackForBPrime()
Definition lltutorwindow.cpp:1393
std::unique_ptr< TreeNode > buildTreeNode(const std::vector< std::string > &symbols, std::unordered_set< std::string > &first_set, int depth, std::vector< std::pair< std::string, std::vector< std::string > > > &active_derivations)
Definition lltutorwindow.cpp:1697
void exportConversationToPdf(const QString &filePath)
< Add widget (e.g., table, tree)
Definition lltutorwindow.cpp:103
void addMessage(const QString &text, bool isUser)
Definition lltutorwindow.cpp:243
void updateProgressPanel()
Definition lltutorwindow.cpp:205
QSet< QString > solutionForB()
Definition lltutorwindow.cpp:1096
bool eventFilter(QObject *obj, QEvent *event) override
Definition lltutorwindow.cpp:1827
void feedbackForB1TreeWidget()
Definition lltutorwindow.cpp:1452
QString generateQuestion()
Generates a question for the current state of the tutor.
Definition lltutorwindow.cpp:766
Manages interactive tutorials by highlighting UI elements and guiding the user.
Definition tutorialmanager.h:53
std::vector< std::string > production
Represents the right-hand side of a grammar rule.
Definition grammar.hpp:34
State
Definition lltutorwindow.h:57
@ C
Definition lltutorwindow.h:57
@ A1
Definition lltutorwindow.h:57
@ A
Definition lltutorwindow.h:57
@ B
Definition lltutorwindow.h:57
@ C_prime
Definition lltutorwindow.h:57
@ B2
Definition lltutorwindow.h:57
@ B_prime
Definition lltutorwindow.h:57
@ A2
Definition lltutorwindow.h:57
@ B1
Definition lltutorwindow.h:57
@ fin
Definition lltutorwindow.h:57
@ A_prime
Definition lltutorwindow.h:57
Represents a context-free grammar, including its rules, symbol table, and starting symbol.
Definition grammar.hpp:46
TreeNode structure used to build derivation trees.
Definition lltutorwindow.h:87
std::vector< std::unique_ptr< TreeNode > > children
Definition lltutorwindow.h:89
QString label
Definition lltutorwindow.h:88
Represents a state in the LR(0) automaton.
Definition state.hpp:33