/*
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 ("\\node [zbox] (z%i) {\\verb\"", 0);
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 ("\\node [zbox] (z%i) {\\verb\"", z);
}
else if (dir == WEST) {
printf ("\\node [zbox, below=of z%i.west, yshift=-4em] (z%i) {\\verb\"", zs, z);
}
else if (dir == EAST) {
printf ("\\node [zbox, below=of z%i.east, yshift=-4em] (z%i) {\\verb\"",zs, z);
}
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 ("\\node [ebox] (z%i) {\\verb\"", z);
}
else if (dir == WEST) {
printf ("\\node [ebox, below=of z%i.west, yshift=-4em] (z%i) {\\verb\"", zs, z);
}
else if (dir == EAST) {
printf ("\\node [ebox, below=of z%i.east, yshift=-4em] (z%i) {\\verb\"",zs, z);
}
//printf ("\\node [ebox] (z%i) {\\verb\" ", z);
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;
}