Re: Neuer Automaten Generator

Ich habe für sie noch ein Beispiel, ich habe ja jetzt den Automaten Generator geschrieben und vor allem für mich. Ich mache heute noch eine Aufgabe. Wie man Zustandsdiagramme mit LaTeX, LaTeX kenne ich gut, habe ich bei der Fernuni Hagen erfahren

Ich mache heute eines. Aber ich habe ja einen ASM-Diagramm Generator geschrieben. Für Schaltwerke. Die mit Operationswerken arbeiten. Bei der Fernuni Hagen, steht auch LaTeX Quelltext, zum Schreiben von ASM-Diagrammen

Ich kann meinen Generator nehmen und ASM-Diagramme erzeugen lassen. Damit es besser aussieht.

Jetzt zum ASM-Diagramm. Da steht

begin{tikzpicture}[%
    >=triangle 60,              % Aussehen der Pfeile
    start chain=going below,    % Richtung von oben nach unten
    node distance=6mm and 60mm, % Abst"ande der Boxen
    every join/.style={norm},
    ]
    tikzset{% Boxen und Koordinaten
  base/.style={draw, on chain, on grid, align=center, minimum height=4ex},
  zbox/.style={base, rectangle, text width=8em},
  ebox/.style={base, diamond, aspect=1.5, text width=4em},
  term/.style={zbox, rounded corners},
  norm/.style={->, draw},
  coord/.style={coordinate, on chain, on grid, node distance=6mm and 25mm}}

% Zustand 0, Box und Zustandsname
 node [zbox] (z0) {Zuweisungen in \$Z_0\$};
 node [above=0mm of z0, text width=8em] {\$Z_0\$};

% Zustand 1, Box und Zustandsname
 node [zbox, join] (z1) {Zuweisungen in \$Z_0\$};
 node [above=0mm of z1, text width=8em] {\$Z_1\$};

% Entscheidungsbox
 node [ebox, join] (e1) {Ent-\scheidungs- box};

% Zustand 2, Box und Zustandsname
 node [term, below=of e1.west, yshift=-4em] (z2) {bedingte Ausgangsbox};
 node [above=0mm of z2, text width=8em]{};

% JA - Pfad aus der E-Box zu Z2
 path (e1.west) to node [near start, xshift=-1em] {\$1\$} (z2);
  draw [->] (e1.west) -- (z2);

% Zustand 3, Box und Zustandsname
 node [zbox, right =of z0] (z3) {Zuweisungen in \$Z_3\$};
 node [above=0mm of z3, text width=8em] {\$Z_3\$};

% NEIN- Pfad aus der E-Box zu Z3
path (e1.east) to node [very near start] {\$0\$} (z3);
node[coord, right = of e1, xshift=1em] (coord1) {};
%fill (coord1) circle (2pt);
node[coord, above = of z3, yshift=2em] (coord2) {};
%fill (coord2) circle (2pt) {};
draw[->] (e1.east) -- (coord1) |- (coord2) -- (z3.north);


end{tikzpicture}
Eigentlich soll man das nicht veröffentlichen. Es sieht einfach aus. Warum?

Sie haben halt einen Knoten - der

node [...]
[code]

Der hat einen Namen.

Der Name steht so da

[code]
node [] (z3)
[code]

Das ist allerdings nicht der Name der angezeigt wird. Der Name schreibt man so

[code]
 node [zbox, right =of z0] (z3) {Zuweisungen in \$Z_3\$};

Die Verbindungen schaffen wir so:

draw[->] (e1.east) -- (coord1) |- (coord2) -- (z3.north);

Jetzt müssen wir nur eines machen. Ich nehme mein altes Programm. Und ich muss es selber mal durchschauen. Anstatt meiner Ausgabe, muss es diese Knoten diese Knoten erzeugen und sinnvoll füllen.

ASM-Parser heisst mein Diagramm

