Re: Artikel Debian

Der Code ist einigermassen weit gediehen, jetzt muss ich kurz weg - es ist ein kleiner Fehler, bei den Zuständen drin

/* 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') \&amp;\&amp; (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') \&amp;\&amp; (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') \&amp;\&amp; (ch <= 'z')) {
            tokenback ();
            j2 = term ();
        }
        state1 [j1] = j1;
        state2 [j1] = j2;
    }
    else if((ch >= 'a') \&amp;\&amp; (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') \&amp;\&amp; (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]);
    }
}