recursive_compiler.c
changeset 30 d037c433ec3e
child 31 c95a6a7e305c
new file mode 100644
--- /dev/null
+++ b/recursive_compiler.c
@@ -0,0 +1,113 @@
+/**
+ * Ein-Pass-Compiler
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define MODE_POSTFIX   0
+#define MODE_ASSEMBLY  1
+
+char lookahead;
+int pos;
+int compile_mode;
+char expression[20 + 1];
+
+void error ()
+{
+    printf ("Syntaxfehler!\n");
+}
+
+void match (char t)
+{
+    if (lookahead == t) {
+        lookahead = expression[++pos];
+    } else
+        error ();
+}
+
+void digit ()
+{
+    switch (lookahead) {
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+        printf (compile_mode == MODE_POSTFIX ? "%c" : "\tPUSH %c\n", lookahead);
+        match (lookahead);
+        break;
+    default:
+        error ();
+        break;
+    }
+}
+
+void term ()
+{
+    digit ();
+    while (1) {
+        switch (lookahead) {
+        case '*':
+            match ('*');
+            digit ();
+            printf ("%s", compile_mode == MODE_POSTFIX ? "*" : "\tPOP B\n\tPOP A\n\tMUL A, B\n\tPUSH A\n");
+            break;
+        case '/':
+            match ('/');
+            digit ();
+            printf ("%s", compile_mode == MODE_POSTFIX ? "/" : "\tPOP B\n\tPOP A\n\tDIV A, B\n\tPUSH A\n");
+            break;
+        default:
+            return;
+        }
+    }
+}
+
+void expr ()
+{
+    term ();
+    while (1) {
+        switch (lookahead) {
+        case '+':
+            match ('+');
+            term ();
+            printf ("%s", compile_mode == MODE_POSTFIX ? "+" : "\tPOP B\n\tPOP A\n\tADD A, B\n\tPUSH A\n");
+            break;
+        case '-':
+            match ('-');
+            term ();
+            printf ("%s", compile_mode == MODE_POSTFIX ? "-" : "\tPOP B\n\tPOP A\n\tSUB A, B\n\tPUSH A\n");
+            break;
+        default:
+            return;
+        }
+    }
+}
+
+int main (int argc, char **argv)
+{
+    printf ("Bitte geben Sie einen Ausdruck in Infix-Notation ein:\n\n\t");
+    fgets (expression, 20, stdin);
+
+    printf ("\nCompilierter Ausdruck in Postfix-Notation:\n\n\t");
+    compile_mode = MODE_POSTFIX;
+    pos = 0;
+    lookahead = *expression;
+    expr ();
+
+    printf ("\n\nCompilierter Ausdruck in Assemblersprache:\n\n");
+    compile_mode = MODE_ASSEMBLY;
+    pos = 0;
+    lookahead = *expression;
+    expr ();
+
+    return 0;
+}