Text Parsing in C on a microcontroller Microcontroller receive data on uart and call parser_i2c function when user presses enter
e.g. parser_i2c(I2C scan)
I want to parse following input from user communicated through uart
I2C scan
I2C read read_adress
I2C Write Write_address data
I have wrote following code
        void parser_i2c(unsigned char str[20])
    {
       //unsigned char str[20]  
       unsigned char s[2] = &quot; &quot;;
       unsigned char *token;
       unsigned char output[10][10] ;
        U8 i_i2c=0;
       /* get the first token */
       token = strtok(str, s);
      
       /* walk through other tokens */
       while( token != NULL ) {
      //    printf( &quot; %s\n&quot;, token );
        strcpy(output[i_i2c],token);
         
         i_i2c++ ;
          token = strtok(NULL, s);
     
       }
     if(!(strcmp(output[0],&quot;I2C&quot;)))
      {
         if(!(strcmp(output[1],&quot;READ&quot;)))
            {
                if(*output[2]!='\0')
                {
                i2c_read(output[2]) ;
                }
                else{
            
                        printf(COLOR_RED &quot;Bad command&quot; COLOR_RESET);
                        
                }
            }
         else if(!(strcmp(output[1],&quot;WRITE&quot;)))
         {
            if(((*output[2])||(*output[3]))!='\0')
            {
            i2c_write(output[2],output[3]);
            }
            else{

                        printf(COLOR_RED &quot;Bad Command&quot; COLOR_RESET);
                
            }
         }
         
         else if(!(strcmp(output[1],&quot;SCAN&quot;)))
         {
         i2c_scan();
         }
         else{
      
                        printf(COLOR_RED &quot;Bad Command&quot; COLOR_RESET);
                    
         }
         
      }
      else {
                            printf(COLOR_RED &quot;Bad Command&quot; COLOR_RESET);
                    
      }
memset(output, '\0', 10*sizeof(arr[0]));
    
    }

How to improve it ? in terms of reducing code lines and code size and memory utilization ? or any other way to parse ? Is there any basic library available ?
Here are some things that may help you improve your program.
Use consistent formatting
The code as posted has inconsistent indentation which makes it hard to read and understand. Pick a style and apply it consistently.
Provide complete code to reviewers
This is not so much a change to the code as a change in how you present it to other people.  Without the full context of the code and an example of how to use it, it takes more effort for other people to understand your code.  This affects not only code reviews, but also maintenance of the code in the future, by you or by others.  One good way to address that is by the use of comments.  Another good technique is to include test code showing how your code is intended to be used.
Use const where practical
The s string is set and never altered, so it could be const or even better in this case, static const.
Consider re-entrancy
In an embedded system, there are often many things happening at once.  The usual case is that many events are event-driven and so the order in which parts of code are executed is uncertain.  For that reason, you should be wary about using non-reentrant calls such as strtok.  Also, we don't have the complete context, but it may be worth making a copy of a buffered line of data so that subesequent data the comes in does not overwrite a line as it is being parsed.
Consider passing a length
This code makes the tacit assumption that the passed array is a '\0'-terminated text string.  If you can guarantee that is always the case, then the code is fine as it is, but a more robust system might be to explicitly pass both a pointer and a length.
Understand system variations
It is implementation-defined whether char is signed or unsigned.  If it happens to be signed on your platform, you will get warnings about sign mismatches for parameters passed to strtok and strcpy.  If you system uses unsigned chars by default, you will get no such warning, but you should be aware that this is at least a portability concern.
Simplify your algorithm
This could be simpler and more maintainble in the future if it used a state machine for parsing.  For this simple grammar we have the following valid sentences:

I2C SCAN
I2C READ n
I2C WRITE n n

I am assuming the n is a numeric value, but it's not clear from the context.  Here's the corresponding state machine:

Here's one way to code that:
void parser_i2c(mychar str[20])
{
    static const mychar s[2] = &quot; &quot;;
    enum { start, i2c, r1, w1, w2, error, done } state = start;
    mychar *n1 = NULL;
    for (mychar *token = strtok(str, s); state != done; token = strtok(NULL, s)) {
        switch (state) {
            case start:
                if (strcmp(token, &quot;I2C&quot;) == 0) {
                    state = i2c;
                } else {
                    state = error;
                }
                break;
            case i2c:
                if (strcmp(token, &quot;READ&quot;) == 0) {
                    state = r1;
                } else if (strcmp(token, &quot;WRITE&quot;) == 0) {
                    state = w1;
                } else if (strcmp(token, &quot;SCAN&quot;) == 0) {
                    i2c_scan();
                    state = done;
                } else {
                    state = error;
                }
                break;
            case r1:
                /* check for number? */
                i2c_read(token);
                state = done;
                break;
            case w1:
                /* check for number? */
                n1 = token;
                state = w2;
                break;
            case w2:
                /* check for number? */
                i2c_write(n1, token);
                state = done;
                break;
            default:
                printf(COLOR_RED &quot;Illegal state&quot; COLOR_RESET);
                state = done;
        }
        if (state == error) {
            printf(COLOR_RED &quot;Bad Command&quot; COLOR_RESET);
            state = done;
        }
    }
}

I've use mychar as a typedef for char on my machine.  On yours, it looks like you could use unsigned char instead.
Note that now, the flow is very easy to follow and it would not be at all difficult to make an alteration to the grammar to accommodate some other command. Because the tokens are handled as they're parsed, there's no need to store any except the first parsed number which we need for i2c_write(). If it gets any more complex than this, one could use a more sophisticated parser or use a tool like flex.