recursive_compiler.c
author Markus Bröker <mbroeker@largo.dyndns.tv>
Fri, 27 Dec 2013 16:00:09 +0100
changeset 167 7c6b221900bf
parent 131 b5ad49852adc
permissions -rw-r--r--
Proper Datatypes to leave the 80's
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
30
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
     1
/**
77
49e0babccb23 HEADER TAGS
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 48
diff changeset
     2
 * recursive_compiler.c
49e0babccb23 HEADER TAGS
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 48
diff changeset
     3
 * Adapted from: http://de.wikipedia.org/wiki/Compiler
49e0babccb23 HEADER TAGS
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 48
diff changeset
     4
 *
30
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
     5
 * Ein-Pass-Compiler
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
     6
 */
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
     7
48
b94d657a9acb Policy Inonsistency on many files
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 31
diff changeset
     8
#include <stdio.h>
30
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
     9
#include <stdlib.h>
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    10
#include <string.h>
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    11
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    12
#define MODE_POSTFIX   0
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    13
#define MODE_ASSEMBLY  1
31
c95a6a7e305c wiki synchronisation
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 30
diff changeset
    14
#define MAX           20
30
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    15
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    16
char lookahead;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    17
int pos;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    18
int compile_mode;
31
c95a6a7e305c wiki synchronisation
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 30
diff changeset
    19
char expression[MAX + 1];
30
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    20
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    21
void error ()
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    22
{
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    23
    printf ("Syntaxfehler!\n");
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    24
}
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    25
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    26
void match (char t)
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    27
{
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    28
    if (lookahead == t) {
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    29
        lookahead = expression[++pos];
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    30
    } else
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    31
        error ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    32
}
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    33
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    34
void digit ()
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    35
{
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    36
    switch (lookahead) {
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    37
    case '0':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    38
    case '1':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    39
    case '2':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    40
    case '3':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    41
    case '4':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    42
    case '5':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    43
    case '6':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    44
    case '7':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    45
    case '8':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    46
    case '9':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    47
        printf (compile_mode == MODE_POSTFIX ? "%c" : "\tPUSH %c\n", lookahead);
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    48
        match (lookahead);
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    49
        break;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    50
    default:
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    51
        error ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    52
        break;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    53
    }
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    54
}
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    55
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    56
void term ()
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    57
{
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    58
    digit ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    59
    while (1) {
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    60
        switch (lookahead) {
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    61
        case '*':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    62
            match ('*');
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    63
            digit ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    64
            printf ("%s", compile_mode == MODE_POSTFIX ? "*" : "\tPOP B\n\tPOP A\n\tMUL A, B\n\tPUSH A\n");
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    65
            break;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    66
        case '/':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    67
            match ('/');
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    68
            digit ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    69
            printf ("%s", compile_mode == MODE_POSTFIX ? "/" : "\tPOP B\n\tPOP A\n\tDIV A, B\n\tPUSH A\n");
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    70
            break;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    71
        default:
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    72
            return;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    73
        }
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    74
    }
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    75
}
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    76
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    77
void expr ()
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    78
{
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    79
    term ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    80
    while (1) {
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    81
        switch (lookahead) {
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    82
        case '+':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    83
            match ('+');
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    84
            term ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    85
            printf ("%s", compile_mode == MODE_POSTFIX ? "+" : "\tPOP B\n\tPOP A\n\tADD A, B\n\tPUSH A\n");
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    86
            break;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    87
        case '-':
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    88
            match ('-');
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    89
            term ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    90
            printf ("%s", compile_mode == MODE_POSTFIX ? "-" : "\tPOP B\n\tPOP A\n\tSUB A, B\n\tPUSH A\n");
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    91
            break;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    92
        default:
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    93
            return;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    94
        }
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    95
    }
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    96
}
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    97
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    98
int main (int argc, char **argv)
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
    99
{
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   100
    printf ("Bitte geben Sie einen Ausdruck in Infix-Notation ein:\n\n\t");
131
b5ad49852adc check for the return values
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 77
diff changeset
   101
    if (fgets (expression, MAX, stdin) == NULL)
b5ad49852adc check for the return values
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 77
diff changeset
   102
        return EXIT_FAILURE;
30
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   103
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   104
    printf ("\nCompilierter Ausdruck in Postfix-Notation:\n\n\t");
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   105
    compile_mode = MODE_POSTFIX;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   106
    pos = 0;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   107
    lookahead = *expression;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   108
    expr ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   109
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   110
    printf ("\n\nCompilierter Ausdruck in Assemblersprache:\n\n");
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   111
    compile_mode = MODE_ASSEMBLY;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   112
    pos = 0;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   113
    lookahead = *expression;
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   114
    expr ();
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   115
48
b94d657a9acb Policy Inonsistency on many files
Markus Bröker <mbroeker@largo.dyndns.tv>
parents: 31
diff changeset
   116
    return EXIT_SUCCESS;
30
d037c433ec3e kleiner auffschrischungskurs compilerbau...
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
diff changeset
   117
}