-
Notifications
You must be signed in to change notification settings - Fork 0
/
mainwindow.cpp
162 lines (151 loc) · 4.25 KB
/
mainwindow.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include "lexerimp.h"
#include "parserll1.h"
#include "parserrecursivedescent.h"
#include <QDebug>
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
tokenList = nullptr;
syntaxTree = nullptr;
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete tokenList;
delete syntaxTree;
delete ui;
}
void MainWindow::on_pushButton_clicked() // 从文件中读取
{
//定义文件对话框类
QFileDialog* fileDialog = new QFileDialog(this);
//定义文件对话框标题
fileDialog->setWindowTitle(QStringLiteral("选中文件"));
//设置默认文件路径
// fileDialog->setDirectory(".");
//设置文件过滤器
fileDialog->setNameFilter(tr("文本文件(*.txt)"));
//设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
fileDialog->setFileMode(QFileDialog::ExistingFiles);
//设置视图模式
fileDialog->setViewMode(QFileDialog::Detail);
//打印所有选择的文件的路径
QStringList fileNames;
if (fileDialog->exec())
{
fileNames = fileDialog->selectedFiles();
}
if (fileNames.size() == 0)
{
return;
}
QFile file(fileNames.back());
file.open(QIODevice::ReadOnly | QIODevice::Text);
QByteArray t = file.readAll();
ui->textEdit->setText(QString(t));
file.close();
}
void MainWindow::on_pushButton_2_clicked() // 进行词法分析
{
Lexer* lexer = new LexerImp();
if (this->tokenList != nullptr)
{
delete this->tokenList;
this->tokenList = nullptr;
}
this->tokenList = lexer->run(ui->textEdit->toPlainText());
delete lexer;
this->printLexer(); // 显示词法分析的结果
}
void MainWindow::on_pushButton_3_clicked() // 进行语法分析
{
if (this->tokenList == nullptr)
{
QMessageBox::about(nullptr, "提示", "尚未进行词法分析,无法进行语法分析");
return;
}
int selectedID = ui->comboBox->currentIndex();
Parser* parser = nullptr;
if (selectedID == 0)
{
parser = new ParserRecursiveDescent(); // 递归下降
}
else
{
parser = new ParserLL1(); // LL1
}
if (this->syntaxTree != nullptr)
{
delete this->syntaxTree;
this->syntaxTree = nullptr;
}
this->syntaxTree = parser->run(*this->tokenList);
this->printParser(); // 显示语法分析的结果
}
void MainWindow::printLexer() // 显示词法分析的结果
{
ui->listWidget->clear();
int tokenSize = this->tokenList->size();
for (int i = 0; i < tokenSize; i++)
{
QString lineStr = "Line " + QString::number((*this->tokenList)[i].getLineShow());
QString lexStr = ConstantVar::lexName[(*this->tokenList)[i].getLexType()];
QString semStr = (*this->tokenList)[i].getSem();
ui->listWidget->addItem(lineStr + " " + lexStr + " " + semStr);
}
}
void MainWindow::printParser() // 显示语法分析的结果
{
ui->treeWidget->clear();
TreeNode* root = this->syntaxTree->getRoot();
QTreeWidgetItem* topItem = new QTreeWidgetItem(ui->treeWidget);
QString str = ConstantVar::nodekindName[root->nodekind];
topItem->setText(0, str);
for (int i = 0; i < 3; i++)
{
if (root->child[i] == nullptr)
{
continue;
}
this->preOrder(root->child[i], topItem);
}
}
void MainWindow::preOrder(TreeNode* node, QTreeWidgetItem* parentItem)
{
QTreeWidgetItem* nowItem = new QTreeWidgetItem(parentItem);
if (node->sibling != nullptr)
{
this->preOrder(node->sibling, parentItem);
}
QString str = ConstantVar::nodekindName[node->nodekind];
// 以下用于显示标识符
for (int i = 0; i < 10; i++)
{
if (node->name[i] != "")
{
if (i != 0)
{
str += ",";
}
else
{
str += ":";
}
str += node->name[i];
}
}
nowItem->setText(0, str);
for (int i = 0; i < 3; i++)
{
if (node->child[i] == nullptr)
{
continue;
}
this->preOrder(node->child[i], nowItem);
}
}