-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtm.js
More file actions
161 lines (144 loc) · 5.69 KB
/
tm.js
File metadata and controls
161 lines (144 loc) · 5.69 KB
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
// Statesクラスのようなもの
function States() {
this.stateNames = [];
}
// states.状態名.nextState[i]
// states.状態名.readSymbol[i]
// states.状態名.writeSymbol[i]
// states.状態名.direction directionだけは状態に固有の値
States.prototype.push = function (addingState, nextState, readSymbol, writeSymbol, direction) {
if (this.stateNames.indexOf(addingState) == -1) {
this.stateNames.push(addingState);
eval("states." + addingState + " = new Object();");
eval("states." + addingState + ".nextState = [];");
eval("states." + addingState + ".readSymbol = [];");
eval("states." + addingState + ".writeSymbol = [];");
eval("states." + addingState + ".nextState.push(\"" + nextState + "\");");
eval("states." + addingState + ".readSymbol.push(\"" + readSymbol + "\");");
eval("states." + addingState + ".writeSymbol.push(\"" + writeSymbol + "\");");
eval("states." + addingState + ".direction = \"" + direction + "\";");
} else {
eval("states." + addingState + ".nextState.push(\"" + nextState + "\");");
eval("states." + addingState + ".readSymbol.push(\"" + readSymbol + "\");");
eval("states." + addingState + ".writeSymbol.push(\"" + writeSymbol + "\");");
}
}
function initialize() {
tape = [];
states = new States();
currentState = "";
$(".result").text("");
$("tr").remove();
}
function readFile() {
var fileObj = $("#input").prop("files")[0];
var reader = new FileReader();
reader.onload = function(e) {
var TMDescription = reader.result;
var rows = TMDescription.split(/\r\n|\r|\n/);
var units;
for (var i = 0; i < rows.length; i++) {
units = rows[i].split(/\,/);
/****************************
********** 注意 **********
****************************/
if (units.length == 5) {
if (states.stateNames.length == 0) {
currentState = units[0]; // 一番最初に取得した状態を開始状態とする
}
states.push(units[0], units[1], units[2], units[3], units[4]);
}
}
states.push("reject", "-", "-", "-", "-");
states.push("accept", "-", "-", "-", "-");
// ファイル読み込みが並列で行われてるらしく,
// 読み込みが終わる前に処理がどんどん進んでしまってバグの原因になっていた.
// 本当はmainに上手いこと書くべきなのだろうが,
// 思いつかないのでとりあえずはここに置いておく.
readTape();
runTuringMachine();
};
reader.readAsText(fileObj, "UTF-8");
}
function readTape() {
var tapeDescription = $("#tape").val();
tape = tapeDescription.split(/\,/);
for (var i = 0; i < tape.length; i++) {
if (tape[i] == " ") {
tape[i] = "_";
}
}
}
function appendCurrentTapeToTable(transitionCount, headIndex) {
$("tbody").append("<tr></tr>");
$("tr:last").append("<th>" + transitionCount + "(" + currentState + ")</th>");
for (var i = 0; i < tape.length; i++) {
$("tr:last").append("<td>" + tape[i] + "</td>");
if (i == headIndex) {
$("td:last").attr("id", "head");
}
}
}
function runTuringMachine() {
var maximumTransitionCount = $("input[name=max]").val();
var j = 0, headIndex = 0, isTapeExtended = false;
eval("var obj = states." + currentState + ";");
for (var i = 0; i < maximumTransitionCount; i++) {
if (currentState == "accept") {
$(".result").text("受理");
break;
} else if (currentState == "reject") {
$(".result").text("非受理");
break;
}
if (obj.direction == "R") {
Outer:
for (headIndex++;; headIndex++) {
if (headIndex >= tape.length) {
if (isTapeExtended) {
alert("テープの内容を確認して下さい.");
return;
}
tape[headIndex] = "_"; // 右側はスペース
isTapeExtended = true;
}
for (j = 0; j < obj.readSymbol.length; j++) {
if (tape[headIndex] == obj.readSymbol[j]) {
isTapeExtended = false;
break Outer;
}
}
}
} else if (obj.direction == "L") {
Outer:
for (headIndex--;; headIndex--) {
for (j = 0; j < obj.readSymbol.length; j++) {
if (tape[headIndex] == obj.readSymbol[j]) {
break Outer;
}
}
}
} else {
for (j = 0; j < obj.readSymbol.length; j++) {
if (tape[headIndex] == obj.readSymbol[j]) {
break;
}
}
}
appendCurrentTapeToTable(i + 1, headIndex);
tape[headIndex] = obj.writeSymbol[j];
eval("currentState = states." + currentState + ".nextState[" + j + "];");
eval("obj = states." + currentState + ";");
}
appendCurrentTapeToTable(i + 1, headIndex);
$("tbody").prepend("<tr><th></th></tr>");
for (var i = 0; i < tape.length; i++) {
$("tr:first").append("<th>" + (i + 1) + "</th>");
}
}
$(function() {
$("#run").click(function() {
initialize();
readFile();
});
})