/** * \brief Check if character is string token character * * Auxilary key-value TOKENIZER function * * Defines if character is in subset of allowed string * token characters. * String defines set of characters which can be a key or value string. * * Allowed subset includes: * - Alphanumerical characters * - Digits * - White spaces and * - subset of punctuation characters. * * \param c Input character to check * \return Return 1 if character is allowed punctuation character, otherwise return false * */ static int isstring(int c) { return (isalpha(c) || isdigit(c) || isspace(c) || ispunctuation(c)); }
int main() { int fd=open("test.js",O_RDONLY); char buf[1024]; int n=read(fd,buf,1024); int c,i,state='X',q,esc, last='X',pstate=0; for(;;) { for(i=0;i<n;i++) { c=buf[i]; putchar(c); switch(state) { case 'X': state_X: state='X'; if(c=='/') { state='/'; } else if(ispunctuation(c)) { parse(c); if(c==')') { last='E'; } else { last='P'; } } else if(isspace(c)) { state='W'; } else if(c=='\''||c=='"') { state='S'; q=c; esc=0; last='S'; } else if(isdigit(c)) { state='N'; last='N'; ident=b_ident; *ident++=c; } else if(isident(c)) { state='I'; last='I'; ident=b_ident; *ident++=c; } else { goto abort; } break; case 'W': if(isspace(c)) { /* nothing */ } else { goto state_X; } break; case 'I': if(isident(c)) { *ident++=c; } else { parse('I'); goto state_X; } break; case 'S': if(esc) { esc=0; } else if(c==q) { parse('S'); state='X'; } else if(c=='\\') { esc=1; } else { /* nothing */ } break; case 'N': if(isdigit(c) || c=='.') { *ident++=c; } else { parse('N'); goto state_X; } break; case '/': printf("\x1b[01;31m%c\x1b[00m" "\x1b[01;33m%.*s\x1b[00m",last,(int)(ident-b_ident),b_ident); if(c=='*') { state='C'; esc=0; } else if(c=='/') { state='c'; } else if(last!='N'&&last!='I'&&last!='E') { esc=0; state='R'; goto state_R; } else if(last=='I'&&strncmp(b_ident,"return",6)==0) { esc=0; state='R'; goto state_R; } else { parse('/'); goto state_X; } break; case 'R': state_R: if(esc) { esc=0; } else if(c=='\\') { esc=1; } else if(c=='/') { parse('R'); state='X'; } else { /* nothing */ } break; case 'C': if(esc) { if(c=='/') { state='X'; } else { esc=0; } } else if(c=='*') { esc=1; } else { /* nothing */ } break; case 'c': if(c=='\n'||c=='\r') { state='X'; } else { /* nothing */ } break; default: abort(); } if(pstate!=state) { printf("\x1b[01;32m%c\x1b[00m",state); } pstate=state; } n=read(fd,buf,1024); if(n==0) break; } return 0; abort: printf("\n Abort: char '%c' state '%c'\n",c,state); return 1; }