# HG changeset patch # User Markus Bröker # Date 1239878944 -7200 # Node ID d037c433ec3ecdcd5e04a1e1637db25cf84555aa # Parent 7abf6146898e83c6e4b32c8f69499a3bd26d1fd0 kleiner auffschrischungskurs compilerbau... committer: Markus Bröker diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -43,7 +43,8 @@ copy \ function_pointers \ sort \ - min2time + min2time \ + recursive_compiler .SUFFIXES: .c .cc .asm @@ -235,6 +236,10 @@ @echo Linking $< ... @$(CC) -o $@ $< +recursive_compiler: recursive_compiler.o + @echo Linking $< ... + @$(CC) -o $@ $< + .PHONY: clean uninstall clean: diff --git a/recursive_compiler.c b/recursive_compiler.c new file mode 100644 --- /dev/null +++ b/recursive_compiler.c @@ -0,0 +1,113 @@ +/** + * Ein-Pass-Compiler + * + */ + +#include +#include +#include + +#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; +}