Implementar um parser na unha é TENSO, ainda mais em C, mas vou dar os meus pitacos.
De uma olhada nesse cara:
http://fxr.googlebit.com/source/bin/sh/main.c?v=8-CURRENT
Um processo de parse parte do principio que vc tem uma ou mais formas que vc quer encontrar que combinam uma série de identificadores.
Por exemplo, se vc quer um parser simples, que só execute um comando, vc pode assumir que a primeira string que vc receba é o nome do executavel que vc vai rodar. Depois vc pode pensar em passar argumentos para este executavel, dessa forma vc separa os mesmos por um ou mais caracteres espaço.
Mas vc pode querer separar por TAB, por New-Line, etc. E vc pode querer escapar estes caracteres, no caso de remover um arquivo cujo nome possui espaços em branco, por exemplo. Nesse ponto vc pode usar expressões regulares ou mesmo algo como strtok + alguma combinação de funções.
Porem um shell possui uma sintaxe bem complexa: vc tem if, for, declara variaveis, pode ter algum alias, subfunção, etc. Vc tem variaveis de ambiente que alteram o próprio comportamento do shell e do parser – como o caso da variavel IFS, por exemplo.
Eu analisaria como um shell simples funciona. De uma olhada no codigo do Busybox que ainda possui shell, grep, awk, sed, etc.
Acredito que vc pode usar alguma lib de parsing onde vc define a gramatica através de uma BNF
http://apoie.org/Shell.htm