int joqe_yylex(JOQE_YYSTYPE *yylval, joqe_build *build) { lexparam l = {yylval, build}; int n, c = peek(l); while(1) switch(c) { case SINGLES: consume(l); return c; case '"': case '\'': consume(l); return string(l, c); case 'a': return keyword(l, "and", AND, 0, 3); case 'o': return keyword(l, "or", OR, 0, 2); case 't': return keyword(l, "true", _TRUE, 0, 4); case 'f': return keyword(l, "false", _FALSE, 0, 5); case 'n': joqe_build_appendstring(l.builder, c); switch(consume(l)) { case 'o': return keyword(l, "not", NOT, 1, 3); case 'u': return keyword(l, "null", _NULL, 1, 4); default: return ident(l); } case DIGITS: return number(l); case '/': { n = consume(l); if(n == c) { consume(l); return SLASH2; } else if(n == '*') { c = c_comment(l); } else { return c; } } break; case '.': if(c == consume(l)) {consume(l); return DOT2;} else return c; case ':': if(c == consume(l)) {consume(l); return C2;} else return c; case '<': if('=' == consume(l)) {consume(l); return LEQ;} else return c; case '>': if('=' == consume(l)) {consume(l); return GEQ;} else return c; case WHITE: c = consume(l); break; default: if(c < 0x20) //TODO error, other characters 0x1f or below are not valid. return 0; return ident(l); } return 0; }
int main(void) { int c; int state = NO_COMMENT; while ((c = getchar()) != EOF) { switch (state) { case NO_COMMENT: state = no_comment(c); break; case OPENING_SLASH: state = opening_slash(c); break; case C_COMMENT: state = c_comment(c); break; case CLOSING_STAR: state = closing_star(c); break; case LINE_COMMENT: state = line_comment(c); break; case IN_STRING: state = in_string(c); break; case IN_CHAR_LIT: state = in_char_lit(c); break; case STRING_ESCAPE: state = string_escape(c); break; case CHAR_LIT_ESCAPE: state = char_lit_escape(c); break; default: printf("error, unknown state: %d\n", state); return 1; } } }