-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
122 lines (119 loc) · 4.54 KB
/
script.js
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
import Thompson from './utils/Thompson.js';
import AFNJoining from './utils/AFNJoining.js';
import AFDConvertion from './utils/AFDConvertion.js';
import AFDMinimization from './utils/AFDMinimization.js';
import Simulation from './utils/Simulation.js';
import {printMat, printAlphabet} from './utils/printing.js';
const getAlphabet = (letters) =>{
const alphabet = Array.from(
new Set(
letters.split('').sort()
)
).join('');//Extract the unique characters and sort them
return alphabet;
}
let alphabet = '';//Alphabet sorted by string asc
let afDArray = []; //array of {token:'' afd:[]}
let symbolsTable = [];//array of {token:'', lexeme:''}
const definitions = [];
const generateAFDs = ()=>{
const textArea = document.getElementById('lexycalDefinition').value;
const alphaInput = document.getElementById('alphabet').value;
const definitionLines = textArea.split('\n');
definitionLines.forEach(line => {
const definition = line.split('->');
definitions.push({
"token":definition[0],
"lexeme":definition[1],
})
});
/***/
alphabet = getAlphabet(alphaInput);
printAlphabet(alphabet);
for(let i = 0; i < definitions.length; i++){
const afn = Thompson(alphabet, definitions[i].lexeme, 0, definitions[i].token);//Generates the afn
printMat(afn);
const bigAFD = AFDConvertion(alphabet, afn);//Convertion to afd
const minimizatedAFD = AFDMinimization(alphabet, bigAFD);//Minimization
afDArray[i] = {//Generates an object with the token and afd
"token": definitions[i].token,
"afd":minimizatedAFD
};
}
}
const simulateAll = ()=>{
const textToSimulate = document.getElementById('stringInput').value;
const arrayToSimulate = textToSimulate.split(' ');
symbolsTable = [];
arrayToSimulate.forEach(string =>{
simulateOne(string);
})
showSymbolsTable();
showTransitionTable();
}
const simulateOne = (stringToSimulate)=>{
if(afDArray.length){
let afdUsed = -1;
let i = 0;
while( afdUsed === -1 && i < afDArray.length){
if( Simulation(afDArray[i].afd, alphabet, stringToSimulate) ){
symbolsTable.push({
token: afDArray[i].token,
lexeme: stringToSimulate
});
afdUsed = i;
}
i++;
}
if(afdUsed === -1){
console.error('Lexical error. Lexeme: ' + stringToSimulate);
}
}
}
const showSymbolsTable = () =>{
const domTable = document.getElementById('symbolsTable');
domTable.innerHTML = "<tr><th>Token</th><th>Lexeme</th></tr>" + symbolsTable.reduce( (acc, curr) => (`${acc}
<tr>
<td>${curr.token}</td>
<td>${curr.lexeme}</td>
</tr>`)
, '' );
}
const generateTransitionTable = () => {
if (alphabet && definitions.length) {
const joinedAFN = AFNJoining(alphabet, definitions );
const bigAFD = AFDConvertion(alphabet, joinedAFN);
const minimizatedAFD = AFDMinimization(alphabet, bigAFD);
return minimizatedAFD;
}
return [];
}
const showTransitionTable = () => {
const transitionTable = generateTransitionTable();
const domTable = document.getElementById('transitionTable');
const alphabetRow = '<tr><th></th>' + alphabet.split('').reduce((acc, curr)=>(`${acc}
<th>${curr}</th>
`),'') + '</tr>';
let totalTable = '';
for( let i = 0; i < transitionTable.length; i++ ){
if( transitionTable[i][transitionTable[i].length - 2] ){//If its initial
totalTable = `${totalTable}<tr style='background-color:#e5f993;'><td> State ${i}</td>`;
}else if( transitionTable[i][transitionTable[i].length - 1] ){//If its final
totalTable = `${totalTable}<tr style='background-color:#bf211e; color:white;'><td> State ${i}</td>`;
}else{
totalTable = `${totalTable}<tr><td> State ${i}</td>`;
}
for( let j = 0; j < transitionTable[i].length - 2; j++ ){
const el = transitionTable[i][j];
if(el===0 || el){
totalTable = `${totalTable}<td>${el}</td>`;
}else{
totalTable = `${totalTable}<td></td>`;
}
}
totalTable = `${totalTable}</tr>`;
}
domTable.innerHTML = alphabetRow + totalTable;
}
document.getElementById('regexInputButton').addEventListener('click', generateAFDs);
document.getElementById('simulate').addEventListener('click', simulateAll);