Parser?!
-
Hallo,
ich arbeite gerade an einem TR/Matheprogramm und wüsste gernen ob mir jmd helfen könnte.
Mein Tr soll Kettenrechnungen durchführen können.Einziges Problem: Die Vorrangregel von / und *.
Ich hab schon einen Algo entworfen der diese Form (3 Zahlen, zwei Rechenzeichen) in einer Schleife berechnet.
3+5/4
(dann nächstes scanf und if anweisungen)
Einziges Porblem was ich nicht bedacht habe:
Was ist wenn als nächstes eine weiteres / oder * kommt haben diese wieder Vorrang.
Es würde ja gehen nur ich weiss ja nicht wieviele werte eingelesen werden.
Bitte dringend um Hilfe, wäre sehr nett.
Thx
-
Beim Parsen würde ich über binäre Bäume gehen. Eine halbwegs brauchbare Implementierung in C kannst Du unter http://www.staff.ncl.ac.uk/d.j.wilkinson/software/meparse.tgz finden.
-
hallo muhi,
hier ein kleiner Compiler, der eigentlich genau das tut was du brauchst:
#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("Syntax error!\n"); } void match( char t ) { if( lookahead == t ) { pos++; 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': if( compile_mode == MODE_POSTFIX ) printf("%c", lookahead); else printf("\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("Please enter an infix-notated expression with single digits:\n\n\t"); scanf("%20s", expression); printf("\nCompiling to postfix-notated expression:\n\n\t"); compile_mode = MODE_POSTFIX; pos = 0; lookahead = *expression; expr(); printf("\n\nCompiling to assembly-notated machine code:\n\n"); compile_mode = MODE_ASSEMBLY; pos = 0; lookahead = *expression; expr(); return 0; }