/*
Grammatik

Sporadische Sammlung
- Zuweisung
- Addition
if
- Vergleiche
    - <=, >=, ==, !=, <, >
- Subtraktion
- Shift
    << >>
- Null setzen

Operationen
    - Mathematische:
        + (Addition)
        - (Subtraktion)
    - Verschieben
        >> Rechtsshift
        << Linksshift
    - 0 setzen
Vergleiche
    - <=, >=, ==, !=, <, >
Zuweisung
    <-

Zeichensatz: Variablen, Register, Operatoren und Konstante Werte

Operand ::= <Register> | <Const>
CMP ::= <= | >= | == | != | < | >
MathOperator ::= + | - | << | >>
BitBooleanOperator ::= '\&amp;\&amp;' | '||' | '!'
Operator ::= <MathOperator> | <BitBooleanOperator>
Expr ::= <Register> <- <Operand> | <Operand> <Operator> <Operand> | 0
Condition ::= IF <Register> <CMP> <Operand> THEN <Program> FI

Programm ::= <Expr> | <Condition> <Program>
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define     MAX_STATES                              1024
#define     MAX_EXPR_CONST_VAL                      128
#define     MAX_EXPR_REG_VAL                        4
#define     FIRST_REG_VAL                           'a'
#define     MAX_EXPR_OPERATOR_VAL                   6
#define     MAX_EXPR_CMP_OPERATOR_VAL               5
#define     RAND_OPERAND_CONST_REGISTER             2
#define     RAND_EXPR_OPERATOR_OPERAND_FOLLOW       2
#define     RAND_COND_TRUE_FALSE_DESICION           2
#define     RAND_PROGRAM_COND_EXPR_DESICION         4
#define     IF_ELSE_DEPTH                           3
#define     STD_PROGRAM_N                           6
#define     STD_PROGRAM2_N                          4
#define     RAND_COND_END_OR_GO_ON                  3

FILE *fout = NULL;

int line = 0;
int nline = 1;
int maxstate = 0;

char *opstr [] = {"+", "-", "<<", ">>", "\&amp;\&amp;", "||", "!"};
char *cmpstr [] = {"<=", ">=", "==", "!=", "<", ">"};

void operator (void);
void cmp (void);
void operand (void);
void expr (int);
void condition (int, int, int, int);
void condition2 (int, int, int, int);
void program (int, int, int, int);
void program2 (int, int, int, int);
void registr (void);
void cnst (void);
void operator (void);
void printemptyspace (int);

void printemptyspace (int n) {
    int i;

    for (i = 0;  i < n*2;  i++)
        fprintf (fout, " ");
}


void registr (void) {
    fprintf (fout, " %c ", (rand () % MAX_EXPR_REG_VAL) + FIRST_REG_VAL);
return;
}

void cnst (void) {
    fprintf (fout, " %i ", rand () % MAX_EXPR_CONST_VAL);
return;
}

void operator (void) {
    fprintf (fout, " %s ", opstr [rand () % MAX_EXPR_OPERATOR_VAL]);
return;
}

void cmp (void) {
    fprintf (fout, " %s ", cmpstr [rand () % MAX_EXPR_CMP_OPERATOR_VAL]);
return;
}

void operand (void) {
    if ((rand () % RAND_OPERAND_CONST_REGISTER) == 0)
        cnst ();
    else
        registr ();
return;
}

void expr (int emptyspacen) {
    fprintf (fout, "%4i:", line++);
    printemptyspace (emptyspacen);
    registr ();
    fprintf (fout, " <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    fprintf (fout, "n");
return;
}

void condition (int n, int i, int emptyspacen, int depth) {
    int goto1or2;

    fprintf (fout, "%4i:", line++);
    printemptyspace (emptyspacen);
    fprintf (fout, " IF ", line);
    registr ();
    cmp ();
    operand ();
    fprintf (fout, " THEN n", line);
    program (n, i+1, emptyspacen+1, depth+1);
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen+1);
    fprintf (fout, "      %4cn", ' ');
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen);
    fprintf (fout, " ELSE n", line);
    program (n, i+1, emptyspacen+1, depth+1);
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen+1);
    fprintf (fout, "      %4cn", ' ');
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen);
    fprintf (fout, " FI n", ' ');
return;
}


void condition2 (int n, int i, int emptyspacen, int depth) {
    int goto1or2;


    fprintf (fout, "%4i:", line++);
    printemptyspace (emptyspacen);
    fprintf (fout, " IF ", line);
    registr ();
    cmp ();
    operand ();
    fprintf (fout, " THEN n", line);
    program2 (n, i+1, emptyspacen+1, depth+1);
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen+1);
    fprintf (fout, " GOTO %in", rand () % nline);
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen);
    fprintf (fout, " ELSE n", line);
    program2 (n, i+1, emptyspacen+1, depth+1);
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen+1);
    fprintf (fout, " GOTO %in", rand () % nline);
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen);
    fprintf (fout, " FI n", ' ');
return;
}


void program2 (int n, int i, int emptyspacen, int depth) {
    if (((rand () % RAND_PROGRAM_COND_EXPR_DESICION) == 0))
        expr (emptyspacen);
    if (i < n) {
        program2 (n, i+1, emptyspacen, depth);
    }
return;
}

void program (int n, int i, int emptyspacen, int depth) {
    program2 (STD_PROGRAM2_N, 0, emptyspacen, depth);
    if ((rand () % RAND_COND_END_OR_GO_ON) == 0)
        condition2 (n, i+1, emptyspacen, depth+1);
    else if ((i < n) \&amp;\&amp; (depth < IF_ELSE_DEPTH))
        condition (n, i+1, emptyspacen, depth+1);
    else {
        fprintf (fout, "%4c ", ' ');
        printemptyspace (emptyspacen);
        fprintf (fout, " GOTO %in", rand () % nline);
        return;
    }
}



int main (void) {
    time_t t;
    int j;
    srand (t = time(NULL));
    fout = stderr;
    program (STD_PROGRAM_N, 0, 0, 0);
    maxstate = line;
    srand (t);
    fout = stdout;
    nline = line;
    line = 0;
    program (STD_PROGRAM_N, 0, 0, 0);
return 0;
}

Ich habe bei mir diese

fprintf (fout, " GOTO %in", rand () % nline);

Anstatt diesen

GOTO

Muss ich hier die Verbindungslinie zeichnen.

Jetzt muss ich mir kurz in Ruhe mein eigenes Programm angucken und dann sehen wie ich das stett dieser

fprintf

Ausgabe so fülle, dass halt das ASM-Diagramm daher kommt

Ich könnte mein Programm jetzt stückweise bearbeiten.

Wenn man die

CONDITION

sieht, erzeugt das ein

IF THEN ELSE

Das heisst, eine Entscheidungsbox, und das eine geht

JA

Das andere

NEIN

Da müsste man nachher die Pfade zu den Zuständen machen. Man könnte jetzt mit der Entscheidungsbox anfangen.

void condition (int n, int i, int emptyspacen, int depth) {
    int goto1or2;

    fprintf (fout, "%4i:", line++);
    printemptyspace (emptyspacen);
    fprintf (fout, " IF ", line);
    registr ();
    cmp ();
    operand ();
    fprintf (fout, " THEN n", line);
    program (n, i+1, emptyspacen+1, depth+1);
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen+1);
    fprintf (fout, "      %4cn", ' ');
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen);
    fprintf (fout, " ELSE n", line);
    program (n, i+1, emptyspacen+1, depth+1);
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen+1);
    fprintf (fout, "      %4cn", ' ');
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen);
    fprintf (fout, " FI n", ' ');
return;
}

Ich fange mit den Zuständen an

Das heisst, ich generiere, ein unvollständiges ASM-Diagramm. Das erzeugt zunächst nur die Zustände und ich sehe, ob es so weit richtig ist.

Ich glaube in dem Fall kann man es einfacher machen. Mein Programm hat ja geschachtelte Anweisungen erzeugt, damit die richtig stehen. Jetzt muss man einfach Querbet, Zustände und Entscheidungsboxen erzeugen und nachher, diese miteinander verbinden. Das ist kein Problem, das geht einfacher. Ich habe gerade eine Ausgabe erzeugt, aber die hat einen Nachteil. In der Ausgabe der Entscheidungsbox, steht wieder eine Entscheidungsbox, das ist nicht das Ziell.

Ich habe das schon mal ganz gut hingekriegt. Die Ausgabe ist jetzt besser. Und zwar ohne Schachtelung

Semantisch macht das Programm keinen Spass. Das sehen sie selber

Aber, es gäbe eine Möglichkeit. Man könnte Ausdrücke erzeugen.

Solche

a := ((a and b) or c) and d

Gut, was haben wir gewonnen. Sie könnten daraus machen - echte Datenabhängigkeit. Das ergibt sogar einen heimlichen Sinn. Weil, sie können mit einem ASM Diagramme - keine Ausdrücke komplett arbeiten

Sowohl in Assembler, als auch bei Hardware Algorirhtmen. Würden inzwischen Zuweisungen statt finden und - es werden die Ausdrücke teilweise bearbeitet. Das heisst sie machen das einfach so

a := ((a and b) or c) and d

r0 := a and b
r1 := r0 or c
r2 := r1 and d

a := ((a and b) or c) and d

r0 := a and b
r1 := r0 or c
r2 := r1 and d

Der ist so überhaupt nicht dumm. Im Gegenteil. Weil es nicht anders geht. Ein ASM-Diagramm es nicht anders

a := ((a and b) or c) and d

Damit ist der Algorithmus bedient worden und es lässt sich so einfach vollziehen, ohne Kopfzerbrechen, lässt ich das Programmieren. Ich erkläre gleich wie. Sie brauchen blos

expr ::= term + expr  | term
term ::= factor * term | factor
factor ::= (expr) | id

Dann erzeugen sie statt

>+
und so weiter. Und anstatt den Ausdruck so hin zu schreiben

Erzeugen sie ein Register. der Witz ist, das ist nicht mal unsinn Natürlich sind das nicht alle Algorithmen aller ASM-Diagramme

Und beinahe schon. Man denke an eine Multiplikation

A*B

Dabei würden sie A B mal nach oben zählen. das komische ist, dass das

A+A+A+...+A

Das komische ist - dass das - und jetzt denken sie nach 2 Sekunden, denken sie nach.

Also

2+2+2+2
=
(((2+2)+2)+2)

Also, was haben wir mit unserem Ausdruck geschaffen???

das heisst, was wir damit erschaffen haben

a := ((a and b) or c) and d

r0 := a and b
r1 := r0 or c
r2 := r1 and d

ist allgemeingültig. Das heisst, es definiert nur eines. Gültige ASM-Diagramme. Also die gültig sind. Und noch lustiger - es definiert die Menge aller Gültigen ASM-Diagramme überhaupt. Würde ich Pi Mal Daumen sagen

Und das Lustige. Wir können Ausdrücke der Form

a := ((a and b) or c) and d
(((2+2)+2)+2)

Im ASM-Diagramm nicht anders hinschreiben, als so

r0 := a and b
r1 := r0 or c
r2 := r1 and d

Weil wir haben die echte Datenabhängigkeit. was wie ein Verhängnis aussieht, ist keines.. weil es das wäre, wäre nichts mehr zu tun. Jeder Ausdruck der Informatik wir darauf zurückgeführt, weil nur so löst der Computer seine Probleme

Na ja, wenn wir pech haben, wir die Schleife niemals aufhören, die Bedingung nie erfüllt sein

Jetzt müssen wir nur einen Fehler korrigieren. Bisher tut unser ASM-Diagramm, ich stelle mal den Code vor, was komisches

/*
Grammatik

Sporadische Sammlung
- Zuweisung
- Addition
if
- Vergleiche
    - <=, >=, ==, !=, <, >
- Subtraktion
- Shift
    << >>
- Null setzen

Operationen
    - Mathematische:
        + (Addition)
        - (Subtraktion)
    - Verschieben
        >> Rechtsshift
        << Linksshift
    - 0 setzen
Vergleiche
    - <=, >=, ==, !=, <, >
Zuweisung
    <-

Zeichensatz: Variablen, Register, Operatoren und Konstante Werte

Operand ::= <Register> | <Const>
CMP ::= <= | >= | == | != | < | >
MathOperator ::= + | - | << | >>
BitBooleanOperator ::= '\&amp;\&amp;' | '||' | '!'
Operator ::= <MathOperator> | <BitBooleanOperator>
Expr ::= <Register> <- <Operand> | <Operand> <Operator> <Operand> | 0
Condition ::= IF <Register> <CMP> <Operand> THEN <Program> FI

Programm ::= <Expr> | <Condition> <Program>
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define     MAX_STATES                              1024
#define     MAX_EXPR_CONST_VAL                      128
#define     MAX_EXPR_REG_VAL                        4
#define     FIRST_REG_VAL                           'a'
#define     MAX_EXPR_OPERATOR_VAL                   6
#define     MAX_EXPR_CMP_OPERATOR_VAL               5
#define     RAND_OPERAND_CONST_REGISTER             2
#define     RAND_EXPR_OPERATOR_OPERAND_FOLLOW       2
#define     RAND_COND_TRUE_FALSE_DESICION           2
#define     RAND_PROGRAM_COND_EXPR_DESICION         4
#define     IF_ELSE_DEPTH                           3
#define     STD_PROGRAM_N                           6
#define     STD_PROGRAM2_N                          4
#define     RAND_COND_END_OR_GO_ON                  3

FILE *fout = NULL;

int line = 0;
int nline = 1;
int maxstate = 0;

char *opstr [] = {"+", "-", "<<", ">>", "\&amp;\&amp;", "||", "!"};
char *cmpstr [] = {"<=", ">=", "==", "!=", "<", ">"};

void operator (void);
void cmp (void);
void operand (void);
void expr (int);
void condition (int);
void program (int, int, int, int);
void program2 (int, int, int, int);
void registr (void);
void cnst (void);
void operator (void);
void printemptyspace (int);


void registr (void) {
    printf (" %c ", (rand () % MAX_EXPR_REG_VAL) + FIRST_REG_VAL);
return;
}

void cnst (void) {
    printf (" %i ", rand () % MAX_EXPR_CONST_VAL);
return;
}

void operator (void) {
    printf (" %s ", opstr [rand () % MAX_EXPR_OPERATOR_VAL]);
return;
}

void cmp (void) {
    printf (" %s ", cmpstr [rand () % MAX_EXPR_CMP_OPERATOR_VAL]);
return;
}

void operand (void) {
    if ((rand () % RAND_OPERAND_CONST_REGISTER) == 0)
        cnst ();
    else
        registr ();
return;
}

void expr (int z) {
    printf BITTE IM PDF NACHGUCKEN
    registr ();
    printf (" <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    printf (""};n");
return;
}

void condition (int z) {
    printf BITTE IM PDF NACHGUCKEN
    operand ();
    cmp ();
    operand ();
    printf (""};n");
}







int main (void) {
    time_t t;
    int j;
    srand (t = time(NULL));

    for (j = 0;  j < rand () % 20;  j++) {
        if ((rand () % 4) < 3)
            expr (j);
        else
            condition (j);
    }

return 0;

}

Das sieht aus wie linear. Jetzt brauchen wir doch die Rekursion. Also, nachher werden wir den Ausdruck so und so abarbeiten. Das geht relativ simpel. Mal abgesehen, dass der Ausdruck zufall ist, haben wir nicht das Problem, wie viele Zustände wir erzeugen müssen. Weil der Ausdruck abgearbeitet wird

Dazwischen erzeugen wir irgendwelche Entscheidungen. In dem Falle ist uns das egal, was drin steht. Wir nehmen Konstanten.

Und - jetzt der Witz - jetzt haben wir ein Problem, weil das Linear aussieht. Das ist aber schnell gelöst

Weil, die Entscheidungsbox hat eine Linke Seite und eine Rechte. Wie machen wir das? Müssen wir nachrechnen, nein, müssen wir nicht

Weil, wir müssen nur

yshift=-4em // bei y
xshift=+/- 4em //bei x

Jetzt brauchen wir doch eine Rekursion. Leider brauchen wir eine. Aber das ist easy. Wenn eine Entscheidungsbox kommt, müssen rekursiv einen Pfad nach rechts und einen links machen. Damit die nicht kollidieren. Weil es kann an der einen Seite runter gehen und inzwischen kommt eine. Da müssen wir aufpassen. Aber gucken wir erst Mal

Damit die nicht kollidierne, machen wir das ganz einfach

Wir erzeugen einen Baum. Das ist nicht so easy - wenn wir die Koordinaten machen, selber, aber es ist ganz einfach, wenn wir nur die relativen Abstände angeben müssen. Der Witz ist, wir erzeugen einen Baum. ab einem Level ist schluss. Automatisch

Das würde sonst bedeuten - 100 Boxen nebeneinander, die würden kollidieren

Also machen wir -

>50%\end{verbatim} die eine Seite und die andere in die andere Richtung. Jede andere Verzweigung wird ebenso halbiert

Fertig. Jetzt w"urden sie fragen, das ist was anderes - eine anedre Rekursion. Unser Ausdruck ist nachher nicht feritg

Stimmt nicht, wir haben ja mit unseren Entscheidungsboxen gemogelt. Die ergeben ja keinen Sinn. Wir m"ussen die gar nicht einf"uhren. das heisst, wir machen irgendwann einfach Schluss mit Entscheidungsboxen.

das Problem l"asst sich schnell erledigen

\begin{verbatim}
void asm (int z, int xpos, int diff) {
    if ((rand () % 4) < 3) {
        z = cond (z+1, xpos);
        z = asm (z, xpos+diff, diff/2);
        z = asm (z, xpos-diff, diff/2);
    }
    else {
        expr (z, xpos);
        asm (z+1, xpos, diff)
    }

}

Ungefähr so. Ich muss es testen. Danach können wir zum Ausdruck übergehen.

Das hat es jetzt erzeugt, hat perfekt funktioniert

node [zbox] (z1) {verb" a  <-  118 "};
node [zbox] (z2) {verb" a  <-  a "};
node [ebox] (z3) {verb" a  !=  90 "};
node [zbox, below=of z3.west, yshift=-4em] (z4) {verb" b  <-  c  >>  c "};
node [zbox, below=of z3.east, yshift=-4em] (z5) {verb" b  <-  15  \&amp;\&amp;  40 "};
node [zbox] (z6) {verb" a  <-  b "};
node [zbox] (z7) {verb" b  <-  34 "};
node [zbox] (z8) {verb" a  <-  a  <<  60 "};
node [ebox] (z9) {verb" b  !=  d "};
node [zbox, below=of z9.west, yshift=-4em] (z10) {verb" d  <-  3  \&amp;\&amp;  b "};
node [ebox] (z11) {verb" 66  >=  a "};
node [ebox, below=of z11.west, yshift=-4em] (z12) {verb" d  !=  c "};
node [zbox, below=of z12.east, yshift=-4em] (z13) {verb" c  <-  8 "};
node [zbox] (z14) {verb" b  <-  b  ||  46 "};
node [zbox] (z15) {verb" a  <-  a "};
node [ebox] (z16) {verb" 84  !=  a "};
node [zbox, below=of z16.east, yshift=-4em] (z17) {verb" d  <-  18 "};
node [zbox, below=of z9.east, yshift=-4em] (z11) {verb" b  <-  82 "};

Ich habe das angepasst

begin{tikzpicture}[%
    >=triangle 60,              % Aussehen der Pfeile
    start chain=going below,    % Richtung von oben nach unten
    node distance=6mm and 60mm, % Abst"ande der Boxen
    every join/.style={norm},
    ]
    tikzset{% Boxen und Koordinaten
  base/.style={draw, on chain, on grid, align=center, minimum height=4ex},
  zbox/.style={base, rectangle, text width=8em},
  ebox/.style={base, diamond, aspect=1.5, text width=10em},
  term/.style={zbox, rounded corners},
  norm/.style={->, draw},
  coord/.style={coordinate, on chain, on grid, node distance=6mm and 25mm}}

% Zustand 0, Box und Zustandsname\end{verbatim}

\includegraphics[width=\textwidth]{./david4/2024-01-27/main3.jpg}

Es funktioniert jetzt so perfekt

\begin{verbatim}
...

#define NO      0
#define WEST    1
#define EAST    2

int expr (int z, int zs, int dir) {
    if (dir == NO)
        printf BITTE IM PDF NACHGUCKEN
    else if (dir == WEST)
        printf BITTE IM PDF NACHGUCKEN
    else if (dir == EAST)
        printf BITTE IM PDF NACHGUCKEN

    registr ();
    printf (" <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    printf (""};n");
return z;
}

int cond (int z, int zs, int dir) {
    if (dir == NO)
        printf BITTE IM PDF NACHGUCKEN
    else if (dir == WEST)
        printf BITTE IM PDF NACHGUCKEN
    else if (dir == EAST)
        printf BITTE IM PDF NACHGUCKEN

    //printf BITTE IM PDF NACHGUCKEN
    operand ();
    cmp ();
    operand ();
    printf (""};n");
    return z;
}

int as (int z, int zs, int dir) {
    int ztmp;
    int r;
    if ((r = (rand () % 8)) < 2) {
        z = ztmp = cond (z+1, zs, dir);
        z = expr (z+1, ztmp, WEST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);
        z = expr (z+1, ztmp, EAST);
        z = expr (z+1, z, NO);

        z = as (z, z, NO);

    }
    else if ((r >= 2) \&amp;\&amp; (r <= 5)) {
        z = expr (z+1, zs, dir);
        as (z, zs, NO);
    }
return z;
}



...

Ich habe einen Unterschied gemacht, hinter die Entscheidungsbox, müssen eine bestimmte Menge an zustännden folgen.

Image main4

Funktioniert perfekt

Image main5

Ich habe immer noch das Problem, dass bei zu viel Entscheidungsboxen, die anecken

Ich löse das Problem damit, dass es maximal 2 oder 3 Entscheidungsboxen gibt.

Es muss eh nicht mehr geben

Jetzt kommen die Connections

Wenn das geschehen ist, der Algorithmus

Jetzt kann ich ausdrücke erzeugen, wie

(2+3)*4

Und die in Register umwandeln

Das ist Unsinn. Ich erzeuge gleich Ausdrücke, dabei werden Register als echte Register gewählt und bei den späteren Ausdrücken, muss echte Datenabhängigkeit erzeugt werden. Oder es darf maximal eine Konstante auftauchen. Und das Problem ist gelöst.

Die Länge des Ausdrucks lässt sich aber auf eine feste Länge einstellen, quasi.

Die Entscheidungsbox sollte sich nur auf die letzte Datenabhängigkeit beziehen. Man kann da schon was machen. Also, was gar keinen Sinn macht, ist am Anfang einen Wert zu berechnen. Und dann folgen Datenabhängigkeiten und die Bedingung bezieht sich auf das erste

Dann lassen sich Testreihen entwickeln. Damit die Abfrage nicht ganz dumm ist. Könnte das Programm die Berechnung vollziehen. Indem es die register belegt und - dann könnten Werte eingesetzt werden. Die Schleife durchlaufen werden. 3x zum Beispiel und was dann für ein Wert raus kommt, könnte auf das letzte Register bezogen, in die Abfrage kommen.

Ich lösche mal die dummen Inhalte hier.

Sorry, nicht aufregen über die Signatur in den Bildern. Ich habe die mit Office schnell konvertiert. Schneller geht es über die Konsole. Besonders mit

convert

Aber, wenn sie Linux benutzen oder nicht - dann müssen sie, bei

 nicht mit PDF

Es gibt die andere alternative, die ich sonst nicht benutze, die geht so

\begin{verbatim}
pdftoppm -jpeg test.pdf test.jpeg

Ich konvertiere jetzt zwei Dateien. Die Verbindungen waren erfolgreich. beim ersten war noch ein Fehler drin, ich zeige es trotzdem. Da war kein gravierender Fehler, aber eine Connection ging durch einen Zustand, beim zweiten geht es

Und gut, dann wäre der Teil erledigt. Hoffentlich

Image main.jpeg-1

So, ich habe die Fehlerhafte Datei leider schon gelöscht, dafür habe ich ein besseres Beispiel, das sieht eh besser aus

Image main.jpeg-2

Und hier der Code.

Das ist die TeX Datei, die muss allerdings in ein weitere TeX Dokument eingebunden werden

begin{tikzpicture}[%
    >=triangle 60,              % Aussehen der Pfeile
    start chain=going below,    % Richtung von oben nach unten
    node distance=6mm and 60mm, % Abst"ande der Boxen
    every join/.style={norm},
    ]
    tikzset{% Boxen und Koordinaten
  base/.style={draw, on chain, on grid, align=center, minimum height=4ex},
  zbox/.style={base, rectangle, text width=8em},
  ebox/.style={base, diamond, aspect=1.5, text width=10em},
  term/.style={zbox, rounded corners},
  norm/.style={->, draw},
  coord/.style={coordinate, on chain, on grid, node distance=6mm and 25mm}}

% Zustand 0, Box und Zustandsname
node [zbox] (z0) {verb" a  <-  d  >>  75 "};
node [ebox] (z1) {verb" 52  >=  a "};
draw [->] (z0) -- (z1);;node [zbox, below=of z1.west, yshift=-4em] (z2) {verb" b  <-  d  -  11 "};
draw [->] (z1.west) -- (z2);;node [zbox] (z3) {verb" b  <-  44 "};
draw [->] (z2) -- (z3);;node [zbox] (z4) {verb" b  <-  c  +  17 "};
draw [->] (z3) -- (z4);;node [ebox] (z5) {verb" d  <  d "};
draw [->] (z4) -- (z5);;node [zbox, below=of z5.west, yshift=-4em] (z6) {verb" b  <-  103  ||  d "};
draw [->] (z5.west) -- (z6);;node [zbox] (z7) {verb" c  <-  d  -  51 "};
draw [->] (z6) -- (z7);;node [zbox] (z8) {verb" c  <-  88 "};
draw [->] (z7) -- (z8);;node [ebox] (z9) {verb" 88  ==  b "};
draw [->] (z8) -- (z9);;node [zbox, below=of z9.west, yshift=-4em] (z10) {verb" c  <-  80  <<  a "};
draw [->] (z9.west) -- (z10);;node [zbox] (z11) {verb" a  <-  c "};
draw [->] (z10) -- (z11);;node [zbox, below=of z9.east, yshift=-4em] (z12) {verb" b  <-  b  -  86 "};
draw [->] (z9.east) -- (z12);;node [zbox] (z13) {verb" c  <-  b  -  70 "};
draw [->] (z12) -- (z13);;node [zbox] (z14) {verb" a  <-  d "};
draw [->] (z13) -- (z14);;node [zbox] (z15) {verb" b  <-  12 "};
draw [->] (z14) -- (z15);;node [zbox] (z16) {verb" a  <-  a  \&amp;\&amp;  d "};
draw [->] (z15) -- (z16);;node [zbox] (z17) {verb" a  <-  b "};
draw [->] (z16) -- (z17);;node [zbox, below=of z5.east, yshift=-4em] (z9) {verb" a  <-  11  +  c "};
draw [->] (z5.east) -- (z9);;node [zbox] (z10) {verb" c  <-  30 "};
draw [->] (z9) -- (z10);;node [zbox] (z11) {verb" a  <-  87  <<  b "};
draw [->] (z10) -- (z11);;node [zbox] (z12) {verb" b  <-  c  ||  77 "};
draw [->] (z11) -- (z12);;node [zbox, below=of z1.east, yshift=-4em] (z5) {verb" b  <-  20 "};
draw [->] (z1.east) -- (z5);;node [zbox] (z6) {verb" a  <-  c  -  120 "};
draw [->] (z5) -- (z6);;d
end{tikzpicture}

Und hier, der C-Code

/*
Grammatik

Sporadische Sammlung
- Zuweisung
- Addition
if
- Vergleiche
    - <=, >=, ==, !=, <, >
- Subtraktion
- Shift
    << >>
- Null setzen

Operationen
    - Mathematische:
        + (Addition)
        - (Subtraktion)
    - Verschieben
        >> Rechtsshift
        << Linksshift
    - 0 setzen
Vergleiche
    - <=, >=, ==, !=, <, >
Zuweisung
    <-

Zeichensatz: Variablen, Register, Operatoren und Konstante Werte

Operand ::= <Register> | <Const>
CMP ::= <= | >= | == | != | < | >
MathOperator ::= + | - | << | >>
BitBooleanOperator ::= '\&amp;\&amp;' | '||' | '!'
Operator ::= <MathOperator> | <BitBooleanOperator>
Expr ::= <Register> <- <Operand> | <Operand> <Operator> <Operand> | 0
Condition ::= IF <Register> <CMP> <Operand> THEN <Program> FI

Programm ::= <Expr> | <Condition> <Program>
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define     MAX_STATES                              1024
#define     MAX_EXPR_CONST_VAL                      128
#define     MAX_EXPR_REG_VAL                        4
#define     FIRST_REG_VAL                           'a'
#define     MAX_EXPR_OPERATOR_VAL                   6
#define     MAX_EXPR_CMP_OPERATOR_VAL               5
#define     RAND_OPERAND_CONST_REGISTER             2
#define     RAND_EXPR_OPERATOR_OPERAND_FOLLOW       2
#define     RAND_COND_TRUE_FALSE_DESICION           2
#define     RAND_PROGRAM_COND_EXPR_DESICION         4
#define     IF_ELSE_DEPTH                           3
#define     STD_PROGRAM_N                           6
#define     STD_PROGRAM2_N                          4
#define     RAND_COND_END_OR_GO_ON                  3

FILE *fout = NULL;

int line = 0;
int nline = 1;
int maxstate = 0;

char *opstr [] = {"+", "-", "<<", ">>", "\&amp;\&amp;", "||", "!"};
char *cmpstr [] = {"<=", ">=", "==", "!=", "<", ">"};


void registr (void) {
    printf (" %c ", (rand () % MAX_EXPR_REG_VAL) + FIRST_REG_VAL);
return;
}

void cnst (void) {
    printf (" %i ", rand () % MAX_EXPR_CONST_VAL);
return;
}

void operator (void) {
    printf (" %s ", opstr [rand () % MAX_EXPR_OPERATOR_VAL]);
return;
}

void cmp (void) {
    printf (" %s ", cmpstr [rand () % MAX_EXPR_CMP_OPERATOR_VAL]);
return;
}

void operand (void) {
    if ((rand () % RAND_OPERAND_CONST_REGISTER) == 0)
        cnst ();
    else
        registr ();
return;
}

#define NO      0
#define WEST    1
#define EAST    2


int expr0 () {
    printf BITTE IM PDF NACHGUCKEN
    registr ();
    printf (" <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    printf (""};n");
return 0;
}


int expr (int z, int zs, int dir) {
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    registr ();
    printf (" <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    printf (""};n");
    if (dir == NO) {
        printf ("\draw [->] (z%i) -- (z%i);;", zs, z);
    }
    else if (dir == WEST) {
        printf ("\draw [->] (z%i.west) -- (z%i);;", zs, z);
    }
    else if (dir == EAST) {
        printf ("\draw [->] (z%i.east) -- (z%i);;", zs, z);
    }

return z;
}

int cond (int z, int zs, int dir) {
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    //printf BITTE IM PDF NACHGUCKEN
    operand ();
    cmp ();
    operand ();
    printf (""};n");
    if (dir == NO) {
        printf ("\draw [->] (z%i) -- (z%i);;", zs, z);
    }
    else if (dir == WEST) {
        printf ("\draw [->] (z%i.west) -- (z%i);;", zs, z);
    }
    else if (dir == EAST) {
        printf ("\draw [->] (z%i.east) -- (z%i);;", zs, z);
    }

    return z;
}

int as (int z, int zs, int dir) {
    int ztmp;
    int r;
    if ((r = (rand () % 8)) < 2) {
        z = ztmp = cond (z+1, z, dir);
        z = expr (z+1, ztmp, WEST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);
        z = expr (z+1, ztmp, EAST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);

    }
    else if ((r >= 2) \&amp;\&amp; (r <= 5)) {
        ztmp = z;
        z = expr (z+1, ztmp, dir);
        as (z, ztmp, NO);
    }
return z;
}






int main (void) {
    time_t t;
    int j;
    srand (t = time(NULL));
    expr0();
    as (0, 0, NO);
return 0;
}

Jetzt kommt der Trick, mit den Registern, den Code erstelle ich vorher und parse ihn dann ab.

Ich mache Register, Konstante, Operation.

Entschuldigung, war eine lange nach, habe geschlafen, jetzt mache ich weiter.

So, der Programmcode zur Erzeugung von RTL-Notation funktioniert

/*
Grammatik

Sporadische Sammlung
- Zuweisung
- Addition
if
- Vergleiche
    - <=, >=, ==, !=, <, >
- Subtraktion
- Shift
    << >>
- Null setzen

Operationen
    - Mathematische:
        + (Addition)
        - (Subtraktion)
    - Verschieben
        >> Rechtsshift
        << Linksshift
    - 0 setzen
Vergleiche
    - <=, >=, ==, !=, <, >
Zuweisung
    <-

Zeichensatz: Variablen, Register, Operatoren und Konstante Werte

Operand ::= <Register> | <Const>
CMP ::= <= | >= | == | != | < | >
MathOperator ::= + | - | << | >>
BitBooleanOperator ::= '\&amp;\&amp;' | '||' | '!'
Operator ::= <MathOperator> | <BitBooleanOperator>
Expr ::= <Register> <- <Operand> | <Operand> <Operator> <Operand> | 0
Condition ::= IF <Register> <CMP> <Operand> THEN <Program> FI

Programm ::= <Expr> | <Condition> <Program>
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define     MAX_STATES                              1024
#define     MAX_EXPR_CONST_VAL                      128
#define     MAX_EXPR_REG_VAL                        4
#define     FIRST_REG_VAL                           'a'
#define     MAX_EXPR_OPERATOR_VAL                   6
#define     MAX_EXPR_CMP_OPERATOR_VAL               5
#define     RAND_OPERAND_CONST_REGISTER             2
#define     RAND_EXPR_OPERATOR_OPERAND_FOLLOW       2
#define     RAND_COND_TRUE_FALSE_DESICION           2
#define     RAND_PROGRAM_COND_EXPR_DESICION         4
#define     IF_ELSE_DEPTH                           3
#define     STD_PROGRAM_N                           6
#define     STD_PROGRAM2_N                          4
#define     RAND_COND_END_OR_GO_ON                  3

FILE *fout = NULL;

int line = 0;
int nline = 1;
int maxstate = 0;

char *opstr [] = {"+", "-", "<<", ">>", "\&amp;\&amp;", "||", "!"};
char *cmpstr [] = {"<=", ">=", "==", "!=", "<", ">"};


void registr (void) {
    printf (" %c ", (rand () % MAX_EXPR_REG_VAL) + FIRST_REG_VAL);
return;
}

void cnst (void) {
    printf (" %i ", rand () % MAX_EXPR_CONST_VAL);
return;
}

void operator (void) {
    printf (" %s ", opstr [rand () % MAX_EXPR_OPERATOR_VAL]);
return;
}

void cmp (void) {
    printf (" %s ", cmpstr [rand () % MAX_EXPR_CMP_OPERATOR_VAL]);
return;
}

void operand (void) {
    if ((rand () % RAND_OPERAND_CONST_REGISTER) == 0)
        cnst ();
    else
        registr ();
return;
}

#define NO      0
#define WEST    1
#define EAST    2

#define MAX_NODES                   64
#define STACKS_MAX                  4

char *op_names [] = {"==",
    "!=",
    ">",
    ">=",
    "<",
    "<=",
    "+",
    "++",
    "-",
    "--",
    "<<",
    ">>",
    "<|",
    "|>",
    "and",
    "not",
    "or",
    "xor",
    "+",
    "++",
    "-",
    "--",
    "<<",
    ">>",
    "<|",
    "|>",
    "and",
    "not",
    "or",
    "xor",
    "<-"
};

#define OP_CMP_EQ_REG_CONST         0
#define OP_CMP_NE_REG_CONST         1
#define OP_CMP_GR_REG_CONST         2
#define OP_CMP_GE_REG_CONST         3
#define OP_CMP_LT_REG_CONST         4
#define OP_CMP_LE_REG_CONST         5
#define OP_ADD_REG_REG_CONST        6
#define OP_INC_REG_REG_CONST        7
#define OP_SUB_REG_REG_CONST        8
#define OP_DEC_REG_REG_CONST        9
#define OP_SLL_REG_REG_CONST        10
#define OP_SLR_REG_REG_CONST        11
#define OP_RL_REG_REG_CONST       12
#define OP_RR_REG_REG_CONST       13
#define OP_AND_REG_REG_CONST      14
#define OP_NOT_REG_REG_CONST      15
#define OP_OR_REG_REG_CONST       16
#define OP_EXOR_REG_REG_CONST     17
#define OP_ADD_REG_REG_REG        18
#define OP_INC_REG_REG_REG        19
#define OP_SUB_REG_REG_REG        20
#define OP_DEC_REG_REG_REG        21
#define OP_SLL_REG_REG_REG        22
#define OP_SLR_REG_REG_REG        23
#define OP_RL_REG_REG_REG         24
#define OP_RR_REG_REG_REG         25
#define OP_AND_REG_REG_REG        26
#define OP_NOT_REG_REG_REG        27
#define OP_OR_REG_REG_REG         28
#define OP_EXOR_REG_REG_REG       29
#define OP_ASSIGNMENT_REG_CONST   30
#define NA                        -1
#define EMPTY                       -2

#define STACK_OPCODE                0
#define STACK_OP1                   1
#define STACK_OP2                   2
#define STACK_OP3                   3

#define MAX_COND                    3
#define CONST_MAX                   32


int stack [STACKS_MAX][MAX_NODES];
int stack2 [MAX_NODES];
int stack_ptr [STACKS_MAX];
int queue_ptr [STACKS_MAX];
int stack_ptr2 = 0;

void init_stack (void) {
    int i;
    for (i = 0;  i < STACKS_MAX;  i++) {
        stack_ptr [i] = 0;
        queue_ptr [i] = 0;
    }
return;
}

void push (int stck, int v) {
    if (stack_ptr[stck] < (MAX_NODES-1)) {
        stack [stck][stack_ptr [stck]] = v;
        stack_ptr [stck]++;
    }
return;
}

int pop (int stck) {
    if (stack_ptr [stck] > 0) {
        stack_ptr [stck]--;
        return stack [stck][stack_ptr [stck]];
    }
}

int get (int stck) {
    if (queue_ptr [stck] < stack_ptr [stck]) {
        return stack [stck][queue_ptr [stck]++];
    }
    else return EMPTY;
}


void push2 (int v) {
    if (stack_ptr2 < (MAX_NODES-1)) {
        stack2 [stack_ptr2] = v;
        stack_ptr2++;
    }
}

int pop2 (void) {
    if (stack_ptr2 > 0) {
        stack_ptr2--;
        return stack2 [stack_ptr2];
    }
}

int regmax = 0;


/*
 * reg ::= op reg reg reg | op reg reg const | op const
 * cond ::= op_cmp reg const addr1 addr2
 */

