#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);
}