Einen einfachen Term parsen
-
Die lexikalische Trennung der Tokens hat einen Fehler, und es kennt halt keine Datentypen und subtrahiert auch immer den linken vom rechten Operanden.
Man tippt zum Beispiel(mit Leerzeichen) ein:
x = 7 / ( 3 + 7 ) ;
und der Assemblercode kommt provisorisch raus.#include <stdio.h> #include <stdlib.h> #include <string.h> static int var_name_count=0; void variable_countup(char *name, int do_countup) { char appendix[255]; char *base="rval"; if ( do_countup == 1 ) ++var_name_count; itoa(var_name_count, appendix, 10); strcpy(name,base); strcat( name, appendix ); return ; } int isnum(char c) { if ( c>=0x30 && c <=0x39 ) return 1; return 0; } struct { int type; char text[255]; }token[255]; static int num_tokens; void remove_tokens( int position, int amount_removed ) { while( position+ amount_removed <= num_tokens ) { token[position].type=token[position+amount_removed].type; strcpy( token[position].text, token[position+amount_removed].text ); position++; } num_tokens-=amount_removed; } int main(void) { int position; int txtcount; int left_limit, right_limit; int reduction_type; char rvalnum[20]; position=0; do { txtcount=0; scanf("%s", token[position].text ); if(token[position].text[0]=='+' && strlen(token[position].text )== 1 ) token[position].type='+', txtcount++; else if(token[position].text[0]=='-' && strlen(token[position].text )== 1 ) token[position].type='-', txtcount++; else if(token[position].text[0]=='*' && strlen(token[position].text )== 1 ) token[position].type='*', txtcount++; else if(token[position].text[0]=='/' && strlen(token[position].text )== 1 ) token[position].type='/', txtcount++; else if(token[position].text[0]=='(' && strlen(token[position].text )== 1 ) token[position].type='(', txtcount++; else if(token[position].text[0]==')' && strlen(token[position].text )== 1 ) token[position].type=')', txtcount++; else if(token[position].text[0]=='=' && strlen(token[position].text )== 1 ) token[position].type='=', txtcount++; else if(token[position].text[0]==';' && strlen(token[position].text )== 1 ) token[position].type=';', txtcount++; else if ( isalpha( token[position].text[0] ) ) { txtcount=0; while( isalpha(token[position].text[txtcount] ) )txtcount++; while( isnum(token[position].text[txtcount] ) ) txtcount++; token[position].type='v'; /* Variable */ if ( token[position].text[txtcount] != '\0' ) return 1; } else if ( isnum( token[position].text[0] ) ) { txtcount=0; while( isnum( token[position].text[txtcount] ) ) txtcount++; token[position].type='n'; /* numerische Konstante */ if ( token[position].text[txtcount] != '\0' ) return 1; } else { printf("Lexikalischer Fehler.\n"); getch(); return 1;} position++; }while(token[position-1].type!= ';' ); num_tokens=position-1; while(reduction_type!=';' ) { reduction_type=';'; /* debug position=0; while(position < num_tokens+1 ) { printf("Position: %d String: %s Typ: %c\n", position, token[position].text, token[position].type ); position++; } getch(); debug Ende */ left_limit=0, right_limit=num_tokens; position=left_limit; while( token[position].type!= ')'&& position < num_tokens ) { position++; } if ( token[position].type== ')' ) { right_limit=position; left_limit=position; while(token[left_limit].type != '(' && left_limit > 0 ) left_limit--; if(token[left_limit].type=='(' ) { reduction_type='('; } else return 1; } position=left_limit; while( position+2 <= right_limit ) { if ( token[position].type=='v' || token[position].type=='n' || token[position].type=='r' ) if ( token[position+1].type=='*' || token[position+1].type=='/' ) if ( token[position+2].type=='v' || token[position+2].type=='n'|| token[position+2].type=='r' ) { reduction_type=token[position+1].type; right_limit=position+2, left_limit=position; break; } position++; } position=left_limit; while( position+2 <= right_limit ) { if ( token[position].type=='v' || token[position].type=='n' || token[position].type=='r' ) if ( token[position+1].type=='+' || token[position+1].type=='-' ) if ( token[position+2].type=='v' || token[position+2].type=='n' || token[position+2].type=='r') { reduction_type=token[position+1].type; right_limit=position+2, left_limit=position; break; } position++; } position=right_limit-2; while( position >=left_limit ) { if ( token[position].type=='v' ) if( token[position+1].type=='=' ) if ( token[position+2].type== 'v' || token[position+2].type=='n' || token[position+2].type=='r') { reduction_type='=', right_limit=position+2, left_limit=position; break; } position--; } if ( reduction_type=='(' ) /* Klammern */ { if ( right_limit-left_limit != 2 ) { printf("Fehlerhafter Klammerinhalt.\n"); getch(); return 1; } if ( token[left_limit+1].type!='n' && token[left_limit+1].type!='v' && token[left_limit+1].type !='r' ) { printf("Syntaxfehler bei Klammerung.\n"); return 1; } variable_countup( rvalnum,1 ); if( token[left_limit+1].type!= 'n' ) printf("mov [%s],[%s]\n",rvalnum,token[left_limit+1].text ); else printf("mov [%s],%s\n",rvalnum,token[left_limit+1].text ); remove_tokens(left_limit,2 ); token[left_limit].type='r'; strcpy( token[left_limit].text, rvalnum ); } else if ( reduction_type=='+' ) /* Addition */ { variable_countup( rvalnum,1 ); if( token[left_limit+2].type!= 'n' ) printf("mov ax,[%s]\n",token[left_limit+2].text ); else printf("mov ax,%s\n",token[left_limit+2].text ); if( token[left_limit].type!= 'n' ) printf("add ax,[%s]\n",token[left_limit].text ); else printf("add ax,%s\n",token[left_limit].text ); printf("mov [%s],ax\n", rvalnum ); remove_tokens(left_limit,2 ); token[left_limit].type='r'; strcpy( token[left_limit].text, rvalnum ); } else if ( reduction_type=='-' ) /* Subtraktion */ { variable_countup( rvalnum,1 ); if( token[left_limit+2].type!= 'n' ) printf("mov ax,[%s]\n",token[left_limit+2].text ); else printf("mov ax,%s\n",token[left_limit+2].text ); if( token[left_limit].type!= 'n' ) printf("sub ax,[%s]\n",token[left_limit].text ); else printf("sub ax,%s\n",token[left_limit].text ); printf("mov [%s],ax\n", rvalnum ); remove_tokens(left_limit,2 ); token[left_limit].type='r'; strcpy( token[left_limit].text, rvalnum ); } else if ( reduction_type=='*' ) /* Multiplikation */ { variable_countup( rvalnum,1 ); if( token[left_limit+2].type!= 'n' ) printf("mov ax,[%s]\n",token[left_limit+2].text ); else printf("mov ax,%s\n",token[left_limit+2].text ); if( token[left_limit].type!= 'n' ) printf("mul ax,[%s]\n",token[left_limit].text ); else printf("mul ax,%s\n",token[left_limit].text ); printf("mov [%s],ax\n", rvalnum ); remove_tokens(left_limit,2 ); token[left_limit].type='r'; strcpy( token[left_limit].text, rvalnum ); } else if ( reduction_type=='/' ) /* Division */ { variable_countup( rvalnum,1 ); if( token[left_limit].type!= 'n' ) printf("mov ax,[%s]\n",token[left_limit].text ); else printf("mov ax,%s\n",token[left_limit].text ); if( token[left_limit+2].type!= 'n' ) printf("div ax,[%s]\n",token[left_limit+2].text ); else printf("div ax,%s\n",token[left_limit+2].text ); printf("mov [%s],ax\n", rvalnum ); remove_tokens(left_limit,2 ); token[left_limit].type='r'; strcpy( token[left_limit].text, rvalnum ); } else if ( reduction_type== '=' ) /* Zuweisung */ { variable_countup( rvalnum,1 ); if ( token[left_limit].type=='r' ){ printf("Zuweisung zu R-Wert !\n"); return 1; } if( token[left_limit+2].type!= 'n' ) printf("mov ax,[%s]\n" "mov [%s],ax\n",token[left_limit+2].text, token[left_limit].text ); else printf("mov ax,%s\n" "mov [%s],ax\n",token[left_limit+2].text, token[left_limit].text ); printf("mov [%s],ax\n", rvalnum ); remove_tokens(left_limit,2 ); token[left_limit].type='r'; strcpy( token[left_limit].text, rvalnum ); } else { if( num_tokens > 2 ) { printf("Operator fehlt.\n"); getch(); return 1; } else if ( num_tokens==2 ) if( ( token[0].type!= 'v' && token[0].type!= 'r' && token[0].type!='n') || token[1].type != ';' ) { printf("Operator fehlt.\n"); getch(); return 1; } if ( num_tokens==1 && token[1].type!=';' ) { printf("Syntaxfehler.\n"); getch(); return 1; } } } getch(); }
-
Wo ist jetzt die Frage?