#include #include #include #include struct token { enum symbol { LPAREN, RPAREN, STRING, IDEN, NUM } sym; union { char *iden; int i; char *str; }; }; static struct token tok; static inline int issep(char c) { return isspace(c) || c == '\0' || c == '}' || c == '{' || c == '"'; } static inline int tillsep(char *str) { size_t i = 0; while(!issep(str[i++])); return i-1; } static inline char *substring(char *str, size_t sub_end) { static char sub[128]; if(sub_end+1 > sizeof(sub)) return NULL; sub[sub_end+1] = '\0'; return memcpy(sub, str, sub_end); } static char *next_token(char *str) { size_t off = 0; char c0 = str[0]; if(c0 == '\0') return NULL; if(isspace(c0)) return next_token(str+1); else { off = tillsep(str); if(off == 0) { // sep switch(str[off++]) { case '{': tok.sym = LPAREN; break; case '}': tok.sym = RPAREN; break; case '"': while(str[off] != '"') if(str[off++] == '\0') return NULL; tok.sym = STRING; tok.str = strdup(substring(str, off)); } } else if(isalpha(c0)) { // iden tok.sym = IDEN; tok.iden = strdup(substring(str, off)); } else if(c0 >= '0' && c0 <= '9') { // num tok.sym = NUM; tok.i = atoi(substring(str, off)); } } return str+off; } int main(void) { char *str = "blah 0 1 443 test{here}13}{1\"fdlkfjakl{fher} fdsfj\" here { {tok {"; while((str = next_token(str))) switch(tok.sym) { case LPAREN: printf("{ "); break; case RPAREN: printf("} "); break; case STRING: printf("\"%s\" ", tok.str); free(tok.str); break; case IDEN: printf("'%s' ", tok.iden); free(tok.iden); break; case NUM: printf("%d ", tok.i); break; } printf("\n"); return 0; }