void init () {
    int i = 0;
    int cond_count = MAX_COND;
    int op;
    int imax = (rand () % 6) + 5;
    int lastreg;

    push (STACK_OPCODE, OP_ASSIGNMENT_REG_CONST);           // Assignment at begin
    push (STACK_OP1, 0);                                    // Register R0 ()
    push (STACK_OP2, rand () % CONST_MAX);                  // Const
    push (STACK_OP3, NA);                                   // Operand 3, assignment, not given

    for (i = 1;  i < imax;  i++) {
        op = rand () % (OP_EXOR_REG_REG_REG+1);
        if (op < OP_CMP_LE_REG_CONST) {
            if (cond_count > 0) {
                cond_count--;
                lastreg = pop (STACK_OP1);
                push (STACK_OP1, lastreg);
                push (STACK_OPCODE, op);
                push (STACK_OP1, lastreg);
                push (STACK_OP2, rand () % CONST_MAX);
                push (STACK_OP3, NA );
                push2 (i);
            }
            else {
                i--;
            }
        }
        else {
                lastreg = pop (STACK_OP1);
                push (STACK_OP1, lastreg);
                push (STACK_OPCODE, op);
                push (STACK_OP1, lastreg+1);
                push (STACK_OP2, lastreg);
                if ((op >= OP_ADD_REG_REG_REG) \&amp;\&amp; (op <= OP_EXOR_REG_REG_REG))
                    push (STACK_OP3, (rand () % (lastreg+1))-1);
                else
                    push (STACK_OP3, rand () % CONST_MAX);
        }
    }
    push (STACK_OPCODE, EMPTY);
    push (STACK_OP1, EMPTY);
    push (STACK_OP2, EMPTY);
    push (STACK_OP3, EMPTY);
}

