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?


Log in to reply