Re: Aufgaben und Übungen,

Ich habe den Quelltext verbessert

/*
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                           5
#define     STD_PROGRAM2_N                          4

FILE *fout = NULL;

int lineelse [MAX_STATES];
int lineif [MAX_STATES];
int linegoto1 [MAX_STATES];
int linegoto2 [MAX_STATES];
int stateif = 0;
int stateelse = 0;
int stategoto1 = 0;
int stategoto2 = 0;
int stategotodst = 0;
int gotodst [MAX_STATES];

int line = 0;
int nline = 0;
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 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;

    goto1or2 = rand () % RAND_COND_TRUE_FALSE_DESICION;


    lineif [stateif++] = line;
    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);
    linegoto1 [stategoto1++] = line;
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen+1);
    if( goto1or2 )
        fprintf (fout, " GOTO %in", lineif [gotodst[stategotodst++]]);
    else
        fprintf (fout, " GOTO %in", rand () % (nline+1));
    lineelse [stateelse++] = line;
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen);
    fprintf (fout, " ELSE n", line);
    program (n, i+1, emptyspacen+1, depth+1);
    linegoto2 [stategoto2++] = line;
    fprintf (fout, "%4c ", ' ');
    printemptyspace (emptyspacen+1);
    if ( !goto1or2)
        fprintf (fout, " GOTO %in", lineif [gotodst[stategotodst++]]);
    else
        fprintf (fout, " GOTO %in", rand () % (nline+1));
    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 ((i < n) \&amp;\&amp; (depth < IF_ELSE_DEPTH))
        condition (n, i+1, emptyspacen, depth+1);
    return;
}


void connect (int n) {
    int i;
    int j;
    int t;

    gotodst [0] = rand () % n;
    for (i = 1;  i < n; ) {
        t = rand () % n;
        for (j = 0;  j < i;  j++) {
            if (gotodst [j] == t) {
                t = rand () % n;
                j = 0;
            }
        }
        if (t != i) {
            gotodst [i] = t;
            i++;
        }
    }

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;
    /*for (j = 0;  j < stateif; j++) {
        fprintf (fout, "If %in", lineif [j]);
        fprintf (fout, "Else %in", lineelse [j]);
        fprintf (fout, "Goto 1 %in", linegoto1 [j]);
        fprintf (fout, "Goto 2 %in", linegoto2 [j]);
    }*/
    if (stateif != 0) {
        connect (stateif);
    }
    nline = line;
    line = 0;
    stategotodst = 0;
    srand (t);
    program (STD_PROGRAM_N, 0, 0, 0);
return 0;
}

Zum generieren von Übungsaufgaben von ASM-Diagrammen. Ich erkläre gleich, welche Übungsaufgaben-Generatoren ich programmiert habe - nachher. Weil: Die Aufgaben sind alle von mir gemacht. Ich habe Programme geschrieben, damit ich das üben kann.

Die erste Version von dem ASM-Diagramm-Generator, was auf dem Prinzip von Parsern beruht, hatte Macken.

Etwa, das hinter der Bedingung noch Anweisungen stehen konnten. Nun kann man sich eine Bedingung als

IF ... THEN
  ...
ELSE
  ...
FI

vorstellen. Manch einer wird sich fragen: Wozu ist das gut? Dass ich

  1. erstens:
     IF THEN ELSE
    
    beantworten

  2. Es geht nicht um das Zeichnen Lernen von ASM-Diagrammen. So gesehen macht das ja dann keinen Unterschied. Der Witz ist, dass man damit dann ein Mikroprogrammsteuerwerk zeichnen kann und ein Operationswerk. Also, man kann sehr schnell zum fertigen Steuer und Operationswerk kommen

Jetzt sind die Zustände mit Nummern versehen, die eindeutig sind

0
1
2
3
...

Auf eine Bedingung folgt, ein Folgezustand, ausgedrückt mit

GOTO

Es folgt auf

JA

und das

NEIN

Es macht keinen Sinn, wenn wir die Nummern angucken

0
1
2
3
...

Die ja, ohne Bedingung, ein Fluss sind, wenn auf ein

GOTO

Ein Block von Anweisungen, die die Reihenfolge der Zustände bedient, ein

JA

NEIN

  1. JA
    

  2. NEIN
    

  3. Folgezustand

Dann hätte die Bedingung ja drei Folgen. Wenn neben dem

JA
NEIN
Noch ein Block folgt, das
GOTO
aber nicht dahin führt, haben wir einen verweisten Block.

Das war die Verbesserung Version 2 des Übungsprogramms. Jetzt ist bei der Korrektur allerdings wieder ein Fehler passiert, der war ganz schnell korrigiert. Jetzt folgen Bedingungen auf Bedingungen und das ist ebenso, wie wenn Zustände auf Bedingungen folgen. Das heisst am Ende kann es nur eine Bedingung geben. Hier ist das Beispiel, dass es funktioniert

   0: b  <-  39  >>  62
   1: IF  d  >=  45  THEN
   2:   IF  c  ==  a  THEN
          GOTO 3
        ELSE
   3:     c  <-  18
   4:     a  <-  119
   5:     c  <-  18
          GOTO 2
        FI
        GOTO 7
      ELSE
   6:   a  <-  50
   7:   IF  c  <=  109  THEN
   8:     c  <-  c  -  14
          GOTO 7
        ELSE
   9:     c  <-  d
  10:     d  <-  c  \&amp;\&amp;  14
          GOTO 1
        FI
        GOTO 4
      FI

Und verbessert habe ich das:

Version 2:

Zeile 190 bis 197

void program (int n, int i, int emptyspacen, int depth) {
    program2 (STD_PROGRAM2_N, 0, emptyspacen, depth);
    if ((i < n) \&amp;\&amp; (depth < IF_ELSE_DEPTH)) {
        program (n, i+1, emptyspacen, depth+1);
        condition (n, i+1, emptyspacen, depth+1);
    }
    return;
}

Zu, Version 3, Zeile 190 bis 195:

void program (int n, int i, int emptyspacen, int depth) {
    program2 (STD_PROGRAM2_N, 0, emptyspacen, depth);
    if ((i < n) \&amp;\&amp; (depth < IF_ELSE_DEPTH))
        condition (n, i+1, emptyspacen, depth+1);
    return;
}