recursive_compiler.c
changeset 30 d037c433ec3e
child 31 c95a6a7e305c
equal deleted inserted replaced
29:7abf6146898e 30:d037c433ec3e
       
     1 /**
       
     2  * Ein-Pass-Compiler
       
     3  *
       
     4  */
       
     5 
       
     6 #include <stdlib.h>
       
     7 #include <stdio.h>
       
     8 #include <string.h>
       
     9 
       
    10 #define MODE_POSTFIX   0
       
    11 #define MODE_ASSEMBLY  1
       
    12 
       
    13 char lookahead;
       
    14 int pos;
       
    15 int compile_mode;
       
    16 char expression[20 + 1];
       
    17 
       
    18 void error ()
       
    19 {
       
    20     printf ("Syntaxfehler!\n");
       
    21 }
       
    22 
       
    23 void match (char t)
       
    24 {
       
    25     if (lookahead == t) {
       
    26         lookahead = expression[++pos];
       
    27     } else
       
    28         error ();
       
    29 }
       
    30 
       
    31 void digit ()
       
    32 {
       
    33     switch (lookahead) {
       
    34     case '0':
       
    35     case '1':
       
    36     case '2':
       
    37     case '3':
       
    38     case '4':
       
    39     case '5':
       
    40     case '6':
       
    41     case '7':
       
    42     case '8':
       
    43     case '9':
       
    44         printf (compile_mode == MODE_POSTFIX ? "%c" : "\tPUSH %c\n", lookahead);
       
    45         match (lookahead);
       
    46         break;
       
    47     default:
       
    48         error ();
       
    49         break;
       
    50     }
       
    51 }
       
    52 
       
    53 void term ()
       
    54 {
       
    55     digit ();
       
    56     while (1) {
       
    57         switch (lookahead) {
       
    58         case '*':
       
    59             match ('*');
       
    60             digit ();
       
    61             printf ("%s", compile_mode == MODE_POSTFIX ? "*" : "\tPOP B\n\tPOP A\n\tMUL A, B\n\tPUSH A\n");
       
    62             break;
       
    63         case '/':
       
    64             match ('/');
       
    65             digit ();
       
    66             printf ("%s", compile_mode == MODE_POSTFIX ? "/" : "\tPOP B\n\tPOP A\n\tDIV A, B\n\tPUSH A\n");
       
    67             break;
       
    68         default:
       
    69             return;
       
    70         }
       
    71     }
       
    72 }
       
    73 
       
    74 void expr ()
       
    75 {
       
    76     term ();
       
    77     while (1) {
       
    78         switch (lookahead) {
       
    79         case '+':
       
    80             match ('+');
       
    81             term ();
       
    82             printf ("%s", compile_mode == MODE_POSTFIX ? "+" : "\tPOP B\n\tPOP A\n\tADD A, B\n\tPUSH A\n");
       
    83             break;
       
    84         case '-':
       
    85             match ('-');
       
    86             term ();
       
    87             printf ("%s", compile_mode == MODE_POSTFIX ? "-" : "\tPOP B\n\tPOP A\n\tSUB A, B\n\tPUSH A\n");
       
    88             break;
       
    89         default:
       
    90             return;
       
    91         }
       
    92     }
       
    93 }
       
    94 
       
    95 int main (int argc, char **argv)
       
    96 {
       
    97     printf ("Bitte geben Sie einen Ausdruck in Infix-Notation ein:\n\n\t");
       
    98     fgets (expression, 20, stdin);
       
    99 
       
   100     printf ("\nCompilierter Ausdruck in Postfix-Notation:\n\n\t");
       
   101     compile_mode = MODE_POSTFIX;
       
   102     pos = 0;
       
   103     lookahead = *expression;
       
   104     expr ();
       
   105 
       
   106     printf ("\n\nCompilierter Ausdruck in Assemblersprache:\n\n");
       
   107     compile_mode = MODE_ASSEMBLY;
       
   108     pos = 0;
       
   109     lookahead = *expression;
       
   110     expr ();
       
   111 
       
   112     return 0;
       
   113 }