100 lines
2.7 KiB
Plaintext
100 lines
2.7 KiB
Plaintext
|
|
var table=[
|
|
['q0','0','1','R','q1'],
|
|
['q1','1','1','R','q1'],
|
|
['q1','0','0','S','q2'],
|
|
['q2','0','1','R','q3'],
|
|
['q3',nil,nil,'S','q3']
|
|
];
|
|
|
|
var operand={
|
|
new:func(symbol,changed_symbol,move,next_state) {
|
|
if (move!='L' and move!='R' and move!='S')
|
|
die("invalid move type:"+move);
|
|
return {
|
|
symbol:symbol,
|
|
changed_symbol:changed_symbol,
|
|
move:move,
|
|
next_state:next_state
|
|
};
|
|
}
|
|
};
|
|
|
|
var machine={
|
|
states:{},
|
|
add:func(state,operand) {
|
|
if (!contains(me.states,state))
|
|
me.states[state]=[operand];
|
|
else {
|
|
foreach(var i;me.states[state])
|
|
if (i.symbol==operand.symbol or i.symbol==nil) {
|
|
println(i);
|
|
die("conflict operand");
|
|
}
|
|
append(me.states[state],operand);
|
|
}
|
|
},
|
|
load:func(data) {
|
|
foreach(var opr;data) {
|
|
var (nstat,sym,csym,move,nextstat)=opr;
|
|
me.add(nstat,operand.new(sym,csym,move,nextstat));
|
|
}
|
|
}
|
|
};
|
|
|
|
var prt = func(state,pointer,paper,act=nil) {
|
|
print(act!=nil?act:'','\n\t');
|
|
var s='';
|
|
foreach(var i;paper)
|
|
s~=i;
|
|
s~='\n\t';
|
|
for(var i=0;i<pointer;i+=1)
|
|
for(var j=0;j<size(paper[i]);j+=1)
|
|
s~=' ';
|
|
print(s,'^\n',state," ");
|
|
}
|
|
var run = func(table,start,stop) {
|
|
var paper=['0','1','1','1','0','1','0','a'];
|
|
var pointer=0;
|
|
|
|
machine.load(table);
|
|
|
|
print("states: ",keys(machine.states),'\n');
|
|
if (!contains(machine.states,start))
|
|
die(start~" is not a valid node");
|
|
if (!contains(machine.states,stop))
|
|
die(stop~" is not a valid node");
|
|
|
|
var (state,pointer)=(start,0);
|
|
|
|
prt(state,pointer,paper);
|
|
while(state!=stop) {
|
|
if (!contains(machine.states,state))
|
|
die("no matching function for state:"~state);
|
|
var found=0;
|
|
foreach(var action;machine.states[state]) {
|
|
var (sym,csym,move,next)=(
|
|
action.symbol,
|
|
action.changed_symbol,
|
|
action.move,
|
|
action.next_state
|
|
);
|
|
if (sym==paper[pointer] or sym==nil) {
|
|
if (sym!=nil)
|
|
paper[pointer]=csym;
|
|
if (move=='L') pointer-=1;
|
|
elsif (move=='R') pointer+=1;
|
|
(state,found)=(next,1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
die("no matching function for state:"~state);
|
|
|
|
prt(state,pointer,paper,[sym,csym,move,next]);
|
|
}
|
|
}
|
|
|
|
run(table,'q0','q3');
|
|
print('\n'); |