initial commit
This commit is contained in:
@@ -0,0 +1,109 @@
|
|||||||
|
{
|
||||||
|
"name": "0n1n",
|
||||||
|
"description": "{ 0^{n}1^{n} | n>0 }",
|
||||||
|
"grammar": {
|
||||||
|
"states": {
|
||||||
|
"states": [
|
||||||
|
"q0",
|
||||||
|
"q1",
|
||||||
|
"q2",
|
||||||
|
"q3",
|
||||||
|
"q4"
|
||||||
|
],
|
||||||
|
"initial": "q0",
|
||||||
|
"finial": [
|
||||||
|
"q4"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"input": [
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"alphabet": [
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"B",
|
||||||
|
"X",
|
||||||
|
"Y"
|
||||||
|
],
|
||||||
|
"blank": "B",
|
||||||
|
"transition": {
|
||||||
|
"q0": {
|
||||||
|
"0": [
|
||||||
|
"q1",
|
||||||
|
"X",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"Y": [
|
||||||
|
"q3",
|
||||||
|
"Y",
|
||||||
|
"R"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q1": {
|
||||||
|
"Y": [
|
||||||
|
"q1",
|
||||||
|
"Y",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"0": [
|
||||||
|
"q1",
|
||||||
|
"0",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"q2",
|
||||||
|
"Y",
|
||||||
|
"L"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q2": {
|
||||||
|
"Y": [
|
||||||
|
"q2",
|
||||||
|
"Y",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"0": [
|
||||||
|
"q2",
|
||||||
|
"0",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"X": [
|
||||||
|
"q0",
|
||||||
|
"X",
|
||||||
|
"R"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q3": {
|
||||||
|
"Y": [
|
||||||
|
"q3",
|
||||||
|
"Y",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"q4",
|
||||||
|
"B",
|
||||||
|
"L"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q4": {
|
||||||
|
"X": [
|
||||||
|
"q4",
|
||||||
|
"0",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"Y": [
|
||||||
|
"q4",
|
||||||
|
"1",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"q4",
|
||||||
|
"B",
|
||||||
|
"R"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"demo": "000111"
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,42 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2018-05-03T23:17:18
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
TARGET = TuringMachine
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
# The following define makes your compiler emit warnings if you use
|
||||||
|
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||||
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
# deprecated API in order to know how to port your code away from it.
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
# You can also make your code fail to compile if you use deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
main.cpp \
|
||||||
|
mainwindow.cpp \
|
||||||
|
turingmachine.cpp \
|
||||||
|
centralwidget.cpp \
|
||||||
|
papertape.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
mainwindow.h \
|
||||||
|
turingmachine.h \
|
||||||
|
centralwidget.h \
|
||||||
|
papertape.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
mainwindow.ui
|
||||||
|
|
||||||
|
RC_ICONS = Alan_Turing.ico
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
#include "centralwidget.h"
|
||||||
|
|
||||||
|
CentralWidget::CentralWidget(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
machine = new TuringMachine(this);
|
||||||
|
|
||||||
|
// nameEdit = new QLineEdit(this);
|
||||||
|
// nameEdit->setReadOnly(true);
|
||||||
|
autoCheckTimer = new QTimer(this);
|
||||||
|
connect(autoCheckTimer, QTimer::timeout, this, [this](){
|
||||||
|
checkByStep->click();
|
||||||
|
});
|
||||||
|
|
||||||
|
teststrEdit = new QLineEdit(this);
|
||||||
|
|
||||||
|
allStatesEdit = new QLineEdit(this);
|
||||||
|
allStatesEdit->setReadOnly(true);
|
||||||
|
inputEdit = new QLineEdit(this);
|
||||||
|
inputEdit->setReadOnly(true);
|
||||||
|
alphabetEdit = new QLineEdit(this);
|
||||||
|
alphabetEdit->setReadOnly(true);
|
||||||
|
initialStateEdit = new QLineEdit(this);
|
||||||
|
initialStateEdit->setReadOnly(true);
|
||||||
|
blankEdit = new QLineEdit(this);
|
||||||
|
blankEdit->setReadOnly(true);
|
||||||
|
finialStatesEdit = new QLineEdit(this);
|
||||||
|
finialStatesEdit->setReadOnly(true);
|
||||||
|
|
||||||
|
listWidget = new QListWidget(this);
|
||||||
|
|
||||||
|
importButton = new QPushButton(tr("导入配置"), this);
|
||||||
|
connect(importButton, QPushButton::clicked, this, importJson);
|
||||||
|
checkByStep = new QPushButton(tr("单步检查"), this);
|
||||||
|
checkByStep->setDisabled(true);
|
||||||
|
connect(checkByStep, QPushButton::clicked, this, stepCheck);
|
||||||
|
autoCheckButton = new QPushButton(tr("自动模式"), this);
|
||||||
|
autoCheckButton->setDisabled(true);
|
||||||
|
connect(autoCheckButton, QPushButton::clicked, this, autoCheck);
|
||||||
|
loadButton = new QPushButton(tr("装载纸带"), this);
|
||||||
|
loadButton->setDisabled(true);
|
||||||
|
connect(loadButton, QPushButton::clicked, this, loadTape);
|
||||||
|
resetButton = new QPushButton(tr("重置"), this);
|
||||||
|
connect(resetButton, QPushButton::clicked, this, [this](){
|
||||||
|
machine->reset();
|
||||||
|
loadButton->setEnabled(true);
|
||||||
|
autoCheckButton->setDisabled(true);
|
||||||
|
checkByStep->setDisabled(true);
|
||||||
|
checkByStep->setChecked(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
tape = new PaperTape();
|
||||||
|
scene = new QGraphicsScene(this);
|
||||||
|
scene->setSceneRect(-250, -65, 500, 130);
|
||||||
|
scene->addItem(tape);
|
||||||
|
scene->addLine(0,0,0,40,QPen(Qt::red));
|
||||||
|
view = new QGraphicsView(scene ,this);
|
||||||
|
|
||||||
|
|
||||||
|
formlayout = new QFormLayout();
|
||||||
|
// formlayout->setSpacing(10);
|
||||||
|
// formlayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
|
||||||
|
// formlayout->addRow(tr("Name"), nameEdit);
|
||||||
|
formlayout->addRow(tr("状态集合"), allStatesEdit);
|
||||||
|
formlayout->addRow(tr("输入字符"), inputEdit);
|
||||||
|
formlayout->addRow(tr("字符表"), alphabetEdit);
|
||||||
|
formlayout->addRow(tr("初始状态"), initialStateEdit);
|
||||||
|
formlayout->addRow(tr("空白符"), blankEdit);
|
||||||
|
formlayout->addRow(tr("终止状态"), finialStatesEdit);
|
||||||
|
formlayout->addRow(tr("Test string"), teststrEdit);
|
||||||
|
// formlayout->addRow(loadButton);
|
||||||
|
// formlayout->addRow(checkByStep);
|
||||||
|
|
||||||
|
vsublayout = new QVBoxLayout();
|
||||||
|
vsublayout->addWidget(importButton);
|
||||||
|
vsublayout->addWidget(resetButton);
|
||||||
|
vsublayout->addWidget(loadButton);
|
||||||
|
vsublayout->addWidget(autoCheckButton);
|
||||||
|
vsublayout->addWidget(checkByStep);
|
||||||
|
|
||||||
|
hlayout = new QHBoxLayout();
|
||||||
|
hlayout->addLayout(formlayout);
|
||||||
|
hlayout->addWidget(listWidget);
|
||||||
|
hlayout->addLayout(vsublayout);
|
||||||
|
// hlayout->addWidget(importButton);
|
||||||
|
|
||||||
|
|
||||||
|
mainlayout = new QVBoxLayout(this);
|
||||||
|
mainlayout->addLayout(hlayout);
|
||||||
|
mainlayout->addWidget(view);
|
||||||
|
|
||||||
|
setLayout(mainlayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
CentralWidget::~CentralWidget()
|
||||||
|
{
|
||||||
|
delete machine;
|
||||||
|
delete tape;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CentralWidget::importJson()
|
||||||
|
{
|
||||||
|
QString filename = QFileDialog::getOpenFileName(this, tr("import json"),
|
||||||
|
".",tr("json(*.json)"));
|
||||||
|
if(filename.isEmpty())
|
||||||
|
return;
|
||||||
|
if(!machine->setGrammar(filename))
|
||||||
|
{
|
||||||
|
setStatus("请检查文件格式");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
setStatus(tr("导入成功"));
|
||||||
|
if(machine->hasGrammar())
|
||||||
|
{
|
||||||
|
loadButton->setEnabled(true);
|
||||||
|
// checkByStep->setEnabled(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
loadButton->setDisabled(false);
|
||||||
|
// nameEdit->setText(machine->getName());
|
||||||
|
allStatesEdit->setText(machine->getAllStates().join(", "));
|
||||||
|
alphabetEdit->setText(machine->getAlphabet().split("", QString::SkipEmptyParts).join(", "));
|
||||||
|
inputEdit->setText(machine->getInput().split("", QString::SkipEmptyParts).join(", "));
|
||||||
|
initialStateEdit->setText(machine->getInitialState());
|
||||||
|
blankEdit->setText(machine->getBlank());
|
||||||
|
finialStatesEdit->setText(machine->getFinialStates().join(", "));
|
||||||
|
listWidget->clear();
|
||||||
|
listWidget->addItems(machine->getTransition());
|
||||||
|
|
||||||
|
if(teststrEdit->text().isEmpty())
|
||||||
|
{
|
||||||
|
teststrEdit->setText(machine->getRawStr());
|
||||||
|
}
|
||||||
|
tape->adjustPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CentralWidget::loadTape()
|
||||||
|
{
|
||||||
|
machine->setTestStr(teststrEdit->text());
|
||||||
|
machine->reset();
|
||||||
|
tape->setStr(machine->getTestStr());
|
||||||
|
tape->standBy(1);
|
||||||
|
checkByStep->setEnabled(true);
|
||||||
|
autoCheckButton->setEnabled(true);
|
||||||
|
machineReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CentralWidget::stepCheck()
|
||||||
|
{
|
||||||
|
machineReady = machine->checkByStep();
|
||||||
|
if(machineReady)
|
||||||
|
{
|
||||||
|
loadButton->setDisabled(true);
|
||||||
|
tape->standBy(machine->getCurrentIndex());
|
||||||
|
tape->setStr(machine->getTestStr());
|
||||||
|
listWidget->setCurrentRow(machine->getTransitionIndex());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loadButton->setEnabled(true);
|
||||||
|
autoCheckButton->setDisabled(true);
|
||||||
|
checkByStep->setDisabled(true);
|
||||||
|
checkByStep->setChecked(false);
|
||||||
|
autoCheckTimer->stop();
|
||||||
|
if(machine->getFinialStates().contains(machine->getCurrentState()))
|
||||||
|
{
|
||||||
|
emit setStatus("Correct!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit setStatus("Not OK!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CentralWidget::autoCheck()
|
||||||
|
{
|
||||||
|
autoCheckTimer->start(300);
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#ifndef CENTRALWIDGET_H
|
||||||
|
#define CENTRALWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
#include <QGraphicsView>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QTimer>
|
||||||
|
#include "turingmachine.h"
|
||||||
|
#include "papertape.h"
|
||||||
|
|
||||||
|
class CentralWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CentralWidget(QWidget *parent = nullptr);
|
||||||
|
~CentralWidget();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void setStatus(QString message);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void importJson();
|
||||||
|
void loadTape();
|
||||||
|
void stepCheck();
|
||||||
|
void autoCheck();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVBoxLayout *mainlayout, *vsublayout;
|
||||||
|
QFormLayout *formlayout;
|
||||||
|
QHBoxLayout *hlayout;
|
||||||
|
QLineEdit *nameEdit, *teststrEdit;
|
||||||
|
QLineEdit *allStatesEdit, *alphabetEdit, *inputEdit, *initialStateEdit, *blankEdit, *finialStatesEdit;
|
||||||
|
QPushButton *importButton;
|
||||||
|
QPushButton *loadButton, *checkByStep, *resetButton, *autoCheckButton;
|
||||||
|
|
||||||
|
QListWidget *listWidget;
|
||||||
|
|
||||||
|
QGraphicsScene *scene;
|
||||||
|
QGraphicsView *view;
|
||||||
|
PaperTape *tape;
|
||||||
|
|
||||||
|
QTimer *autoCheckTimer;
|
||||||
|
|
||||||
|
TuringMachine *machine;
|
||||||
|
bool machineReady = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CENTRALWIDGET_H
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
{
|
||||||
|
"name": "m-n",
|
||||||
|
"description": "calculate m-n",
|
||||||
|
"grammar": {
|
||||||
|
"states": {
|
||||||
|
"states": [
|
||||||
|
"q0",
|
||||||
|
"q1",
|
||||||
|
"q2",
|
||||||
|
"q3",
|
||||||
|
"q4",
|
||||||
|
"q5",
|
||||||
|
"q6"
|
||||||
|
],
|
||||||
|
"initial": "q0",
|
||||||
|
"finial": [
|
||||||
|
"q6"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"input": [
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"alphabet": [
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"B"
|
||||||
|
],
|
||||||
|
"blank": "B",
|
||||||
|
"transition": {
|
||||||
|
"q0": {
|
||||||
|
"0": [
|
||||||
|
"q1",
|
||||||
|
"B",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"q5",
|
||||||
|
"B",
|
||||||
|
"R"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q1": {
|
||||||
|
"0": [
|
||||||
|
"q1",
|
||||||
|
"0",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"q2",
|
||||||
|
"1",
|
||||||
|
"R"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q2": {
|
||||||
|
"1": [
|
||||||
|
"q2",
|
||||||
|
"1",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"q3",
|
||||||
|
"B",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"0": [
|
||||||
|
"q4",
|
||||||
|
"1",
|
||||||
|
"L"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q3": {
|
||||||
|
"0": [
|
||||||
|
"q3",
|
||||||
|
"0",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"q3",
|
||||||
|
"B",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"q6",
|
||||||
|
"0",
|
||||||
|
"S"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q4": {
|
||||||
|
"0": [
|
||||||
|
"q4",
|
||||||
|
"0",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"q4",
|
||||||
|
"1",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"q0",
|
||||||
|
"B",
|
||||||
|
"R"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"q5": {
|
||||||
|
"0": [
|
||||||
|
"q5",
|
||||||
|
"B",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
"q5",
|
||||||
|
"B",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"q6",
|
||||||
|
"B",
|
||||||
|
"S"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"demo": "00000100"
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include "turingmachine.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
a.setFont(QFont("Microsoft YaHei UI",9));
|
||||||
|
MainWindow w;
|
||||||
|
w.show();
|
||||||
|
|
||||||
|
// TuringMachine tm;
|
||||||
|
// tm.setGrammar("0n1n.json");
|
||||||
|
// tm.setTestStr("");
|
||||||
|
// if(tm.run())
|
||||||
|
// qDebug()<<"OK";
|
||||||
|
// else
|
||||||
|
// qDebug()<<"not ok";
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow(parent)
|
||||||
|
// ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
// ui->setupUi(this);
|
||||||
|
cw = new CentralWidget(this);
|
||||||
|
helpMenu = new QMenu(this);
|
||||||
|
aboutAction = new QAction(tr("关于"), this);
|
||||||
|
connect(aboutAction, QAction::triggered, this, showAbout);
|
||||||
|
helpMenu->setTitle(tr("帮助(&H)"));
|
||||||
|
helpMenu->addAction(aboutAction);
|
||||||
|
setCentralWidget(cw);
|
||||||
|
menuBar()->addMenu(helpMenu);
|
||||||
|
statusBar()->showMessage("欢迎使用环保图灵机!");
|
||||||
|
connect(cw, CentralWidget::setStatus, this,[this](QString message)
|
||||||
|
{
|
||||||
|
statusBar()->showMessage(message, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete cw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showAbout()
|
||||||
|
{
|
||||||
|
QMessageBox *aboutWindow = new QMessageBox(this);
|
||||||
|
aboutWindow->setStandardButtons(QMessageBox::Ok);
|
||||||
|
aboutWindow->setText(tr("<h1>TuringMachine</h1>"
|
||||||
|
"<p>Based on Qt 5.10.1 (MinGW 5.3.0, 32bit)</p>"
|
||||||
|
"Source Code: <a href=\"https://github.com/c-my/TuringMachine\">https://github.com/c-my/TuringMachine</a><br/>"
|
||||||
|
"Email: "
|
||||||
|
"<address><a href=\"mailto:cmy1113@outlook.com?subject=TuringMachine Feedback\">cmy1113@outlook.com</a>"
|
||||||
|
"</address>"));
|
||||||
|
aboutWindow->show();
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include "centralwidget.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CentralWidget *cw;
|
||||||
|
QMenu *helpMenu;
|
||||||
|
QAction *aboutAction;
|
||||||
|
|
||||||
|
void showAbout();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAINWINDOW_H
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenuBar" name="menuBar" />
|
||||||
|
<widget class="QToolBar" name="mainToolBar" />
|
||||||
|
<widget class="QWidget" name="centralWidget" />
|
||||||
|
<widget class="QStatusBar" name="statusBar" />
|
||||||
|
</widget>
|
||||||
|
<layoutDefault spacing="6" margin="11" />
|
||||||
|
<pixmapfunction></pixmapfunction>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#include "papertape.h"
|
||||||
|
|
||||||
|
PaperTape::PaperTape(QGraphicsItem *parent): QGraphicsObject(parent)
|
||||||
|
{
|
||||||
|
ani = new QPropertyAnimation(this, "pos");
|
||||||
|
this->setStr("hello");
|
||||||
|
this->adjustPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF PaperTape::boundingRect() const
|
||||||
|
{
|
||||||
|
return QRectF(0 ,0 ,str.size()*width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaperTape::setStr(QString str)
|
||||||
|
{
|
||||||
|
this->str = str;
|
||||||
|
lastLenth = lenth;
|
||||||
|
lenth = str.size();
|
||||||
|
// this->adjustPos();
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PaperTape::getWidth()
|
||||||
|
{
|
||||||
|
return lenth*width;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaperTape::standBy(int index)
|
||||||
|
{
|
||||||
|
// ani->setStartValue(this->pos());
|
||||||
|
ani->setEndValue(QPointF(-(index+0.5)*width, this->pos().y()));
|
||||||
|
ani->setDuration(230);
|
||||||
|
ani->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaperTape::adjustPos()
|
||||||
|
{
|
||||||
|
setPos(-str.size()*width/2, -height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaperTape::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||||
|
{
|
||||||
|
painter->setBackground(QBrush(Qt::white));
|
||||||
|
painter->eraseRect(/*-lastLenth*width/2, -height, width*1000, height*/boundingRect());
|
||||||
|
painter->setBrush(QBrush("lightblue"));
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->drawRect(0, 0, lenth*width, height);
|
||||||
|
painter->setPen(Qt::black);
|
||||||
|
painter->setPen(Qt::DotLine);
|
||||||
|
painter->setFont(QFont("Microsoft Yahei", 13));
|
||||||
|
for(int i=0; i<lenth; i++)
|
||||||
|
{
|
||||||
|
if(i!=0)
|
||||||
|
{
|
||||||
|
// 画分割线
|
||||||
|
painter->drawLine(0+i*width, 0, 0+i*width, height);
|
||||||
|
}
|
||||||
|
// 画字符
|
||||||
|
painter->drawText(i*width+width/2-4, height/2+8, str.at(i));
|
||||||
|
}
|
||||||
|
setToolTip(this->str);
|
||||||
|
// setPos(-str.size()*width/2, -height);
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef PAPERTAPE_H
|
||||||
|
#define PAPERTAPE_H
|
||||||
|
|
||||||
|
#include <QGraphicsObject>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
|
||||||
|
class PaperTape : public QGraphicsObject
|
||||||
|
{
|
||||||
|
Q_PROPERTY(QPoinF pos READ pos WRITE setPos)
|
||||||
|
public:
|
||||||
|
PaperTape(QGraphicsItem *parent = Q_NULLPTR);
|
||||||
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR);
|
||||||
|
QRectF boundingRect() const;
|
||||||
|
void setStr(QString str);
|
||||||
|
int getWidth();
|
||||||
|
void standBy(int index);
|
||||||
|
void adjustPos();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int height = 50;
|
||||||
|
int width = 50;
|
||||||
|
QString str;
|
||||||
|
int lenth=0, lastLenth=0;
|
||||||
|
QPropertyAnimation *ani;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PAPERTAPE_H
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
#include "turingmachine.h"
|
||||||
|
|
||||||
|
TuringMachine::TuringMachine(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
currentIndex = 1;
|
||||||
|
isRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TuringMachine::setGrammar(QString filename)
|
||||||
|
{
|
||||||
|
QFile jsonFile(filename);
|
||||||
|
if(!jsonFile.exists())
|
||||||
|
return false;
|
||||||
|
jsonFile.open(QIODevice::ReadOnly|QIODevice::Text);
|
||||||
|
jsonobj = QJsonDocument::fromJson(jsonFile.readAll()).object();
|
||||||
|
jsonFile.close();
|
||||||
|
if(jsonobj.isEmpty()||!jsonobj.contains("grammar"))
|
||||||
|
return false;
|
||||||
|
grammar = jsonobj.value("grammar").toObject();
|
||||||
|
if(!grammar.contains("states")
|
||||||
|
||!grammar.contains("input")
|
||||||
|
||!grammar.contains("alphabet")
|
||||||
|
||!grammar.contains("blank")
|
||||||
|
||!grammar.contains("transition"))
|
||||||
|
return false;
|
||||||
|
//获取初始状态
|
||||||
|
initialState = grammar.value("states").toObject().value("initial").toString();
|
||||||
|
currentState = initialState;
|
||||||
|
|
||||||
|
//获取终止状态
|
||||||
|
finialStates.clear();
|
||||||
|
QJsonArray array = grammar.value("states").toObject().value("finial").toArray();
|
||||||
|
for(auto item: array)
|
||||||
|
finialStates.append(item.toString());
|
||||||
|
|
||||||
|
//获取状态集合
|
||||||
|
allStates.clear();
|
||||||
|
array = grammar.value("states").toObject().value("states").toArray();
|
||||||
|
for(auto item: array)
|
||||||
|
allStates.append(item.toString());
|
||||||
|
|
||||||
|
//获取空白符
|
||||||
|
blank = grammar.value("blank").toString().at(0);
|
||||||
|
|
||||||
|
//获取字符表
|
||||||
|
alphabet.clear();
|
||||||
|
array = grammar.value("alphabet").toArray();
|
||||||
|
for(auto item: array)
|
||||||
|
alphabet += (item.toString());
|
||||||
|
|
||||||
|
//获取接受字符
|
||||||
|
input.clear();
|
||||||
|
array = grammar.value("input").toArray();
|
||||||
|
for(auto item: array)
|
||||||
|
input += (item.toString());
|
||||||
|
|
||||||
|
//获取转移字符
|
||||||
|
transition.clear();
|
||||||
|
QStringList keys = grammar.value("transition").toObject().keys();
|
||||||
|
for(auto key: keys)
|
||||||
|
{
|
||||||
|
QJsonObject subobject = grammar.value("transition").toObject().value(key).toObject();
|
||||||
|
QStringList subkeys = subobject.keys();
|
||||||
|
for(auto subkey: subkeys)
|
||||||
|
{
|
||||||
|
QJsonArray array = subobject.value(subkey).toArray();
|
||||||
|
QString tmp = "δ(" + key +", " + subkey + ") = (";
|
||||||
|
for(auto item: array)
|
||||||
|
tmp += item.toString()+", ";
|
||||||
|
tmp.remove(tmp.length()-2, 2);
|
||||||
|
tmp+=")";
|
||||||
|
transition.append(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTestStr(jsonobj.value("demo").toString());
|
||||||
|
name = jsonobj.value("name").toString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TuringMachine::setTestStr(QString str)
|
||||||
|
{
|
||||||
|
rawStr = str;
|
||||||
|
testStr = blank + str + blank;
|
||||||
|
isRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TuringMachine::checkByStep()
|
||||||
|
{
|
||||||
|
QJsonValue value = grammar.value("transition").toObject().value(currentState)
|
||||||
|
.toObject().value(testStr.at(currentIndex));
|
||||||
|
if(!value.isUndefined())
|
||||||
|
{
|
||||||
|
QString listItem;
|
||||||
|
listItem = "δ(" +currentState + ", " + testStr.at(currentIndex) + ") = (";
|
||||||
|
currentState = value.toArray()[0].toString(); //更新当前状态
|
||||||
|
testStr[currentIndex] = value.toArray()[1].toString()[0]; //更新当前字符
|
||||||
|
QString move = value.toArray()[2].toString();
|
||||||
|
listItem += currentState +", " + testStr[currentIndex] + ", " + move+")";
|
||||||
|
transitionIndex = transition.indexOf(listItem);
|
||||||
|
|
||||||
|
if(move == "L")
|
||||||
|
currentIndex = (currentIndex - 1 >= 0) ? (currentIndex - 1) : 0;
|
||||||
|
else if(move == "R")
|
||||||
|
currentIndex = (currentIndex + 1 < testStr.size()) ?
|
||||||
|
(currentIndex + 1) : testStr.size()-1;
|
||||||
|
else if(move == "S")
|
||||||
|
currentIndex = currentIndex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TuringMachine::run()
|
||||||
|
{
|
||||||
|
while (isRunning) {
|
||||||
|
checkByStep();
|
||||||
|
}
|
||||||
|
if(finialStates.contains(currentState))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TuringMachine::hasGrammar()
|
||||||
|
{
|
||||||
|
return !this->jsonobj.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TuringMachine::isStopped()
|
||||||
|
{
|
||||||
|
return !isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TuringMachine::reset()
|
||||||
|
{
|
||||||
|
currentIndex = 1;
|
||||||
|
currentState = initialState;
|
||||||
|
// transition.clear();
|
||||||
|
// input.clear();
|
||||||
|
// alphabet.clear();
|
||||||
|
// finialStates.clear();
|
||||||
|
// allStates.clear();
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef TURINGMACHINE_H
|
||||||
|
#define TURINGMACHINE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonValue>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class TuringMachine : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TuringMachine(QObject *parent = nullptr);
|
||||||
|
bool setGrammar(QString filename);
|
||||||
|
void setTestStr(QString str);
|
||||||
|
QString getTestStr() { return testStr; }
|
||||||
|
QString getRawStr() { return rawStr; }
|
||||||
|
QString getName() { return name; }
|
||||||
|
QString getInitialState() { return initialState; }
|
||||||
|
QChar getBlank() { return blank; }
|
||||||
|
QStringList getFinialStates() { return finialStates; }
|
||||||
|
QStringList getAllStates() { return allStates; }
|
||||||
|
QString getAlphabet() { return alphabet; }
|
||||||
|
QString getInput() { return input; }
|
||||||
|
int getCurrentIndex() { return currentIndex; }
|
||||||
|
QStringList getTransition() { return transition; }
|
||||||
|
int getTransitionIndex() { return transitionIndex; }
|
||||||
|
QString getCurrentState() { return currentState; }
|
||||||
|
bool checkByStep();
|
||||||
|
bool run();
|
||||||
|
bool hasGrammar();
|
||||||
|
bool isStopped();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QJsonObject jsonobj;
|
||||||
|
QJsonObject grammar;
|
||||||
|
QString name;
|
||||||
|
QString rawStr, testStr;
|
||||||
|
QChar blank; //空白符
|
||||||
|
QString currentState; //当前状态
|
||||||
|
int currentIndex; //当前字符索引号
|
||||||
|
int transitionIndex;
|
||||||
|
QString initialState;
|
||||||
|
QStringList finialStates;
|
||||||
|
QStringList allStates;
|
||||||
|
QString input;
|
||||||
|
QString alphabet;
|
||||||
|
QStringList transition;
|
||||||
|
bool isRunning;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TURINGMACHINE_H
|
||||||
Reference in New Issue
Block a user