Re: Artikel Debian

Ich habe hier eine neue Grammatikableitung, die ist richtiger, lassen sie sich nicht imponieren - dass ich expr, term, factor verwende. Ich wusste nicht, wie ich sie sonst nennen soll, hat mit arithmetischen Ausdrücken nichts zu tun. Ich habe ein Regel hinzugefügt chr

https://www.davidvajda.de/viewtopic.php?p=1184#p1184">

/* 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 ();


char matchexpr [] = "((((acasdasd|b)*)|c)|p)|l";
//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--;
}

/* Das einfachste: Auf zeichen folgt Zeichen
 *
 *
 * chr ::= ch | ch chr
 * a
 * aa
 * aaa
 *
 * chr ::= rpt | rpt chr
 * rpt ::= ch | *ch
 *
 * chr ::= sel | sel chr
 * sel ::= rpt | + rpt sel // + rpt rpt
 * rpt ::= ch | *ch
 * ch  ::= id | (chr)
 *
 * chr ::= sel | sel chr
 * sel ::= rpt | rpt + sel // + rpt rpt
 * rpt ::= ch | ch*
 * ch  ::= id | (chr)
 *
 * chr      ::= expr | expr chr
 * expr     ::= term | term '|' expr
 * term     ::= factor | factor*
 * factor   ::= id | (expr)

 * chr      ::= expr | expr chr
 * expr     ::= term | term '|' term
 * term     ::= factor | factor*
 * factor   ::= id | (expr)
 * */

int chr ();
int expr ();
int term ();
int factor ();

int chr () {
    int ch;
    expr ();
    ch = gettoken ();
    if ((ch >= 'a') \&amp;\&amp; (ch <= 'z')) {
        tokenback ();
        chr ();
    }
    else
        tokenback();
}

int expr () {
    term ();
    if (gettoken () == '|')
        term ();
    else
        tokenback ();
}

int term () {
    factor ();
    if (gettoken () == '*');
    else
        tokenback ();
}

int factor () {
    int ch = gettoken ();
    if (ch == '(') {
        chr ();
        if (gettoken () != ')') {
            printf ("Klammer schliessen vergessen");
            exit (1);
        }
    }
    else if ((ch >= 'a') | (ch <= 'z'))
        printf ("%cn", ch);
    else {
        printf ("Unbekanntes Zeichen");
        exit (1);
    }
}


int main (void) {
    int k;
    chr ();

}