Autor: Andreas Rieger
Datum: 10.01.2022
Erzeugen Sie mit Hilfe der Grammatik aus Aufgabe P2 einen zufälligen arithmetische Ausdruck. Es sollt auch möglich sein einen [wahrscheinlich] fehlerhaften Ausdruck zu erzeugen. Dazu löschen Sie einfach ein beliebiges Zeichen aus dem Ausdruck. Prüfen Sie den erzeugten Ausdruck mittels eines Kellerautomaten.
Die Generierung der Ausdrücke mittels der Grammatik wird nicht angezeigt. Der Kellerautomaten soll als Tabelle und als Graph dargestellt werden. Die Verarbeitung der Eingabe durch den Automaten kann gleichzeitig schrittweise in der Tabelle der Überführungsfunktion und im Graphen nachvollzogen werden. Schließlich wird das Endzustand und das Ergebnis (erkannt oder nicht erkannt) des Automaten dargestellt.
Die Anwendung basiert auf HTML, CSS und Javascript.
Zur Visualisierung der Oberfläche wurde das Framework Bootstrap v5.1 verwendet. Bootstrap liefert eine einheitliche, gut strukturierte und responsive Benutzeroberfläche, die sich verschiedenen Endgeräten anpassen lässt. Außerdem hält das Framework viele vordefinierte und ansprechend gestaltete Komponenten zur Interaktion bereit.
Zunächst erfolgt die Eingabe des zu prüfenden arithmetischen Ausdrucks per Formular. Alternativ dazu erstellt die Anwendung im Hintergrund einen zufälligen aber korrekten Ausdruck.
Übergabe der Formulardaten an das Backend bzw. Start des Zufallsgenerators.
const response = (input.value != "") ? main(input.value) : E(false);
Erzeugung eines zufälligen korrekten Ausdrucks.
const A = () => {
let expression = randomZ().toString();
for (let i = 1; i < eL; i++) {
expression = (i < 2 || i == eL) ? randomCD(expression) : randomCD(B(expression));
}
return expression
};
Anschließend wird ein beliebiges Zeichen entfernt, so dass der Ausdruck wahrscheinlich fehlerhaft ist
Entfernung eines beliebigen Zeichens
const makeInvalid = (expression) => {
const min = 0;
const max = expression.length - 1;
const e2R = Math.floor(Math.random() * (max - min + 1)) + min;
return expression.slice(0, e2R) + expression.slice(e2R + 1);
};
Der eingegebene bzw. erstellte Ausdruck und die Prüfschritte werden anschließend als Objekt zur Ausgabe an das Frontend zurückgegeben.
Rückgabe an das Frontend
const E = (bool) => {
const expression = (bool) ? A() : makeInvalid(A());
const states = isValidExpression(expression)
return {
expression: expression,
states: states
}
};
Ausgabe des Ausdrucks und der Zustände
Hierfür werden die Zustände in ein neues Objekt (Array) eingelesen und anschließend zeilenweise ausgegeben.
const stateOutput = response => {
let counter = 0;
const arr = [];
// Einlesen der Zustände in neues Objekt
for (const state of response["states"]) {
arr.push(state)
}
...
if (document.getElementById("nextButton")) {
document.getElementById("nextButton").addEventListener("click", () => {
if (counter == 0) tableHeader(arr[counter])
if (counter < arr.length) {
// console.log(arr[counter])
nextStep(arr[counter])
if (counter == arr.length - 1 && arr[counter]["valid"]) {
alert("Der Automat akzeptiert den Ausdruck.")
} else if (counter == arr.length - 1 && !arr[counter]["valid"]) {
alert("Der Automat hat den Ausdruck nicht erkannt.")
}
counter += 1;
}
if (counter == arr.length) {
nextButton.setAttribute("disabled", "")
}
})
}
};
Zeilenweise Ausgabe der Automatenzustände
const nextStep = state => {
const outputTable = document.getElementById("transitions");
const tableRow = outputTable.insertRow();
for (const [key, value] of Object.entries(state)) {
if (key != "valid") {
const tableCell = tableRow.insertCell();
tableCell.appendChild(document.createTextNode(value))
tableRow.appendChild(tableCell)
}
}
outputTable.appendChild(tableRow)
};