/media/sda-magnetic/david/Dok-15-2023-11-27/informatik/compilerbau/pattern-matching/1th-episode/reg16.c


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//char expr [] = "(a(((+bc(d))l+ll)de(faaa)))zzz";
char expr [] = "abc*de[f,g*]hijk";
int i = 0;
int j;
int state1 [1024];
int state2 [1024];
char statechar [1024];

char gettoken () {
    return expr [i++];
}
void tokenback () {
    i--;
}

/*
aaaa
aaaaaa
aaaaaaa
aaaaaaaa()
*/

int stream ();
int followed ();
int compound ();
int or_operator ();
int repeat_operator ();

int or_operator (int jin) {
    int j1, j2, j3;
    int t = j;
    
    if (gettoken () == '[') {
        j3 = j;
        j++;
        j1 = repeat_operator ();
        if (gettoken () != ',') {
            fprintf (stderr, "Komma vergessen");
            exit (1);
        }
        j2 = repeat_operator ();
        if (gettoken () != ']') {
            fprintf (stderr, "Klammer vergessen ]");
            exit (1);
        }
        state1 [j3] = j1;
        state2 [j3] = j2;
        statechar [j3] = '#';
        j3 = repeat_operator ();
        if (jin == -1)
            state1 [j1] = j3;
        else
            state1 [j1] = t;
        state2 [j1] = j3;
        if (jin == -1)
            state1 [j2] = j3;
        else
            state1 [j1] = t;
        state2 [j2] = j3;
    }
    else { 
        tokenback ();
        j3 = repeat_operator ();
    }
return j3;
}

int repeat_operator () {
    int j1;
    
    if (gettoken () == '*') {
        j1 = stream (j);
    }
    else { 
        tokenback ();
        j1 = stream (-1);
    }
return j1;
}

int stream (int jin) {
    compound ();
    return followed (jin);
}

int followed (int jin) {    
    int j1, j2;
    int t;
    
    int ch = gettoken ();
    if ((ch >= 'a') && (ch <= 'z')) {
        t = j;
        j++;
        if (jin == -1)
            j2 = j1 = or_operator (jin);
        else {
            j1 = or_operator (jin);
            j2 = t;
        }
        state1 [t] = j1;
        state2 [t] = j2;
        statechar [t] = ch;
    }
    else
        tokenback ();
return t;
}

int compound () {
    if (gettoken () == '(') {
        or_operator (-1);
        if (gettoken () != ')') {
            fprintf (stderr, "fehler klammer vergessen %c %i\n", expr [i], i);
            exit (1);
        }
    }
    else
        tokenback ();
}




int main (void) {
    int k;
    or_operator (-1);
    
    for (k = 0;  k < 24;  k++) {
        printf ("statechar [%i] = %c\n", k, statechar [k]);
        printf ("state1 [%i] = %i\n", k, state1 [k]);
        printf ("state2 [%i] = %i\n", k, state2 [k]);
    }
    
}