/* expr ::= term | term + expr
* term ::= factor | factor * term
* factor ::= id | (expr)
*
* expr ::= term | term '|' expr
* term ::= factor | factor '*' term
* factor ::= ch | (expr)
*
* Wie wir sehen werden f"uhrt das nicht zum Ziel. Die Grammatik geht anders
*
* 1.) m"usste nach dem * auch ein | kommen k"onnen. Zur Not setzt man Klammern
*
* Aber der | Operator ist infix. Und der wiederholungsoperator ist Postfix - und hat nur einen Operanden
*
* Das heisst:
*
* expr ::= term | term '|' expr
* term ::= factor | factor '*'
* factor ::= id | (expr)
*/
/*
#include <stdio.h>
#include <stdlib.h>
char gettoken ();
void tokenback ();
void expr ();
void factor ();
void term ();
char matchexpr [] = "(((acasdasd|b)*)|c)|p";
int i = 0;
char gettoken () {
return matchexpr [i++];
}
void tokenback () {
i--;
}
void expr () {
term ();
if (gettoken () == '|')
expr ();
else
tokenback ();
return;
}
*/
/* Das geht nicht
void term () {
factor ();
if (gettoken () == '*')
term ();
else
tokenback ();
return;
}
*/
/*
void term () {
char ch;
factor ();
if ((ch = gettoken ()) == '*');
else if((ch >= 'a') \&\& (ch <= 'z')) {
tokenback ();
term ();
}
else
tokenback ();
return;
}
void factor () {
char ch = gettoken ();
if (ch == '(') {
expr ();
if (gettoken () != ')') {
fprintf (stderr, "Geschlossene Klammer vergessen");
exit (1);
}
}
else if ((ch >= 'a') \&\& (ch <= 'z'))
printf ("%cn", ch);
else {
fprintf (stderr, "Falsches Zeichen %c", ch);
exit (1);
}
return;
}
int main (void) {
expr ();
}
*/
/*
*
* Jetzt kommt der Automat. Jetzt m"ussen wir nachdenken, ohne Robert Sedgewick
* a 0 -> 0
* aa 0 -> 0
* aaa 0 -> 0 -> 0
* aaaa 0 -> 0 -> 0 -> 0
* a(a|b) 0 -> 0
* 0 -> 1
*
* Also, das erste, was wir merken, die Zeichen sind nicht unsere Zust"ande - also 'a' entspricht nicht 0 und 'b' 1
*
* a(a|b)* 0 -> 0
* 0 -> 1
* 0 -> 0 -> 0
* 0 -> 1 -> 0
* 0 -> 0 -> 1
* 0 -> 1 -> 1
*
* Also, wenn man das hintereinander schreibt
*
* a(a|b)* Da ist mir das aufgefallen
*
* Sagen wir
* abc
* dann ist a nicht der Zustand, aber es steht an Index 0
* b steht an Index 1
* c an Index 2
* Gut, der Witz bei den Automaten, es kann der eine Zustand folgen, oder der anderen. Deswegen brauchen wir einen Automaten
* Das ist logisch. wenn ich 10 Zust"ande Folgezust"ande haben k"onnte, kann ich das nach der Baumregel, auf zwei Folgezust"ande reduzieren
*
* state1 [0] = 1
* state2 [0] = 1
* state1 [1] = 2
* state2 [1] = 2
* ...
*
* So w"are das bei einer Zeichenkette wie
*
* abc
*
* Jetzt angenommen ich habe ein ODER dann kommt
*
* state1 [5] = 1
* state2 [5] = 4
*
* Ich weiss wie es geht! Bingo!
*
* Es ist ganz einfach
*
* Ich habe die States
*
* state1 [...]
* state2 [...]
*
* daneben habe ich noch etwas. Ein Feld, was f"ur jeden Zustand angibt, was das f"ur ein Zeichen ist. Das ist was anderes. Also ein Feld
*
* statechar [...]
* Dann habe ich
*
* state1 [...]
* state2 [...]
* statechar [...]
*
* Jetzt muss ich mir merken
*
* "abcd"
*
* state1 [0] = 1
* state2 [0] = 1
* state1 [1] = 2
* state2 [1] = 2
* state1 [2] = 3
* state2 [2] = 3
* ...
*
* Nebenbei ist
*
* statechar [0] = 'a'
* ...
*
* Gut, das wichtige ist, bei ODER das hat nichts mit dem Zeichen zu tun
*
* Wenn da steht
* a(a|b)
*
* Dann folgt auf
* state1[0] = 1
* state2[0] = 2
*
* Bei einer Wiederholung folgt auf
*
* a*b
*
* state1 [0] = 0
* state2 [0] = 1
*
* Jetzt merken wir, die Grammatik ist Falsches
*
* Weil bei arithmetischen Ausdrucken, folgt auf Operand Operator Operand
* Und jetzt haben wir Operand Operand
*
* Dann f"uhren wir noch eine Regel eine
*
*
* expr ::= term | term '|' expr
* term ::= factor | factor term | factor*
* factor ::= id | (expr)
*
* Das hat mit dem Automaten nichts zu tun. Unabh"angig ob das eine Wiederholung oder ein ODER ist, tut der Automat
*
* Bei einer Wiederholung zeigt der Zustand auf sich selber. Bei einem ODER zeigt der Vorg"angezustand entweder auf den Einen Zustand oder den anderen. Das sind aber Folgezust"ande
*
* */
#include <stdio.h>
#include <stdlib.h>
char gettoken ();
void tokenback ();
int expr ();
int factor ();
int term ();
//char matchexpr [] = "(((acasdasd|b)*)|c)|p";
char matchexpr [] = "qbc|defg";
int i = 0;
int j = 0;
int state1 [128];
int state2 [128];
char statechar [1024];
char gettoken () {
return matchexpr [i++];
}
void tokenback () {
i--;
}
int expr () {
int j1, j2;
int t;
t = j;
j++;
j1 = term ();
if (gettoken () == '|') {
j2 = expr ();
state1 [t] = j1;
state2 [t] = j2;
}
else {
state1 [t] = j1;
state2 [t] = j1;
tokenback ();
}
return j1;
}
int term () {
char ch;
int j1, j2;
j1 = factor ();
if ((ch = gettoken ()) == '*') {
j2 = j1;
if((ch >= 'a') \&\& (ch <= 'z')) {
tokenback ();
j2 = term ();
}
state1 [j1] = j1;
state2 [j1] = j2;
}
else if((ch >= 'a') \&\& (ch <= 'z')) {
tokenback ();
j2 = term ();
state1 [j1] = j2;
state2 [j1] = j2;
}
else
tokenback ();
return j1;
}
int factor () {
char ch = gettoken ();
int j1;
if (ch == '(') {
j1 = expr ();
if (gettoken () != ')') {
fprintf (stderr, "Geschlossene Klammer vergessen");
exit (1);
}
}
else if ((ch >= 'a') \&\& (ch <= 'z')) {
statechar [j] = ch;
j1 = j;
j++;
printf ("%cn", ch);
}
else {
fprintf (stderr, "Falsches Zeichen %c", ch);
exit (1);
}
return j1;
}
int main (void) {
int k;
expr ();
for (k = 0; k < 24; k++) {
printf ("state1[%i] = %in", k, state1[k]);
printf ("state2[%i] = %in", k, state2[k]);
printf ("statechar[%i] = %cn", k, statechar[k]);
}
}