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 ::= '\&\&' | '||' | '!' 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 [] = {"+", "-", "<<", ">>", "\&\&", "||", "!"}; 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) \&\& (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 ::= '\&\&' | '||' | '!' 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 [] = {"+", "-", "<<", ">>", "\&\&", "||", "!"}; 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 \&\& 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 \&\& 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) \&\& (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.
Funktioniert perfekt
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
So, ich habe die Fehlerhafte Datei leider schon gelöscht, dafür habe ich ein besseres Beispiel, das sieht eh besser aus
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 \&\& 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 ::= '\&\&' | '||' | '!' 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 [] = {"+", "-", "<<", ">>", "\&\&", "||", "!"}; 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) \&\& (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 ::= '\&\&' | '||' | '!' 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 [] = {"+", "-", "<<", ">>", "\&\&", "||", "!"}; 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) \&\& (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) \&\& (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) \&\& (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) \&\& (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 ::= '\&\&' | '||' | '!' 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 [] = {"+", "-", "<<", ">>", "\&\&", "||", "!"}; 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) \&\& (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) \&\& (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) \&\& (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) \&\& (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) \&\& (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) \&\& (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 ::= '\&\&' | '||' | '!' 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 [] = {"+", "-", "<<", ">>", "\&\&", "||", "!"}; 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) \&\& (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) \&\& (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) \&\& (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) \&\& (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) \&\& (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) \&\& (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) \&\& (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
Natürlich hatten wir einen gravierenden Fehler
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
>popim Automaten nachher waren falsch. Hier müssen wir eine Schlange verwenden
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
Das sind eigentlich zwei Generatoren
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
Insofern ist es eine Frage, des Steuerwerks, wo wir unsere Multiplikation unterbringen
Doch unser Generator hat zwei Teile
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) \&\& (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.
Das sieht doch schon mal ganz ordentlich aus.
Wir erkennen allerdings ein paar Fehler
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
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 \&\& 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 \&\& 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 ::= '\&\&' | '||' | '!' 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 [] = {"+", "-", "<<", ">>", "\&\&", "||", "!"}; 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) \&\& (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) \&\& (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) \&\& (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) \&\& (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) \&\& (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) \&\& (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) \&\& (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; }