void test_output (void) {
    int p, o1, o2, o3;

    while ((p = get (STACK_OPCODE)) != EMPTY) {
        if ((p >= OP_CMP_EQ_REG_CONST) \&amp;\&amp; (p <= OP_CMP_LE_REG_CONST)) {
            printf ("R%i %s %in", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
        }
        else if (p == OP_ASSIGNMENT_REG_CONST) {
            printf ("R%i %s %in", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
        }
        else {
            if ((p >= OP_ADD_REG_REG_CONST) \&amp;\&amp; (p <= OP_EXOR_REG_REG_CONST))
                printf ("R%i %s R%i %s %in", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
            else
                printf ("R%i %s R%i %s R%in", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
        }
    }
}

int expr0 () {
    printf BITTE IM PDF NACHGUCKEN
    registr ();
    printf (" <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    printf (""};n");
return 0;
}


int expr (int z, int zs, int dir) {
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    registr ();
    printf (" <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }

   printf (""};n");
    if (dir == NO) {
        printf ("\draw [->] (z%i) -- (z%i);;", zs, z);
    }
    else if (dir == WEST) {
        printf ("\draw [->] (z%i.west) -- (z%i);;", zs, z);
    }
    else if (dir == EAST) {
        printf ("\draw [->] (z%i.east) -- (z%i);;", zs, z);
    }

return z;
}

int cond (int z, int zs, int dir) {
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    //printf BITTE IM PDF NACHGUCKEN
    operand ();
    cmp ();
    operand ();
    printf (""};n");
    if (dir == NO) {
        printf ("\draw [->] (z%i) -- (z%i);;", zs, z);
    }
    else if (dir == WEST) {
        printf ("\draw [->] (z%i.west) -- (z%i);;", zs, z);
    }
    else if (dir == EAST) {
        printf ("\draw [->] (z%i.east) -- (z%i);;", zs, z);
    }

    return z;
}

int as (int z, int zs, int dir) {
    int ztmp;
    int r;
    if ((r = (rand () % 8)) < 2) {
        z = ztmp = cond (z+1, z, dir);
        z = expr (z+1, ztmp, WEST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);
        z = expr (z+1, ztmp, EAST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);

    }
    else if ((r >= 2) \&amp;\&amp; (r <= 5)) {
        ztmp = z;
        z = expr (z+1, ztmp, dir);
        as (z, ztmp, NO);
    }
return z;
}






int main (void) {
    time_t t;
    int j;
    srand (t = time(NULL));
    //expr0();
    //as (0, 0, NO);
    init ();
    test_output ();
return 0;
}

david@laptop-peaq:~\$ gcc asmparser10.c
david@laptop-peaq:~\$ ./a.out
R0 <- 7
R1 <= 0
R2 <- R1 << R0
R3 <- R2 >> R-1
R4 <- R3 and 1
R5 <- R4 << 18
david@laptop-peaq:~\$ ./a.out
R0 <- 19
R1 <- R0 |> R-1
R2 <- R1 + R-1
R3 <- R2 - 3
R4 <- R3 or R2
R5 <- R4 xor R1
R5 < 10
david@laptop-peaq:~\$ ./a.out
R0 <- 19
R1 <- R0 |> R-1
R2 <- R1 + R-1
R3 <- R2 - 3
R4 <- R3 or R2
R5 <- R4 xor R1
R5 < 10
david@laptop-peaq:~\$ ./a.out
R0 <- 3
R1 <- R0 or R-1
R2 <- R1 xor 8
R3 <- R2 -- R-1
R3 == 19
david@laptop-peaq:~\$

Das sind mehrere Ausgaben

R0 <- 8
R1 <- R0 + R-1
R2 <- R1 not R-1
R3 <- R2 and R-1
R4 <- R3 not 25
R0 <- 13
R1 <- R0 ++ R-1
R2 <- R1 + R0
R3 <- R2 xor 23
R4 <- R3 and R2
R4 > 13
R5 <- R4 |> R3
R6 <- R5 + 13
R7 <- R6 >> 12
R0 <- 29
R0 >= 2
R1 <- R0 + R-1
R2 <- R1 xor 16
R3 <- R2 <| 12
R3 != 20
R0 <- 29
R0 >= 2
R1 <- R0 + R-1
R2 <- R1 xor 16
R3 <- R2 <| 12
R3 != 20
R0 <- 20
R1 <- R0 not 30
R2 <- R1 + 13
R3 <- R2 + 23
R4 <- R3 and R1
R5 <- R4 -- 6
R6 <- R5 << R-1
R0 <- 20
R1 <- R0 not 30
R2 <- R1 + 13
R3 <- R2 + 23
R4 <- R3 and R1
R5 <- R4 -- 6
R6 <- R5 << R-1
R0 <- 0
R1 <- R0 <| 4
R1 < 15
R1 != 8
R2 <- R1 + 1
R3 <- R2 >> R1
R4 <- R3 not R2
R5 <- R4 not R0
R0 <- 20
R0 < 7
R1 <- R0 >> R-1
R1 < 0
R2 <- R1 -- 3
R3 <- R2 << R1
R4 <- R3 <| 14
R5 <- R4 |> 1
R6 <- R5 << R-1
R0 <- 20
R0 < 7
R1 <- R0 >> R-1
R1 < 0
R2 <- R1 -- 3
R3 <- R2 << R1
R4 <- R3 <| 14
R5 <- R4 |> 1
R6 <- R5 << R-1
R0 <- 3
R1 <- R0 xor 12
R2 <- R1 and 1
R3 <- R2 |> R1
R4 <- R3 or R0
R4 == 18
R0 <- 22
R1 <- R0 and R-1
R1 > 4
R2 <- R1 and R0
R2 >= 28
R3 <- R2 or 15
R3 < 11
R4 <- R3 >> 21
R5 <- R4 |> R3

Da war noch ein Fehler

Increment
Decrement

waren nicht richtig

david@laptop-peaq:~\$ ./a.out
R0 <- 20
R1 <- R0 --
R2 <- R1 >> R-1
R3 <- R2 |> 11
R4 <- R3 |> 8
david@laptop-peaq:~\$ ./a.out
R0 <- 8
R1 <- R0 |> 27
R2 <- R1 - R-1
R3 <- R2 --
R3 > 11
R4 >= 3
R5 <- R4 <| 24
R6 <- R5 --
david@laptop-peaq:~\$ ./a.out
R0 <- 8
R1 <- R0 |> 27
R2 <- R1 - R-1
R3 <- R2 --
R3 > 11
R4 >= 3
R5 <- R4 <| 24
R6 <- R5 --
david@laptop-peaq:~\$ ./a.out
R0 <- 6
R1 <- R0 + R-1
R2 <- R1 or R-1
R3 <- R2 or 21
R4 <- R3 <| R0
R5 <- R4 xor 14
R6 <- R5 xor R2
R7 <- R6 xor R-1
R8 <- R7 |> R4
R9 <- R8 + 26

Im nächsten Schritt arbeite ich Anwensisungen einfach ab. die Rekursion des ASM-Diagramm wird nicht länger selbstständig arbeiten Die Rekursion des ASM-Diagramms, wird die RTL-Notation-Answeisungen - Schritt für Schritt abarbeiten und eine entsprechende Ausgabe erzeugen.

/*
Grammatik

Sporadische Sammlung
- Zuweisung
- Addition
if
- Vergleiche
    - <=, >=, ==, !=, <, >
- Subtraktion
- Shift
    << >>
- Null setzen

Operationen
    - Mathematische:
        + (Addition)
        - (Subtraktion)
    - Verschieben
        >> Rechtsshift
        << Linksshift
    - 0 setzen
Vergleiche
    - <=, >=, ==, !=, <, >
Zuweisung
    <-

Zeichensatz: Variablen, Register, Operatoren und Konstante Werte

Operand ::= <Register> | <Const>
CMP ::= <= | >= | == | != | < | >
MathOperator ::= + | - | << | >>
BitBooleanOperator ::= '\&amp;\&amp;' | '||' | '!'
Operator ::= <MathOperator> | <BitBooleanOperator>
Expr ::= <Register> <- <Operand> | <Operand> <Operator> <Operand> | 0
Condition ::= IF <Register> <CMP> <Operand> THEN <Program> FI

Programm ::= <Expr> | <Condition> <Program>
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define     MAX_STATES                              1024
#define     MAX_EXPR_CONST_VAL                      128
#define     MAX_EXPR_REG_VAL                        4
#define     FIRST_REG_VAL                           'a'
#define     MAX_EXPR_OPERATOR_VAL                   6
#define     MAX_EXPR_CMP_OPERATOR_VAL               5
#define     RAND_OPERAND_CONST_REGISTER             2
#define     RAND_EXPR_OPERATOR_OPERAND_FOLLOW       2
#define     RAND_COND_TRUE_FALSE_DESICION           2
#define     RAND_PROGRAM_COND_EXPR_DESICION         4
#define     IF_ELSE_DEPTH                           3
#define     STD_PROGRAM_N                           6
#define     STD_PROGRAM2_N                          4
#define     RAND_COND_END_OR_GO_ON                  3

FILE *fout = NULL;

int line = 0;
int nline = 1;
int maxstate = 0;

char *opstr [] = {"+", "-", "<<", ">>", "\&amp;\&amp;", "||", "!"};
char *cmpstr [] = {"<=", ">=", "==", "!=", "<", ">"};


void registr (void) {
    printf (" %c ", (rand () % MAX_EXPR_REG_VAL) + FIRST_REG_VAL);
return;
}

void cnst (void) {
    printf (" %i ", rand () % MAX_EXPR_CONST_VAL);
return;
}

void operator (void) {
    printf (" %s ", opstr [rand () % MAX_EXPR_OPERATOR_VAL]);
return;
}

void cmp (void) {
    printf (" %s ", cmpstr [rand () % MAX_EXPR_CMP_OPERATOR_VAL]);
return;
}

void operand (void) {
    if ((rand () % RAND_OPERAND_CONST_REGISTER) == 0)
        cnst ();
    else
        registr ();
return;
}

#define NO      0
#define WEST    1
#define EAST    2

#define MAX_NODES                   64
#define STACKS_MAX                  4

char *op_names [] = {"==",
    "!=",
    ">",
    ">=",
    "<",
    "<=",
    "+",
    "++",
    "-",
    "--",
    "<<",
    ">>",
    "<|",
    "|>",
    "and",
    "not",
    "or",
    "xor",
    "+",
    "++",
    "-",
    "--",
    "<<",
    ">>",
    "<|",
    "|>",
    "and",
    "not",
    "or",
    "xor",
    "<-"
};

#define OP_CMP_EQ_REG_CONST         0
#define OP_CMP_NE_REG_CONST         1
#define OP_CMP_GR_REG_CONST         2
#define OP_CMP_GE_REG_CONST         3
#define OP_CMP_LT_REG_CONST         4
#define OP_CMP_LE_REG_CONST         5
#define OP_ADD_REG_REG_CONST        6
#define OP_INC_REG_REG_CONST        7
#define OP_SUB_REG_REG_CONST        8
#define OP_DEC_REG_REG_CONST        9
#define OP_SLL_REG_REG_CONST        10
#define OP_SLR_REG_REG_CONST        11
#define OP_RL_REG_REG_CONST       12
#define OP_RR_REG_REG_CONST       13
#define OP_AND_REG_REG_CONST      14
#define OP_NOT_REG_REG_CONST      15
#define OP_OR_REG_REG_CONST       16
#define OP_EXOR_REG_REG_CONST     17
#define OP_ADD_REG_REG_REG        18
#define OP_INC_REG_REG_REG        19
#define OP_SUB_REG_REG_REG        20
#define OP_DEC_REG_REG_REG        21
#define OP_SLL_REG_REG_REG        22
#define OP_SLR_REG_REG_REG        23
#define OP_RL_REG_REG_REG         24
#define OP_RR_REG_REG_REG         25
#define OP_AND_REG_REG_REG        26
#define OP_NOT_REG_REG_REG        27
#define OP_OR_REG_REG_REG         28
#define OP_EXOR_REG_REG_REG       29
#define OP_ASSIGNMENT_REG_CONST   30
#define NA                        -1
#define EMPTY                       -2

#define STACK_OPCODE                0
#define STACK_OP1                   1
#define STACK_OP2                   2
#define STACK_OP3                   3

#define MAX_COND                    3
#define CONST_MAX                   32


int stack [STACKS_MAX][MAX_NODES];
int stack2 [MAX_NODES];
int stack_ptr [STACKS_MAX];
int queue_ptr [STACKS_MAX];
int stack_ptr2 = 0;

void init_stack (void) {
    int i;
    for (i = 0;  i < STACKS_MAX;  i++) {
        stack_ptr [i] = 0;
        queue_ptr [i] = 0;
    }
return;
}

void push (int stck, int v) {
    if (stack_ptr[stck] < (MAX_NODES-1)) {
        stack [stck][stack_ptr [stck]] = v;
        stack_ptr [stck]++;
    }
return;
}

int pop (int stck) {
    if (stack_ptr [stck] > 0) {
        stack_ptr [stck]--;
        return stack [stck][stack_ptr [stck]];
    }
}

int get (int stck) {
    if (queue_ptr [stck] < stack_ptr [stck]) {
        return stack [stck][queue_ptr [stck]++];
    }
    else return EMPTY;
}


void push2 (int v) {
    if (stack_ptr2 < (MAX_NODES-1)) {
        stack2 [stack_ptr2] = v;
        stack_ptr2++;
    }
}

int pop2 (void) {
    if (stack_ptr2 > 0) {
        stack_ptr2--;
        return stack2 [stack_ptr2];
    }
}

int regmax = 0;


/*
 * reg ::= op reg reg reg | op reg reg const | op const
 * cond ::= op_cmp reg const addr1 addr2
 */

void init () {
    int i = 0;
    int cond_count = MAX_COND;
    int cond_least = 0;
    int op;
    int imax = (rand () % 6) + 5;
    int lastreg;

    push (STACK_OPCODE, OP_ASSIGNMENT_REG_CONST);           // Assignment at begin
    push (STACK_OP1, 0);                                    // Register R0 ()
    push (STACK_OP2, rand () % CONST_MAX);                  // Const
    push (STACK_OP3, NA);                                   // Operand 3, assignment, not given

    for (i = 1;  i < imax;  i++) {
        op = rand () % (OP_EXOR_REG_REG_REG+1);
        if ((op < OP_CMP_LE_REG_CONST) \&amp;\&amp; (cond_least == 0)) {
            if (cond_count > 0) {
                cond_count--;
                lastreg = pop (STACK_OP1);
                push (STACK_OP1, lastreg);
                push (STACK_OPCODE, op);
                push (STACK_OP1, lastreg);
                push (STACK_OP2, rand () % CONST_MAX);
                push (STACK_OP3, NA );
                cond_least = 2;
                if ((i + cond_least) > imax)
                    imax += cond_least;
                push2 (i);
            }
            else {
                i--;
            }
        }
        else {
                if (cond_least != 0)
                    cond_least--;
                lastreg = pop (STACK_OP1);
                push (STACK_OP1, lastreg);
                push (STACK_OPCODE, op);
                push (STACK_OP1, lastreg+1);
                push (STACK_OP2, lastreg);
                if ((op >= OP_ADD_REG_REG_REG) \&amp;\&amp; (op <= OP_EXOR_REG_REG_REG))
                    push (STACK_OP3, (rand () % (lastreg+1))-1);
                else
                    push (STACK_OP3, rand () % CONST_MAX);
        }
    }
    push (STACK_OPCODE, EMPTY);
    push (STACK_OP1, EMPTY);
    push (STACK_OP2, EMPTY);
    push (STACK_OP3, EMPTY);
}

void test_output (void) {
    int p, o1, o2, o3;

    while ((p = get (STACK_OPCODE)) != EMPTY) {
        if ((p >= OP_CMP_EQ_REG_CONST) \&amp;\&amp; (p <= OP_CMP_LE_REG_CONST)) {
            printf ("R%i %s %in", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
        }
        else if (p == OP_ASSIGNMENT_REG_CONST) {
            printf ("R%i %s %in", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
        }
        else {
            if ((p == OP_INC_REG_REG_CONST) || (p == OP_INC_REG_REG_REG) || (p == OP_DEC_REG_REG_CONST) || (p == OP_DEC_REG_REG_REG)) {
                printf ("R%i %s R%i %sn", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p]);
                get (STACK_OP3);
            }
            else if ((p >= OP_ADD_REG_REG_CONST) \&amp;\&amp; (p <= OP_EXOR_REG_REG_CONST))
                printf ("R%i %s R%i %s %in", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
            else
                printf ("R%i %s R%i %s R%in", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
        }
    }
}

int expr0 () {
    printf BITTE IM PDF NACHGUCKEN
    registr ();
    printf (" <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    printf (""};n");
return 0;
}


int expr (int z, int zs, int dir) {
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    registr ();
    printf (" <- ");
    operand ();
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }

   printf (""};n");
    if (dir == NO) {
        printf ("\draw [->] (z%i) -- (z%i);;", zs, z);
    }
    else if (dir == WEST) {
        printf ("\draw [->] (z%i.west) -- (z%i);;", zs, z);
    }
    else if (dir == EAST) {
        printf ("\draw [->] (z%i.east) -- (z%i);;", zs, z);
    }

return z;
}

int cond (int z, int zs, int dir) {
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    //printf BITTE IM PDF NACHGUCKEN
    operand ();
    cmp ();
    operand ();
    printf (""};n");
    if (dir == NO) {
        printf ("\draw [->] (z%i) -- (z%i);;", zs, z);
    }
    else if (dir == WEST) {
        printf ("\draw [->] (z%i.west) -- (z%i);;", zs, z);
    }
    else if (dir == EAST) {
        printf ("\draw [->] (z%i.east) -- (z%i);;", zs, z);
    }

    return z;
}

/*int as (int z, int zs, int dir) {
    int ztmp;
    int r;
    if ((r = (rand () % 8)) < 2) {
        z = ztmp = cond (z+1, z, dir);
        z = expr (z+1, ztmp, WEST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);
        z = expr (z+1, ztmp, EAST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);

    }
    else if ((r >= 2) \&amp;\&amp; (r <= 5)) {
        ztmp = z;
        z = expr (z+1, ztmp, dir);
        as (z, ztmp, NO);
    }
return z;
}

*/

int as (int z, int zs, int dir) {
    int ztmp;
    int r;
    if ((r = (rand () % 8)) < 2) {
        z = ztmp = cond (z+1, z, dir);
        z = expr (z+1, ztmp, WEST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);
        z = expr (z+1, ztmp, EAST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);

    }
    else if ((r >= 2) \&amp;\&amp; (r <= 5)) {
        ztmp = z;
        z = expr (z+1, ztmp, dir);
        as (z, ztmp, NO);
    }
return z;
}






int main (void) {
    time_t t;
    int j;
    srand (t = time(NULL));
    //expr0();
    //as (0, 0, NO);
    init_stack ();
    init ();
    test_output ();
    init_stack ();
return 0;
}

Das richtige ist, bei der Rekursiven

as

wieder mit Stack zu arbeiten.

Das habe ich getan, ich glaube, es funktioniert jetzt, ich teste

Für, alle, die sich gerade gewundert haben, hier die Auflösung des Rätsels

/*
Grammatik

Sporadische Sammlung
- Zuweisung
- Addition
if
- Vergleiche
    - <=, >=, ==, !=, <, >
- Subtraktion
- Shift
    << >>
- Null setzen

Operationen
    - Mathematische:
        + (Addition)
        - (Subtraktion)
    - Verschieben
        >> Rechtsshift
        << Linksshift
    - 0 setzen
Vergleiche
    - <=, >=, ==, !=, <, >
Zuweisung
    <-

Zeichensatz: Variablen, Register, Operatoren und Konstante Werte

Operand ::= <Register> | <Const>
CMP ::= <= | >= | == | != | < | >
MathOperator ::= + | - | << | >>
BitBooleanOperator ::= '\&amp;\&amp;' | '||' | '!'
Operator ::= <MathOperator> | <BitBooleanOperator>
Expr ::= <Register> <- <Operand> | <Operand> <Operator> <Operand> | 0
Condition ::= IF <Register> <CMP> <Operand> THEN <Program> FI

Programm ::= <Expr> | <Condition> <Program>
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define     MAX_STATES                              1024
#define     MAX_EXPR_CONST_VAL                      128
#define     MAX_EXPR_REG_VAL                        4
#define     FIRST_REG_VAL                           'a'
#define     MAX_EXPR_OPERATOR_VAL                   6
#define     MAX_EXPR_CMP_OPERATOR_VAL               5
#define     RAND_OPERAND_CONST_REGISTER             2
#define     RAND_EXPR_OPERATOR_OPERAND_FOLLOW       2
#define     RAND_COND_TRUE_FALSE_DESICION           2
#define     RAND_PROGRAM_COND_EXPR_DESICION         4
#define     IF_ELSE_DEPTH                           3
#define     STD_PROGRAM_N                           6
#define     STD_PROGRAM2_N                          4
#define     RAND_COND_END_OR_GO_ON                  3

FILE *fout = NULL;

int line = 0;
int nline = 1;
int maxstate = 0;

char *opstr [] = {"+", "-", "<<", ">>", "\&amp;\&amp;", "||", "!"};
char *cmpstr [] = {"<=", ">=", "==", "!=", "<", ">"};


void registr (void) {
    printf (" %c ", (rand () % MAX_EXPR_REG_VAL) + FIRST_REG_VAL);
return;
}

void cnst (void) {
    printf (" %i ", rand () % MAX_EXPR_CONST_VAL);
return;
}

void operator (void) {
    printf (" %s ", opstr [rand () % MAX_EXPR_OPERATOR_VAL]);
return;
}

void cmp (void) {
    printf (" %s ", cmpstr [rand () % MAX_EXPR_CMP_OPERATOR_VAL]);
return;
}

void operand (void) {
    if ((rand () % RAND_OPERAND_CONST_REGISTER) == 0)
        cnst ();
    else
        registr ();
return;
}

#define NO      0
#define WEST    1
#define EAST    2

#define MAX_NODES                   64
#define STACKS_MAX                  4

char *op_names [] = {"==",
    "!=",
    ">",
    ">=",
    "<",
    "<=",
    "+",
    "++",
    "-",
    "--",
    "<<",
    ">>",
    "<|",
    "|>",
    "and",
    "not",
    "or",
    "xor",
    "+",
    "++",
    "-",
    "--",
    "<<",
    ">>",
    "<|",
    "|>",
    "and",
    "not",
    "or",
    "xor",
    "<-"
};

#define OP_CMP_EQ_REG_CONST         0
#define OP_CMP_NE_REG_CONST         1
#define OP_CMP_GR_REG_CONST         2
#define OP_CMP_GE_REG_CONST         3
#define OP_CMP_LT_REG_CONST         4
#define OP_CMP_LE_REG_CONST         5
#define OP_ADD_REG_REG_CONST        6
#define OP_INC_REG_REG_CONST        7
#define OP_SUB_REG_REG_CONST        8
#define OP_DEC_REG_REG_CONST        9
#define OP_SLL_REG_REG_CONST        10
#define OP_SLR_REG_REG_CONST        11
#define OP_RL_REG_REG_CONST       12
#define OP_RR_REG_REG_CONST       13
#define OP_AND_REG_REG_CONST      14
#define OP_NOT_REG_REG_CONST      15
#define OP_OR_REG_REG_CONST       16
#define OP_EXOR_REG_REG_CONST     17
#define OP_ADD_REG_REG_REG        18
#define OP_INC_REG_REG_REG        19
#define OP_SUB_REG_REG_REG        20
#define OP_DEC_REG_REG_REG        21
#define OP_SLL_REG_REG_REG        22
#define OP_SLR_REG_REG_REG        23
#define OP_RL_REG_REG_REG         24
#define OP_RR_REG_REG_REG         25
#define OP_AND_REG_REG_REG        26
#define OP_NOT_REG_REG_REG        27
#define OP_OR_REG_REG_REG         28
#define OP_EXOR_REG_REG_REG       29
#define OP_ASSIGNMENT_REG_CONST   30
#define NA                        -1
#define EMPTY                       -2
#define STACK_UNDERFLOW             -3

#define STACK_OPCODE                0
#define STACK_OP1                   1
#define STACK_OP2                   2
#define STACK_OP3                   3

#define MAX_COND                    3
#define CONST_MAX                   32


int stack [STACKS_MAX][MAX_NODES];
int stack2 [MAX_NODES];
int stack_ptr [STACKS_MAX];
int queue_ptr [STACKS_MAX];
int stack_ptr2 = 0;

void init_stack (void) {
    int i;
    for (i = 0;  i < STACKS_MAX;  i++) {
        stack_ptr [i] = 0;
    }
return;
}

void queue_init (void) {
    int i;
    for (i = 0;  i < STACKS_MAX;  i++) {
        queue_ptr [i] = 0;
    }
return;
}

void push (int stck, int v) {
    if (stack_ptr[stck] < (MAX_NODES-1)) {
        stack [stck][stack_ptr [stck]] = v;
        stack_ptr [stck]++;
    }
return;
}

int pop (int stck) {
    if (stack_ptr [stck] > 0) {
        stack_ptr [stck]--;
        return stack [stck][stack_ptr [stck]];
    }
    else
        return STACK_UNDERFLOW;
}

int getstckptr (int stck) {
    return stack_ptr [stck];
}

int get (int stck) {
    if (queue_ptr [stck] < stack_ptr [stck]) {
        return stack [stck][queue_ptr [stck]++];
    }
    else return EMPTY;
}
void unget (int stck) {
    if (queue_ptr [stck] > 0)
        queue_ptr [stck]--;
}


void push2 (int v) {
    if (stack_ptr2 < (MAX_NODES-1)) {
        stack2 [stack_ptr2] = v;
        stack_ptr2++;
    }
}

int pop2 (void) {
    if (stack_ptr2 > 0) {
        stack_ptr2--;
        return stack2 [stack_ptr2];
    }
}

int regmax = 0;


/*
 * reg ::= op reg reg reg | op reg reg const | op const
 * cond ::= op_cmp reg const addr1 addr2
 */

void init () {
    int i = 0;
    int cond_count = MAX_COND;
    int cond_least = 0;
    int op;
    int imax = (rand () % 6) + 5;
    int lastreg;

    push (STACK_OPCODE, OP_ASSIGNMENT_REG_CONST);           // Assignment at begin
    push (STACK_OP1, 0);                                    // Register R0 ()
    push (STACK_OP2, rand () % CONST_MAX);                  // Const
    push (STACK_OP3, NA);                                   // Operand 3, assignment, not given

    for (i = 1;  i < imax;  i++) {
        op = rand () % (OP_EXOR_REG_REG_REG+1);
        if ((op < OP_CMP_LE_REG_CONST) \&amp;\&amp; (cond_least == 0)) {
            if (cond_count > 0) {
                cond_count--;
                lastreg = pop (STACK_OP1);
                push (STACK_OP1, lastreg);
                push (STACK_OPCODE, op);
                push (STACK_OP1, lastreg);
                push (STACK_OP2, rand () % CONST_MAX);
                push (STACK_OP3, NA );
                cond_least = 2;
                if ((i + cond_least) > imax)
                    imax += cond_least;
                push2 (i);
            }
            else {
                i--;
            }
        }
        else {
                if (cond_least != 0)
                    cond_least--;
                lastreg = pop (STACK_OP1);
                push (STACK_OP1, lastreg);
                push (STACK_OPCODE, op);
                push (STACK_OP1, lastreg+1);
                push (STACK_OP2, lastreg);
                if ((op >= OP_ADD_REG_REG_REG) \&amp;\&amp; (op <= OP_EXOR_REG_REG_REG))
                    push (STACK_OP3, (rand () % (lastreg+1))-1);
                else
                    push (STACK_OP3, rand () % CONST_MAX);
        }
    }
    push (STACK_OPCODE, EMPTY);
    push (STACK_OP1, EMPTY);
    push (STACK_OP2, EMPTY);
    push (STACK_OP3, EMPTY);
}

void test_output (void) {
    int p, o1, o2, o3;

    while ((p = get (STACK_OPCODE)) != EMPTY) {
        if ((p >= OP_CMP_EQ_REG_CONST) \&amp;\&amp; (p <= OP_CMP_LE_REG_CONST)) {
            printf ("R%i %s %in", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
        }
        else if (p == OP_ASSIGNMENT_REG_CONST) {
            printf ("R%i %s %in", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
        }
        else {
            if ((p == OP_INC_REG_REG_CONST) || (p == OP_INC_REG_REG_REG) || (p == OP_DEC_REG_REG_CONST) || (p == OP_DEC_REG_REG_REG)) {
                printf ("R%i %s R%i %sn", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p]);
                get (STACK_OP3);
            }
            else if ((p >= OP_ADD_REG_REG_CONST) \&amp;\&amp; (p <= OP_EXOR_REG_REG_CONST))
                printf ("R%i %s R%i %s %in", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
            else
                printf ("R%i %s R%i %s R%in", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
        }
    }
}

int expr0 () {
    printf BITTE IM PDF NACHGUCKEN
    printf ("R%i %s %i", get (STACK_OP1), op_names [get (STACK_OPCODE)], get(STACK_OP2));
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    printf (""};n");
return 0;
}


int expr (int z, int zs, int dir) {
    int p = get (STACK_OPCODE);
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    if (p == OP_ASSIGNMENT_REG_CONST) {
            printf ("R%i %s %i", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
    }
    else if ((p == OP_INC_REG_REG_CONST) || (p == OP_INC_REG_REG_REG) || (p == OP_DEC_REG_REG_CONST) || (p == OP_DEC_REG_REG_REG)) {
        printf ("R%i %s R%i %s", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p]);
        get (STACK_OP3);
    }
    else if ((p >= OP_ADD_REG_REG_CONST) \&amp;\&amp; (p <= OP_EXOR_REG_REG_CONST))
        printf ("R%i %s R%i %s %i", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
    else {
        printf ("R%i %s R%i %s R%i", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
    }

   printf (""};n");
    if (dir == NO) {
        printf ("\draw [->] (z%i) -- (z%i);nn", zs, z);
    }
    else if (dir == WEST) {
        printf ("\draw [->] (z%i.west) -- (z%i);nn", zs, z);
    }
    else if (dir == EAST) {
        printf ("\draw [->] (z%i.east) -- (z%i);nn", zs, z);
    }

return z;
}

int cond (int z, int zs, int dir) {
    int p = get (STACK_OPCODE);
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    //printf BITTE IM PDF NACHGUCKEN
    printf ("R%i %s %i", get (STACK_OP1), op_names [p], get(STACK_OP2));
    get (STACK_OP3);
    printf (""};n");
    if (dir == NO) {
        printf ("\draw [->] (z%i) -- (z%i);nn", zs, z);
    }
    else if (dir == WEST) {
        printf ("\draw [->] (z%i.west) -- (z%i);nn", zs, z);
    }
    else if (dir == EAST) {
        printf ("\draw [->] (z%i.east) -- (z%i);nn", zs, z);
    }

    return z;
}


/*int as (int z, int zs, int dir) {
    int ztmp;
    int r;
    if ((r = (rand () % 8)) < 2) {
        z = ztmp = cond (z+1, z, dir);
        z = expr (z+1, ztmp, WEST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);
        z = expr (z+1, ztmp, EAST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);

    }
    else if ((r >= 2) \&amp;\&amp; (r <= 5)) {
        ztmp = z;
        z = expr (z+1, ztmp, dir);
        as (z, ztmp, NO);
    }
return z;
}

*/

int as (int z, int zs, int dir, int steps) {
    int ztmp;
    int r, rtmp;
    int stepsr;
    int stepss;


    if (steps > 0) {
        r = get (STACK_OPCODE);
        if ((r >= OP_CMP_EQ_REG_CONST) \&amp;\&amp; (r <= OP_CMP_LE_REG_CONST)){
            unget (STACK_OPCODE);
            z = ztmp = cond (z+1, z, dir);
            stepsr = (rand () % steps)-1;
            stepss = steps - stepsr;
            z = as (z, z, WEST, stepsr);
            z = as (z, z, EAST, stepss);
        }
        else if (r != EMPTY) {
            unget (STACK_OPCODE);
            z = expr (z+1, zs, dir);
            ztmp = z;
            as (z, ztmp, NO, steps-1);
        }
        else
            return STACK_UNDERFLOW;
    }
return z;
}






int main (void) {
    time_t t;
    int j;
    srand (t = time(NULL));
    expr0();
    printf ("Hallon");
    //as (0, 0, NO);
    init_stack ();
    queue_init ();
    init ();
    test_output ();
    queue_init ();
    as (0, 0, NO, getstckptr (STACK_OPCODE));
return 0;
}

Einigen wird zum Wundern zum Mute gewesen sein. Ich löse ihnen das Problem einfach

Also, ganz langsam. sie müssen unterscheiden

  1. Zwischen dem Schaltwerk - nämlich dem Steuerwerk, also, das was das Steuerwerk macht

  2. Zweitens zwischen dem Operationswerk

Natürlich hatten wir einen gravierenden Fehler

  1. Die Verwendung der Schlange war schon richtig

  2. Gleichzeitig des Stacks

So etwas gibt es in der Informatik als Datenstruktur und nennt sich

doubled ended queue

Das ist ein Stack, der gleichzeitig eine Schlange ist. So sehr das im Schaltwerk nur als Schlange entgegen tritt, so brauchen wir doch den Stack. Lassen wir es dabei

Wir haben ein Problem, gehabt, bisher

  1. Zunächst die Verwendung der
    >pop
    
    im Automaten nachher waren falsch. Hier müssen wir eine Schlange verwenden

  2. Wir hatten noch ein Problem

    Nach dem alten System hat die Condition mindestens zwei Zust"ande auf beiden Seiten aufgerufen. Eine Condition hat eine Rechte Seite und eine Linke. Gut, auf beide sollen mindestens zwei Zust"ande folgen
    

    Was haben wir gemacht? Vergessen sie nicht, wir haben es mit einer Mischung aus Generator und Compiler zu tun. Es ist irgendwo ein Compiler, aber auch ein Generator. Ein Generator tut etwas anderes, als ein Compiler

    Ein Compiler wird über die Eingabe gesteuert. Ein Generator erzeugt eine Ausgabe, aber nicht anhand einer existierenden Eingabe. Sondern er bedient sich Zufallszahlen. Nälmlich indem er entscheidet, was als nächstes kommt

Aber vergessen sie nicht

  1. wir haben ein Schaltwerk (Steuerwerk)

  2. Wir haben RTL-Notation (Operationswer)

Das sind eigentlich zwei Generatoren

  1. wir haben ein Schaltwerk (Steuerwerk) => Das ASM.Diagramm regelt das Steuerwerk

  2. Wir haben RTL-Notation (Operationswer) => Die RTL-Notation regelt das Operationswerk

Nun, schauen wir uns Ausdrücke der Art

((A + B) AND C)*D AND A

An. Es sind Ausdrücke in der Backus Naur Form, allerdings wurden sie erweitert, um die logischen Operationen

AND
OR
NOT
EXOR

Im Prinzip haben wir mit der RTL-Notation die möglichkeit Ausdrücke der Art

((A+B)+C)+D

zu lösen. Unser Schaltwerk kann mehr. Durch das ASM-Diagramm werden Verzweigungen möglich. Und was unser Komplexes Schaltwrek tut, ist nichts anderes. Also Ausdrücke in der wirklichen Bakus Naur Form zu lösen

Nämlich dem System der Gruppe, bzw. dem Körper der Ganzen Zahlen. Es erfüllt

(A+B)*C

Im Prinzip ist dieses Schaltwerk perfekt, um auf der Realen Maschine Ausdrücke mit ganzen Zahlen zu lösen. Und was ist das? Alles berechenbare quasi. Aber was die Condition möglich macht, ist umgangssprachlich gesagt, die Multiplikation

Doch wie wird das möglich

Erst durch das Steuerwerk

Nur durch das Steuerwerk findet die Wiederholung statt. Doch wir haben einen Generator. Und vergessen sie nicht

  1. Operationswerk

  2. Steuerwerk

Insofern ist es eine Frage, des Steuerwerks, wo wir unsere Multiplikation unterbringen

Doch unser Generator hat zwei Teile

  1. Operationswerk

  2. Steuerwerk

Die Generierung des Steuerwerks ist eine andere als die des Operationswerks. Gut - damit wäre alles gesagt, wo unsere Condition eine Abzweigung macht, ist eben reiner Zufall

Wir haben nur ein Problem. die bisherige Schreibweise versagte

Sie tat folgendes

Sie rief eine Condition auf
Rief ein Mal einen Zustand und noch mal einen Zustand auf der Linken Seite auf
Und das ganze noch mal auf der Rechten

Das ist falsch. Doch wir bedienen uns nun eines Tricks, damit gesichert ist, auf beiden Seiten der Condition stehen entsprechend viele Zustände.

int as (int z, int zs, int dir, int steps) {
    int ztmp;
    int r, rtmp;
    int stepsr;
    int stepss;


    if (steps > 0) {
        r = get (STACK_OPCODE);
        if ((r >= OP_CMP_EQ_REG_CONST) \&amp;\&amp; (r <= OP_CMP_LE_REG_CONST)){
            unget (STACK_OPCODE);
            z = ztmp = cond (z+1, z, dir);
            stepsr = (rand () % steps)-1;
            stepss = steps - stepsr;
            z = as (z, z, WEST, stepsr);
            z = as (z, z, EAST, stepss);
        }
        else if (r != EMPTY) {
            unget (STACK_OPCODE);
            z = expr (z+1, zs, dir);
            ztmp = z;
            as (z, ztmp, NO, steps-1);
        }
        else
            return STACK_UNDERFLOW;
    }
return z;
}

Wir führe eine Variable ein, die sagt, wie viele Zustände folgen werden. Es dürfen niemals mehr als die Gesamtzahl sein. Es sollten auf der einen Seite eine Menge sein und auf der anderen.

Wo am Ende unsere weiteren Conditions stehen ist letzten Endes egal. Weil es ist ja ein Generator.

Image main3.jpeg-1

Das sieht doch schon mal ganz ordentlich aus.

Wir erkennen allerdings ein paar Fehler

  1. Zunächst sollten wir zumindest für den Anfang längere Beispiele erzeugen, um zu sehen, es tut

  2. Die Conditions verwenden neue Register. Die Conditions sollten keine Register durchzählen

  3. Die Register der ersten Ausdrücke verweisen auf negative Register

  4. Die erste Anweisung muss bearbeitet werden

    Hier habe ich nämlich etwas gepfuscht. So sieht der von mir modifizierte Code aus

    begin{tikzpicture}[%
        >=triangle 60,              % Aussehen der Pfeile
        start chain=going below,    % Richtung von oben nach unten
        node distance=6mm and 60mm, % Abst"ande der Boxen
        every join/.style={norm},
        ]
        tikzset{% Boxen und Koordinaten
      base/.style={draw, on chain, on grid, align=center, minimum height=4ex},
      zbox/.style={base, rectangle, text width=8em},
      ebox/.style={base, diamond, aspect=1.5, text width=10em},
      term/.style={zbox, rounded corners},
      norm/.style={->, draw},
      coord/.style={coordinate, on chain, on grid, node distance=6mm and 25mm}}
    
    % Zustand 0, Box und Zustandsname
    node [zbox] (z1) {verb"R0 <- 10"};
    
    
    node [zbox] (z2) {verb"R1 <- R0 or R-1"};
    draw [->] (z1) -- (z2);
    
    node [zbox] (z3) {verb"R2 <- R1 not R-1"};
    draw [->] (z2) -- (z3);
    
    node [zbox] (z4) {verb"R3 <- R2 + 29"};
    draw [->] (z3) -- (z4);
    
    node [zbox] (z5) {verb"R4 <- R3 or 24"};
    draw [->] (z4) -- (z5);
    
    node [ebox] (z6) {verb"R5 <= 4"};
    draw [->] (z5) -- (z6);
    
    node [zbox, below=of z6.west, yshift=-4em] (z7) {verb"R6 <- R5 not 7"};
    draw [->] (z6.west) -- (z7);
    
    node [zbox] (z8) {verb"R7 <- R6 and R-1"};
    draw [->] (z7) -- (z8);
    
    node [zbox, below=of z6.east, yshift=-4em] (z8) {verb"R8 <- R7 <| R4"};
    draw [->] (z6.east) -- (z8);
    
    node [zbox] (z9) {verb"R9 <- R8 >> 20"};
    draw [->] (z8) -- (z9);
    
    
    
    end{tikzpicture}
    

    Also

    node [zbox] (z1) {verb"R0 <- 10"};
    
    
    node [zbox] (z2) {verb"R1 <- R0 or R-1"};
    draw [->] (z1) -- (z2);
    
    node [zbox] (z3) {verb"R2 <- R1 not R-1"};
    draw [->] (z2) -- (z3);
    
    node [zbox] (z4) {verb"R3 <- R2 + 29"};
    draw [->] (z3) -- (z4);
    
    node [zbox] (z5) {verb"R4 <- R3 or 24"};
    draw [->] (z4) -- (z5);
    
    node [ebox] (z6) {verb"R5 <= 4"};
    draw [->] (z5) -- (z6);
    
    node [zbox, below=of z6.west, yshift=-4em] (z7) {verb"R6 <- R5 not 7"};
    draw [->] (z6.west) -- (z7);
    
    node [zbox] (z8) {verb"R7 <- R6 and R-1"};
    draw [->] (z7) -- (z8);
    
    node [zbox, below=of z6.east, yshift=-4em] (z8) {verb"R8 <- R7 <| R4"};
    draw [->] (z6.east) -- (z8);
    
    node [zbox] (z9) {verb"R9 <- R8 >> 20"};
    draw [->] (z8) -- (z9);
    

    In der Realität sieht er so aus

    node [zbox] (z1) {verb"R0 <- 10"};
    draw [->] (z0) -- (z1);
    
    node [zbox] (z2) {verb"R1 <- R0 or R-1"};
    draw [->] (z1) -- (z2);
    
    node [zbox] (z3) {verb"R2 <- R1 not R-1"};
    draw [->] (z2) -- (z3);
    
    node [zbox] (z4) {verb"R3 <- R2 + 29"};
    draw [->] (z3) -- (z4);
    
    node [zbox] (z5) {verb"R4 <- R3 or 24"};
    draw [->] (z4) -- (z5);
    
    node [ebox] (z6) {verb"R5 <= 4"};
    draw [->] (z5) -- (z6);
    
    node [zbox, below=of z6.west, yshift=-4em] (z7) {verb"R6 <- R5 not 7"};
    draw [->] (z6.west) -- (z7);
    
    node [zbox] (z8) {verb"R7 <- R6 and R-1"};
    draw [->] (z7) -- (z8);
    
    node [zbox, below=of z6.east, yshift=-4em] (z8) {verb"R8 <- R7 <| R4"};
    draw [->] (z6.east) -- (z8);
    
    node [zbox] (z9) {verb"R9 <- R8 >> 20"};
    draw [->] (z8) -- (z9);
    
    Dieses Problem taucht auf, wenn man sich nicht drum kümmert. Der erste Zutand 0 Zustand, wird wieder auf einen 0 Zustand verweisen, den es nicht gibt. Das muss unterbleiben, zum Beispiel indem der Null Zustand seperat erzeugt wird.

Jetzt gibt es ein paar Kleinigkeiten für später zu klären

  1. Die Entscheidungsboxen sollten sinnvolle Vergleichswerte enthalten. Also müssen durchläufe stattfinden. Die Register müssen nachgebildet werden. Es muss ein oberer Wert und ein unterer Wert berechnet werden. Am Besten wäre es als Eingangsvektor keine Konstante zu nehmen, sondern Variable werte. Für alle Werte muss ein Minimalwert errechnet werden, der (!) auf jeden Fall erreicht wird (!) ein Maximalwert der auf jeden Fall erreicht wird. Es sollte davon ausgegangen werden, die Verzweigung wird 3 bis 4x ausgeführt

  2. Viele Werden sich an der Wahl der Register stören. Wenn ich

    r0 <- 1
    r1 <- r0 + 1
    r2 <- r1 + 1
    r3 <- r2 + 1
    ...
    

    Sind dies auf der einen Seite sinnvolle Datenabhängigkeiten. So muss das Problem aber nicht gelöst werden. Es handelt sich um Echte Datenahängigkeite Echte Datenabhängigkeiten, dieser Struktur lassen sich aber anders lösen

    r0 <- 1
    r1 <- r0+1
    r0 <- r1+1
    r1 <- r0 +1
    

    Warum? Die Werte können hin und her pendeln. Denn - es findet echte Datenabhängigkeit statt. Aber - so seltsam es klingt - die ED schaltet die ED aus. Denn das Register wrude schon verwendet, wieder

    Irgendwo absurd. Aber es liesse sich durch Ausdrücke der Art

    A <- 0
    A <- A + 1
    

    Lösen. Bitte denken sie nichts falsches. Aus sicht des Compilerbaus nicht falsch. Denn mit wenigen Schritten, hätten wir das Program modifziert und Eingangsvariablen

    A, B, C
    

    Damit Ausdrücke

    ((A+B)*C+B)*A
    

    Denken sie nichts falsches. Denken sie nicht so. Denken sie Compilerbau. Es geht um die Struktur des Programms. Mit wenigen Schritten führen wir neue Variablen ein. beim Compilerbau und Bakus Naur Form geht es um Ausdrücke. Gut

    OK - und das nächste wäre. Wenn wir allerdings in einer Verzweigung sind, dürfen wir

    r0
    r1
    

    Unter Umständen nicht ungeniert weiter verwenden. Warum? Ganz einfach. Sie könnten als Abfrage Kriterium in der Bedingung gelten und der Teil der Verzweigung etwas anderes darstellen

Das waren nur Überlegungen.

So, ich habe das Programm jetzt weitest gehened verbessert

david@laptop-peaq:~\$ ./a.out
node [zbox] (z0) {verb"R-2 (null) -2 \&amp;\&amp;  98 "};


0



6

R0 <- 3
R0 == 21
R1 <- R0 + R0
R2 <- R1 - R0
R3 <- R2 + 28
R4 <- R3 |> 22
R5 <- R4 + R0
R6 <- R5 or R2
R6 > 25
R7 <- R6 and 7
node [zbox] (z1) {verb"R0 <- 3"};
node [ebox] (z2) {verb"R0 == 21"};
draw [->] (z1) -- (z2);

node [zbox, below=of z2.west, yshift=-4em] (z3) {verb"R1 <- R0 + R0"};
draw [->] (z2.west) -- (z3);

node [zbox, below=of z2.east, yshift=-4em] (z4) {verb"R2 <- R1 - R0"};
draw [->] (z2.east) -- (z4);

node [zbox] (z5) {verb"R3 <- R2 + 28"};
draw [->] (z4) -- (z5);

node [zbox] (z6) {verb"R4 <- R3 |> 22"};
draw [->] (z5) -- (z6);

node [zbox] (z7) {verb"R5 <- R4 + R0"};
draw [->] (z6) -- (z7);

node [zbox] (z8) {verb"R6 <- R5 or R2"};
draw [->] (z7) -- (z8);

node [ebox] (z9) {verb"R6 > 25"};
draw [->] (z8) -- (z9);

node [zbox, below=of z9.west, yshift=-4em] (z10) {verb"R7 <- R6 and 7"};
draw [->] (z9.west) -- (z10);

david@laptop-peaq:~\$ ./a.out
node [zbox] (z0) {verb"R-2 (null) -2 \&amp;\&amp;  d "};


1

R0 <- 11
R1 <- R0 ++
R1 != 14
R2 <- R1 ++
R3 <- R2 ++
R4 <- R3 - 23
R5 <- R4 or R2
node [zbox] (z1) {verb"R0 <- 11"};
node [zbox] (z2) {verb"R1 <- R0 ++"};
draw [->] (z1) -- (z2);

node [ebox] (z3) {verb"R1 != 14"};
draw [->] (z2) -- (z3);

node [zbox, below=of z3.west, yshift=-4em] (z4) {verb"R2 <- R1 ++"};
draw [->] (z3.west) -- (z4);

node [zbox] (z5) {verb"R3 <- R2 ++"};
draw [->] (z4) -- (z5);

node [zbox, below=of z3.east, yshift=-4em] (z5) {verb"R4 <- R3 - 23"};
draw [->] (z3.east) -- (z5);

node [zbox] (z6) {verb"R5 <- R4 or R2"};
draw [->] (z5) -- (z6);

david@laptop-peaq:~\$ ./a.out
node [zbox] (z0) {verb"R-2 (null) -2"};


3

R0 <- 1
R1 <- R0 xor 11
R2 <- R1 <| 24
R3 <- R2 or R0
R3 >= 7
R4 <- R3 xor R0
R5 <- R4 and 9
R6 <- R5 |> 19
R7 <- R6 |> R0
node [zbox] (z1) {verb"R0 <- 1"};
node [zbox] (z2) {verb"R1 <- R0 xor 11"};
draw [->] (z1) -- (z2);

node [zbox] (z3) {verb"R2 <- R1 <| 24"};
draw [->] (z2) -- (z3);

node [zbox] (z4) {verb"R3 <- R2 or R0"};
draw [->] (z3) -- (z4);

node [ebox] (z5) {verb"R3 >= 7"};
draw [->] (z4) -- (z5);

node [zbox, below=of z5.west, yshift=-4em] (z6) {verb"R4 <- R3 xor R0"};
draw [->] (z5.west) -- (z6);

node [zbox] (z7) {verb"R5 <- R4 and 9"};
draw [->] (z6) -- (z7);

node [zbox] (z8) {verb"R6 <- R5 |> 19"};
draw [->] (z7) -- (z8);

node [zbox, below=of z5.east, yshift=-4em] (z7) {verb"R7 <- R6 |> R0"};
draw [->] (z5.east) -- (z7);

david@laptop-peaq:~\$ ./a.out
node [zbox] (z0) {verb"R-2 (null) -2 >>  106 "};
R0 <- 4
R1 <- R0 --
R2 <- R1 or R0
R3 <- R2 --
R4 <- R3 not R2
R5 <- R4 or 7
R6 <- R5 << 30
R7 <- R6 >> R4
node [zbox] (z1) {verb"R0 <- 4"};
node [zbox] (z2) {verb"R1 <- R0 --"};
draw [->] (z1) -- (z2);

node [zbox] (z3) {verb"R2 <- R1 or R0"};
draw [->] (z2) -- (z3);

node [zbox] (z4) {verb"R3 <- R2 --"};
draw [->] (z3) -- (z4);

node [zbox] (z5) {verb"R4 <- R3 not R2"};
draw [->] (z4) -- (z5);

node [zbox] (z6) {verb"R5 <- R4 or 7"};
draw [->] (z5) -- (z6);

node [zbox] (z7) {verb"R6 <- R5 << 30"};
draw [->] (z6) -- (z7);

node [zbox] (z8) {verb"R7 <- R6 >> R4"};
draw [->] (z7) -- (z8);

david@laptop-peaq:~\$

/*
Grammatik

Sporadische Sammlung
- Zuweisung
- Addition
if
- Vergleiche
    - <=, >=, ==, !=, <, >
- Subtraktion
- Shift
    << >>
- Null setzen

Operationen
    - Mathematische:
        + (Addition)
        - (Subtraktion)
    - Verschieben
        >> Rechtsshift
        << Linksshift
    - 0 setzen
Vergleiche
    - <=, >=, ==, !=, <, >
Zuweisung
    <-

Zeichensatz: Variablen, Register, Operatoren und Konstante Werte

Operand ::= <Register> | <Const>
CMP ::= <= | >= | == | != | < | >
MathOperator ::= + | - | << | >>
BitBooleanOperator ::= '\&amp;\&amp;' | '||' | '!'
Operator ::= <MathOperator> | <BitBooleanOperator>
Expr ::= <Register> <- <Operand> | <Operand> <Operator> <Operand> | 0
Condition ::= IF <Register> <CMP> <Operand> THEN <Program> FI

Programm ::= <Expr> | <Condition> <Program>
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define     MAX_STATES                              1024
#define     MAX_EXPR_CONST_VAL                      128
#define     MAX_EXPR_REG_VAL                        4
#define     FIRST_REG_VAL                           'a'
#define     MAX_EXPR_OPERATOR_VAL                   6
#define     MAX_EXPR_CMP_OPERATOR_VAL               5
#define     RAND_OPERAND_CONST_REGISTER             2
#define     RAND_EXPR_OPERATOR_OPERAND_FOLLOW       2
#define     RAND_COND_TRUE_FALSE_DESICION           2
#define     RAND_PROGRAM_COND_EXPR_DESICION         4
#define     IF_ELSE_DEPTH                           3
#define     STD_PROGRAM_N                           6
#define     STD_PROGRAM2_N                          4
#define     RAND_COND_END_OR_GO_ON                  3

FILE *fout = NULL;

int line = 0;
int nline = 1;
int maxstate = 0;

char *opstr [] = {"+", "-", "<<", ">>", "\&amp;\&amp;", "||", "!"};
char *cmpstr [] = {"<=", ">=", "==", "!=", "<", ">"};


void registr (void) {
    printf (" %c ", (rand () % MAX_EXPR_REG_VAL) + FIRST_REG_VAL);
return;
}

void cnst (void) {
    printf (" %i ", rand () % MAX_EXPR_CONST_VAL);
return;
}

void operator (void) {
    printf (" %s ", opstr [rand () % MAX_EXPR_OPERATOR_VAL]);
return;
}

void cmp (void) {
    printf (" %s ", cmpstr [rand () % MAX_EXPR_CMP_OPERATOR_VAL]);
return;
}

void operand (void) {
    if ((rand () % RAND_OPERAND_CONST_REGISTER) == 0)
        cnst ();
    else
        registr ();
return;
}

#define NO      0
#define WEST    1
#define EAST    2

#define MAX_NODES                   64
#define STACKS_MAX                  4

char *op_names [] = {"==",
    "!=",
    ">",
    ">=",
    "<",
    "<=",
    "+",
    "++",
    "-",
    "--",
    "<<",
    ">>",
    "<|",
    "|>",
    "and",
    "not",
    "or",
    "xor",
    "+",
    "++",
    "-",
    "--",
    "<<",
    ">>",
    "<|",
    "|>",
    "and",
    "not",
    "or",
    "xor",
    "<-"
};

#define OP_CMP_EQ_REG_CONST         0
#define OP_CMP_NE_REG_CONST         1
#define OP_CMP_GR_REG_CONST         2
#define OP_CMP_GE_REG_CONST         3
#define OP_CMP_LT_REG_CONST         4
#define OP_CMP_LE_REG_CONST         5
#define OP_ADD_REG_REG_CONST        6
#define OP_INC_REG_REG_CONST        7
#define OP_SUB_REG_REG_CONST        8
#define OP_DEC_REG_REG_CONST        9
#define OP_SLL_REG_REG_CONST        10
#define OP_SLR_REG_REG_CONST        11
#define OP_RL_REG_REG_CONST       12
#define OP_RR_REG_REG_CONST       13
#define OP_AND_REG_REG_CONST      14
#define OP_NOT_REG_REG_CONST      15
#define OP_OR_REG_REG_CONST       16
#define OP_EXOR_REG_REG_CONST     17
#define OP_ADD_REG_REG_REG        18
#define OP_INC_REG_REG_REG        19
#define OP_SUB_REG_REG_REG        20
#define OP_DEC_REG_REG_REG        21
#define OP_SLL_REG_REG_REG        22
#define OP_SLR_REG_REG_REG        23
#define OP_RL_REG_REG_REG         24
#define OP_RR_REG_REG_REG         25
#define OP_AND_REG_REG_REG        26
#define OP_NOT_REG_REG_REG        27
#define OP_OR_REG_REG_REG         28
#define OP_EXOR_REG_REG_REG       29
#define OP_ASSIGNMENT_REG_CONST   30
#define NA                        -1
#define EMPTY                       -2
#define STACK_UNDERFLOW             -3

#define STACK_OPCODE                0
#define STACK_OP1                   1
#define STACK_OP2                   2
#define STACK_OP3                   3

#define MAX_COND                    3
#define CONST_MAX                   32


int stack [STACKS_MAX][MAX_NODES];
int stack2 [MAX_NODES];
int stack_ptr [STACKS_MAX];
int queue_ptr [STACKS_MAX];
int stack_ptr2 = 0;

void init_stack (void) {
    int i;
    for (i = 0;  i < STACKS_MAX;  i++) {
        stack_ptr [i] = 0;
    }
return;
}

void queue_init (void) {
    int i;
    for (i = 0;  i < STACKS_MAX;  i++) {
        queue_ptr [i] = 0;
    }
return;
}

void push (int stck, int v) {
    if (stack_ptr[stck] < (MAX_NODES-1)) {
        stack [stck][stack_ptr [stck]] = v;
        stack_ptr [stck]++;
    }
return;
}

int pop (int stck) {
    if (stack_ptr [stck] > 0) {
        stack_ptr [stck]--;
        return stack [stck][stack_ptr [stck]];
    }
    else
        return STACK_UNDERFLOW;
}

int getstckptr (int stck) {
    return stack_ptr [stck];
}

int get (int stck) {
    if (queue_ptr [stck] < stack_ptr [stck]) {
        return stack [stck][queue_ptr [stck]++];
    }
    else return EMPTY;
}
void unget (int stck) {
    if (queue_ptr [stck] > 0)
        queue_ptr [stck]--;
}


void push2 (int v) {
    if (stack_ptr2 < (MAX_NODES-1)) {
        stack2 [stack_ptr2] = v;
        stack_ptr2++;
    }
}

int pop2 (void) {
    if (stack_ptr2 > 0) {
        stack_ptr2--;
        return stack2 [stack_ptr2];
    }
}

int regmax = 0;


/*
 * reg ::= op reg reg reg | op reg reg const | op const
 * cond ::= op_cmp reg const addr1 addr2
 */

void init () {
    int i = 0;
    int cond_count = MAX_COND;
    int cond_least = 0;
    int op;
    int imax = (rand () % 6) + 5;
    int lastreg;
    int r;

    push (STACK_OPCODE, OP_ASSIGNMENT_REG_CONST);           // Assignment at begin
    push (STACK_OP1, 0);                                    // Register R0 ()
    push (STACK_OP2, rand () % CONST_MAX);                  // Const
    push (STACK_OP3, NA);                                   // Operand 3, assignment, not given

    for (i = 1;  i < imax;  i++) {
        op = rand () % (OP_EXOR_REG_REG_REG+1);
        if ((op <= OP_CMP_LE_REG_CONST) \&amp;\&amp; (cond_least == 0)) {
            if (cond_count > 0) {
                cond_count--;
                lastreg = pop (STACK_OP1);
                push (STACK_OP1, lastreg);
                push (STACK_OPCODE, op);
                push (STACK_OP1, lastreg);
                printf ("nn%inn", lastreg);
                push (STACK_OP2, rand () % CONST_MAX);
                push (STACK_OP3, NA );
                cond_least = 2;
                if ((i + cond_least) > imax) {
                    imax += cond_least;
                }
                push2 (i);
            }
            else {
                i--;
            }
        }
        else if (op > OP_CMP_LE_REG_CONST){
                if (cond_least != 0)
                    cond_least--;
                lastreg = pop (STACK_OP1);
                push (STACK_OP1, lastreg);
                push (STACK_OPCODE, op);
                push (STACK_OP1, lastreg+1);
                push (STACK_OP2, lastreg);
                if ((op >= OP_ADD_REG_REG_REG) \&amp;\&amp; (op <= OP_EXOR_REG_REG_REG)) {
                    r = (rand () % (lastreg+1))-1;
                    if (r < 0)
                        r = 0;
                    push (STACK_OP3, r);
                }
                else
                    push (STACK_OP3, rand () % CONST_MAX);
        }
        else
            i--;
    }
    push (STACK_OPCODE, EMPTY);
    push (STACK_OP1, EMPTY);
    push (STACK_OP2, EMPTY);
    push (STACK_OP3, EMPTY);
}

void test_output (void) {
    int p, o1, o2, o3;

    while ((p = get (STACK_OPCODE)) != EMPTY) {
        if ((p >= OP_CMP_EQ_REG_CONST) \&amp;\&amp; (p <= OP_CMP_LE_REG_CONST)) {
            printf ("R%i %s %in", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
        }
        else if (p == OP_ASSIGNMENT_REG_CONST) {
            printf ("R%i %s %in", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
        }
        else {
            if ((p == OP_INC_REG_REG_CONST) || (p == OP_INC_REG_REG_REG) || (p == OP_DEC_REG_REG_CONST) || (p == OP_DEC_REG_REG_REG)) {
                printf ("R%i %s R%i %sn", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p]);
                get (STACK_OP3);
            }
            else if ((p >= OP_ADD_REG_REG_CONST) \&amp;\&amp; (p <= OP_EXOR_REG_REG_CONST))
                printf ("R%i %s R%i %s %in", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
            else
                printf ("R%i %s R%i %s R%in", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
        }
    }
}

int expr0 () {
    printf BITTE IM PDF NACHGUCKEN
    printf ("R%i %s %i", get (STACK_OP1), op_names [get (STACK_OPCODE)], get(STACK_OP2));
    if ((rand () % RAND_EXPR_OPERATOR_OPERAND_FOLLOW) == 0) {
        operator ();
        operand ();
    }
    printf (""};n");
return 0;
}


int expr (int z, int zs, int dir) {
    int p = get (STACK_OPCODE);
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    if (p == OP_ASSIGNMENT_REG_CONST) {
            printf ("R%i %s %i", get (STACK_OP1), op_names [p], get(STACK_OP2));
            get (STACK_OP3);
    }
    else if ((p == OP_INC_REG_REG_CONST) || (p == OP_INC_REG_REG_REG) || (p == OP_DEC_REG_REG_CONST) || (p == OP_DEC_REG_REG_REG)) {
        printf ("R%i %s R%i %s", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p]);
        get (STACK_OP3);
    }
    else if ((p >= OP_ADD_REG_REG_CONST) \&amp;\&amp; (p <= OP_EXOR_REG_REG_CONST))
        printf ("R%i %s R%i %s %i", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
    else {
        printf ("R%i %s R%i %s R%i", get (STACK_OP1), op_names [OP_ASSIGNMENT_REG_CONST], get (STACK_OP2), op_names [p],  get (STACK_OP3));
    }

   printf (""};n");
   if (z != 1) {
        if (dir == NO) {
            printf ("\draw [->] (z%i) -- (z%i);nn", zs, z);
        }
        else if (dir == WEST) {
            printf ("\draw [->] (z%i.west) -- (z%i);nn", zs, z);
        }
        else if (dir == EAST) {
            printf ("\draw [->] (z%i.east) -- (z%i);nn", zs, z);
        }
   }

return z;
}

int cond (int z, int zs, int dir) {
    int p = get (STACK_OPCODE);
    if (dir == NO) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == WEST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    else if (dir == EAST) {
        printf BITTE IM PDF NACHGUCKEN
    }
    //printf BITTE IM PDF NACHGUCKEN
    printf ("R%i %s %i", get (STACK_OP1), op_names [p], get(STACK_OP2));
    get (STACK_OP3);
    printf (""};n");
    if (z != 1) {
        if (dir == NO) {
            printf ("\draw [->] (z%i) -- (z%i);nn", zs, z);
        }
        else if (dir == WEST) {
            printf ("\draw [->] (z%i.west) -- (z%i);nn", zs, z);
        }
        else if (dir == EAST) {
            printf ("\draw [->] (z%i.east) -- (z%i);nn", zs, z);
        }
    }

    return z;
}


/*int as (int z, int zs, int dir) {
    int ztmp;
    int r;
    if ((r = (rand () % 8)) < 2) {
        z = ztmp = cond (z+1, z, dir);
        z = expr (z+1, ztmp, WEST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);
        z = expr (z+1, ztmp, EAST);
        z = expr (z+1, z, NO);
        z = as (z, z, NO);

    }
    else if ((r >= 2) \&amp;\&amp; (r <= 5)) {
        ztmp = z;
        z = expr (z+1, ztmp, dir);
        as (z, ztmp, NO);
    }
return z;
}

*/

int as (int z, int zs, int dir, int steps) {
    int ztmp;
    int r, rtmp;
    int stepsr;
    int stepss;


    if (steps > 0) {
        r = get (STACK_OPCODE);
        if ((r >= OP_CMP_EQ_REG_CONST) \&amp;\&amp; (r <= OP_CMP_LE_REG_CONST)){
            unget (STACK_OPCODE);
            z = ztmp = cond (z+1, z, dir);
            stepsr = (rand () % steps)-1;
            stepss = steps - stepsr;
            z = as (z, z, WEST, stepsr);
            z = as (z, ztmp, EAST, stepss);
        }
        else if (r != EMPTY) {
            unget (STACK_OPCODE);
            z = expr (z+1, zs, dir);
            as (z, z, NO, steps-1);
        }
        else
            return STACK_UNDERFLOW;
    }
return z;
}






int main (void) {
    time_t t;
    int j;
    srand (t = time(NULL));
    expr0();
    //as (0, 0, NO);
    init_stack ();
    queue_init ();
    init ();
    test_output ();
    queue_init ();
    as (0, 0, NO, getstckptr (STACK_OPCODE));
return 0;
}