/media/sda-magnetic/david/Dok-15-2023-11-27/informatik/newC2023-10-23/c2023-10-23/reg705.c


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

#define X   1024
#define Y   1024
#define END -1

char statechar [Y][X];
char statelevel [Y][X];
int x;
int y;

int initstates () {
    int k, l;

    for (k = 0;  k < Y;  k++) {
        for (l = 0;  l < X;  l++) {
            statechar [k][l] = ' ';
        }
    }

}

int jx = 0;

char text [] = "abcebce";

//char expr [] = "abc*de[fasd,asddsr]qdsda*ghijk";
//char expr [] = "[*([[[([a,[[[p,q*],ca],[d,*(ead)]]]f*(mmm(nnn)mm)),a],asd],semdu]),*poller]";
//char expr [] = "[*([[[([a,[[[p,*(q)],ca],[d,*(ead)]]]f*(mmm(nnn)mm)),a],asd],semdu]),*poller]";
//char expr [] = "*(mmm(nnn)mm)";
char expr [] = "a*(b(ce))gg";
//char expr [] = "abcd";
int i = 0;

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

/*
aaaa
aaaaaa
aaaaaaa
aaaaaaaa()
*/

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

int or_operator (int l) {
    int ch;
    if ((ch = gettoken ()) == '[') {
        or_operator (l+1);

        if (gettoken () != ',') {
            fprintf (stderr, "Komma vergessen");
            exit (1);
        }
        statechar [y][x] = '$';
        statelevel [y][x] = l;
        x++;
        y++;
        or_operator (l+1);
        if ((ch = gettoken ()) != ']') {
            fprintf (stderr, "Klammer vergessen ]");
            exit (1);
        }
        repeat_operator (l);
    }
    else {
        tokenback ();
        repeat_operator (l);
    }

}


int repeat_operator (int l) {
    if (gettoken () == '*') {
        statechar [y][x] = '#';
        statelevel [y][x] = l;
        x++;
        stream (l);
    }
    else {
        tokenback ();
        stream (l);
    }

}

int stream (int l) {
    int r = 0;
    r = compound (l);
    r |= followed (l);
    if (r) {
        or_operator(l);
    }
}

int followed (int l) {
    int ch = gettoken ();
    int st, xtmp;
    if ((ch >= 'a') && (ch <= 'z')) {
        statechar [y][x] = ch;
        statelevel [y][x] = l;
        x = x+1;
        or_operator (l);
        return 1;
    }
    else {
        tokenback ();
        return 0;
    }
}

int compound (int l) {
    int ch;
    if (gettoken () == '(') {
        statechar [y][x] = '@';
        statelevel [y][x] = l;
        x++;
        y++;
        or_operator (l+1);
        if ((ch = gettoken ()) != ')') {
            fprintf (stderr, "fehler klammer vergessen %c %i\n", expr [i], i);
            exit (1);
        }
        return 1;
    }
    else {
        tokenback ();
        return 0;
    }
}

#define TRUE                    1
#define FALSE                   0

#define LOOPLABELXSTACK         0
#define LOOPLABELYSTACK         1
#define LOOPLABELENDXSTACK      2
#define LOOPLABELENDYSTACK      3
#define LOOPSUCCESSSTACK        4
#define LASTWASLABELSTACK       5
#define LEVELSTACK              6


#define LASTWASLOOPLABEL        0

int stacks [32][1024];
int stacksp [32];

void push (int stackid, int state) {
  stacks [stackid][stacksp[stackid]++] = state;
}

int pop (int stackid) {
  stacksp [stackid]--;
  return stacks [stackid][stacksp[stackid]];
}

int emptystack (int stackid) {
    return (stacksp[stackid] == 0);
}

void automat (int yi, int xi, int txti, int level) {
    int tmp1;

    for (;  txti < strlen (text);) {
        if (statechar [yi][xi] == text[txti]) {
            printf ("fits: %s\n", text +txti);
            xi++;
            txti++;
        }
        else if (statechar [yi][xi] == '@') {
            xi++;
            yi++;
            level++;
        }
        else if (statechar [yi][xi] == '#') {
            xi++;
            if (statechar [yi][xi] == '@') {
                push (LOOPLABELXSTACK, xi);
                push (LOOPLABELYSTACK, yi);
                push (LASTWASLABELSTACK, LASTWASLOOPLABEL);
                push (LOOPSUCCESSSTACK, FALSE);
                //push (LEVELSTACK, statelevel [yi][xi]);
                level = statelevel [yi][xi];
                yi++;
                xi++;
            }
        }
        else if ((statelevel [yi][xi] < level) && (statelevel [yi][xi+1] < statelevel [yi][xi+1])) {
            printf ("Hallo");
            getchar ();
            if (pop (LASTWASLABELSTACK) == LASTWASLOOPLABEL) {
                if (pop (LOOPSUCCESSSTACK) == FALSE) {
                    push (LOOPLABELENDXSTACK, xi);
                    push (LOOPLABELENDYSTACK, yi);
                    push (LOOPSUCCESSSTACK, TRUE);
                }
                xi = pop (LOOPLABELXSTACK);
                yi = pop (LOOPLABELYSTACK);
                push (LOOPLABELXSTACK, xi);
                push (LOOPLABELYSTACK, yi);
                push (LASTWASLABELSTACK, TRUE);
                push (LOOPSUCCESSSTACK, TRUE);
            }
        }
        else {
            if ((tmp1 = pop (LASTWASLABELSTACK)) == LASTWASLOOPLABEL) {
                if (pop (LOOPSUCCESSSTACK) == TRUE) {
                    xi = pop (LOOPLABELENDXSTACK);
                    yi = pop (LOOPLABELENDYSTACK);
                    pop (LOOPLABELXSTACK);
                    pop (LOOPLABELYSTACK);
                    pop (LASTWASLABELSTACK);
                    pop (LOOPSUCCESSSTACK);
                    level = statelevel [xi][yi];
                }
                else
                    break;

            }
        }
        printf ("level: %i\n", level);
    }

}

int main (void) {
    int k, l;
    initstates ();
    or_operator (0);

    for (l = 0;  l <= y;  l++) {
        for (k = 0;  k <= x;  k++)
            printf ("%2c%2i ", statechar [l][k], statelevel[l][k]);
        printf ("\n");
    }
    automat (0,0,0,0);
}