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