// [24] ws ::= #x9 | #xA | #xD | #x20 | comment static inline bool read_ws(SerdReader* reader) { const uint8_t c = peek_byte(reader); switch (c) { case 0x9: case 0xA: case 0xD: case 0x20: eat_byte_safe(reader, c); return true; case '#': read_comment(reader); return true; default: return false; } }
static int runtest(char *filename, char *ironout) { struct input *input = input_open(filename); char current_line[MAXLINELEN]; char cmd[128]; char *line; if (!input) return 1; while ((line = input_line(input))) { int result = -1; strcpy(current_line, line); nthtoken(cmd, line, " \n", 2); if (!strcmp(cmd, "comment") || !strcmp(cmd, "#") || !*cmd) result = read_comment(input); if (!strcmp(cmd, "write") || !strcmp(cmd, ">")) result = write_file(input); if (!strcmp(cmd, "read") || !strcmp(cmd, "<")) result = read_file(input); if (!strcmp(cmd, "ironout")) result = exec_ironout(input, ironout); if (result == -1) { printf("unknown cmd: %s\n", cmd); return 1; } if (result > 0) { char *testname = filename; if (strchr(testname, '/')) testname = strrchr(testname, '/') + 1; printf("%s:%d %s", testname, input->lineno, current_line); return 1; } } input_free(input); return 0; }
VALUE ox_parse(char *xml, ParseCallbacks pcb, char **endp, int trace, Effort effort) { struct _PInfo pi; int body_read = 0; if (0 == xml) { raise_error("Invalid arg, xml string can not be null", xml, 0); } if (DEBUG <= trace) { printf("Parsing xml:\n%s\n", xml); } /* initialize parse info */ pi.str = xml; pi.s = xml; pi.h = 0; pi.pcb = pcb; pi.obj = Qnil; pi.circ_array = 0; pi.encoding = 0; pi.trace = trace; pi.effort = effort; while (1) { next_non_white(&pi); // skip white space if ('\0' == *pi.s) { break; } if (body_read && 0 != endp) { *endp = pi.s; break; } if ('<' != *pi.s) { // all top level entities start with < raise_error("invalid format, expected <", pi.str, pi.s); } pi.s++; // past < switch (*pi.s) { case '?': // prolog pi.s++; read_instruction(&pi); break; case '!': /* comment or doctype */ pi.s++; if ('\0' == *pi.s) { raise_error("invalid format, DOCTYPE or comment not terminated", pi.str, pi.s); } else if ('-' == *pi.s) { pi.s++; // skip - if ('-' != *pi.s) { raise_error("invalid format, bad comment format", pi.str, pi.s); } else { pi.s++; // skip second - read_comment(&pi); } } else if (0 == strncmp("DOCTYPE", pi.s, 7)) { pi.s += 7; read_doctype(&pi); } else { raise_error("invalid format, DOCTYPE or comment expected", pi.str, pi.s); } break; case '\0': raise_error("invalid format, document not terminated", pi.str, pi.s); default: read_element(&pi); body_read = 1; break; } } return pi.obj; }
/* Entered after the '<' and the first character after that. Returns status * code. */ static void read_element(PInfo pi) { struct _Attr attrs[MAX_ATTRS]; Attr ap = attrs; char *name; char *ename; char *end; char c; long elen; int hasChildren = 0; int done = 0; ename = read_name_token(pi); end = pi->s; elen = end - ename; next_non_white(pi); c = *pi->s; *end = '\0'; if ('/' == c) { /* empty element, no attributes and no children */ pi->s++; if ('>' != *pi->s) { //printf("*** '%s' ***\n", pi->s); raise_error("invalid format, element not closed", pi->str, pi->s); } pi->s++; /* past > */ ap->name = 0; pi->pcb->add_element(pi, ename, attrs, hasChildren); pi->pcb->end_element(pi, ename); return; } /* read attribute names until the close (/ or >) is reached */ while (!done) { if ('\0' == c) { next_non_white(pi); c = *pi->s; } switch (c) { case '\0': raise_error("invalid format, document not terminated", pi->str, pi->s); case '/': // Element with just attributes. pi->s++; if ('>' != *pi->s) { raise_error("invalid format, element not closed", pi->str, pi->s); } pi->s++; ap->name = 0; pi->pcb->add_element(pi, ename, attrs, hasChildren); pi->pcb->end_element(pi, ename); return; case '>': // has either children or a value pi->s++; hasChildren = 1; done = 1; ap->name = 0; pi->pcb->add_element(pi, ename, attrs, hasChildren); break; default: // Attribute name so it's an element and the attribute will be // added to it. ap->name = read_name_token(pi); end = pi->s; next_non_white(pi); if ('=' != *pi->s++) { raise_error("invalid format, no attribute value", pi->str, pi->s); } *end = '\0'; // terminate name // read value next_non_white(pi); ap->value = read_quoted_value(pi); if (0 != strchr(ap->value, '&')) { if (0 != collapse_special((char*)ap->value)) { raise_error("invalid format, special character does not end with a semicolon", pi->str, pi->s); } } ap++; if (MAX_ATTRS <= (ap - attrs)) { raise_error("too many attributes", pi->str, pi->s); } break; } c = '\0'; } if (hasChildren) { char *start; done = 0; // read children while (!done) { start = pi->s; next_non_white(pi); c = *pi->s++; if ('\0' == c) { raise_error("invalid format, document not terminated", pi->str, pi->s); } if ('<' == c) { switch (*pi->s) { case '!': /* better be a comment or CDATA */ pi->s++; if ('-' == *pi->s && '-' == *(pi->s + 1)) { pi->s += 2; read_comment(pi); } else if (0 == strncmp("[CDATA[", pi->s, 7)) { pi->s += 7; read_cdata(pi); } else { raise_error("invalid format, invalid comment or CDATA format", pi->str, pi->s); } break; case '/': pi->s++; name = read_name_token(pi); end = pi->s; next_non_white(pi); c = *pi->s; *end = '\0'; if (0 != strcmp(name, ename)) { raise_error("invalid format, elements overlap", pi->str, pi->s); } if ('>' != c) { raise_error("invalid format, element not closed", pi->str, pi->s); } pi->s++; pi->pcb->end_element(pi, ename); return; case '\0': raise_error("invalid format, document not terminated", pi->str, pi->s); default: // a child element read_element(pi); break; } } else { // read as TEXT pi->s = start; //pi->s--; read_text(pi); //read_reduced_text(pi); // to exit read_text with no errors the next character must be < if ('/' == *(pi->s + 1) && 0 == strncmp(ename, pi->s + 2, elen) && '>' == *(pi->s + elen + 2)) { // close tag after text so treat as a value pi->s += elen + 3; pi->pcb->end_element(pi, ename); return; } } } } }
macro_fn getmacro(int c) { if (c == '"') { return read_string; } else if (c == '(') { return read_list; } else if (c == ')') { // lambda's are awesome! // but! note that this is only ok as long as the capture list is empty // TODO: and i should probably make sure this doesn't incur any // run time overhead as apposed to using pure functions return [] (std::istream &) -> std::shared_ptr<Object> { throw "Unmatched delimiter: )"; }; } else if (c == '[') { return read_vector; } else if (c == ']') { return [] (std::istream &) -> std::shared_ptr<Object> { throw "Unmatched delimiter: ]"; }; } else if (c == '{') { return read_map; } else if (c == '}') { return [] (std::istream &) -> std::shared_ptr<Object> { throw "Unmatched delimiter: }"; }; } else if (c == '\'') { return [] (std::istream &in) -> std::shared_ptr<Object> { return wrap_read(in, Symbol::create("quote")); }; } else if (c == '@') { return [] (std::istream &in) -> std::shared_ptr<Object> { return wrap_read(in, Symbol::create("clojure.core", "deref")); }; } else if (c == ';') { return read_comment; } else if (c == '\\') { return read_character; } else if (c == '^') { return read_meta; } else if (c == '`') { return [] (std::istream &in) -> std::shared_ptr<Object> { throw "TODO: implement syntax quote reader"; }; } else if (c == '~') { // unquote reader return [] (std::istream &in) -> std::shared_ptr<Object> { int ch = in.get(); if (in.eof()) { throw "EOF while reading character"; } if (ch == '@') { return wrap_read(in, UNQUOTE_SPLICING); } else { in.unget(); return wrap_read(in, UNQUOTE); } }; } else if (c == '%') { return [] (std::istream &in) -> std::shared_ptr<Object> { throw "TODO: implement arg reader"; }; } else if (c == '#') { // dispatch macro reader (lambda) // TODO: is this over-using lambdas? what is the overhead of a lambda // over a pure function, esp if the function is being called via a ptr return [] (std::istream &in) -> std::shared_ptr<Object> { int c = in.get(); if (in.eof()) { throw "EOF while reading character"; } if (c == '{') { return read_set(in); } else if (c == '^') { return read_meta(in); } else if (c == '\'') { return wrap_read(in, Symbol::create("var")); } else if (c == '"') { return read_regex(in); } else if (c == '(') { throw "TODO: implement function reader"; } else if (c == '=') { throw "TODO: implement eval reader"; } else if (c == '!') { return read_comment(in); } else if (c == '<') { throw "Unreadable form"; } else if (c == '_') { read(in, true, Object::nil, true); return NOOP; } else { // try ctor reader // TODO: implement ctor reader } throw "No dispatch macro for: " + std::string{ (char)c }; }; } else { return 0; } }
struct generic_section_config * parse_param(char const *path, FILE *f, const struct config_section_info *params, int quiet_flag, int _ncond_var, cfg_cond_var_t *_cond_vars, int *p_cond_count) { struct generic_section_config *cfg = NULL; struct generic_section_config **psect = &cfg, *sect = NULL; const struct config_section_info *cur_info = NULL; char sectname[32]; char varname[32]; char varvalue[1024]; int c, sindex; parsecfg_state.ncond_var = _ncond_var; parsecfg_state.cond_vars = _cond_vars; parsecfg_state.cond_stack = 0; parsecfg_state.output_enabled = 1; parsecfg_state.lineno = 1; if (p_cond_count) *p_cond_count = 0; /* found the global section description */ for (sindex = 0; params[sindex].name; sindex++) { if (!strcmp(params[sindex].name, "global")) { cur_info = ¶ms[sindex]; break; } } /* if (!cur_info) { fprintf(stderr, "Cannot find description of section [global]\n"); goto cleanup; } */ if (!f && !(f = fopen(path, "r"))) { fprintf(stderr, "Cannot open configuration file %s\n", path); goto cleanup; } if (cur_info) { cfg = (struct generic_section_config*) xcalloc(1, cur_info->size); if (cur_info->init_func) cur_info->init_func(cfg); cfg->next = NULL; psect = &cfg->next; } while (1) { c = read_first_char(f); if (c == EOF || c == '[') break; if (c == '#' || c== '%' || c == ';') { read_comment(f); continue; } if (c == '@') { if (handle_conditional(f) < 0) goto cleanup; if (p_cond_count) (*p_cond_count)++; continue; } if (!parsecfg_state.output_enabled) { read_comment(f); continue; } if (read_variable(f, varname, sizeof(varname), varvalue, sizeof(varvalue)) < 0) goto cleanup; if (!quiet_flag) { printf("%d: Value: %s = %s\n", parsecfg_state.lineno - 1, varname, varvalue); } if (!cur_info) { fprintf(stderr, "Cannot find description of section [global]\n"); goto cleanup; } if (copy_param(cfg, cur_info, varname, varvalue) < 0) goto cleanup; } while (c != EOF) { if (read_section_name(f, sectname, sizeof(sectname)) < 0) goto cleanup; if (!quiet_flag) { printf("%d: New section %s\n", parsecfg_state.lineno - 1, sectname); } if (!strcmp(sectname, "global")) { fprintf(stderr, "Section global cannot be specified explicitly\n"); goto cleanup; } for (sindex = 0; params[sindex].name; sindex++) { if (!strcmp(params[sindex].name, sectname)) { cur_info = ¶ms[sindex]; break; } } if (!cur_info) { fprintf(stderr, "Cannot find description of section [%s]\n", sectname); goto cleanup; } if (cur_info->pcounter) (*cur_info->pcounter)++; sect = (struct generic_section_config*) xcalloc(1, cur_info->size); strcpy(sect->name, sectname); if (cur_info->init_func) cur_info->init_func(sect); sect->next = NULL; *psect = sect; psect = §->next; while (1) { c = read_first_char(f); if (c == EOF || c == '[') break; if (c == '#' || c == '%' || c == ';') { read_comment(f); continue; } if (c == '@') { if (handle_conditional(f) < 0) goto cleanup; if (p_cond_count) (*p_cond_count)++; continue; } if (!parsecfg_state.output_enabled) { read_comment(f); continue; } if (read_variable(f, varname, sizeof(varname), varvalue, sizeof(varvalue)) < 0) goto cleanup; if (!quiet_flag) { printf("%d: Value: %s = %s\n", parsecfg_state.lineno - 1, varname, varvalue); } if (copy_param(sect, cur_info, varname, varvalue) < 0) goto cleanup; } } if (parsecfg_state.cond_stack) { fprintf(stderr, "%d: unclosed conditional compilation\n", parsecfg_state.lineno); goto cleanup; } fflush(stdout); if (f) fclose(f); return cfg; cleanup: xfree(cfg); if (f) fclose(f); return NULL; }
/******************************************************** * next_token -- read the next token in an input stream * * * * Returns * * next token * ********************************************************/ enum TOKEN_TYPE next_token(void) { if (in_comment) return (read_comment()); while (is_char_type(in_cur_char(), C_WHITE)) { in_read_char(); } if (in_cur_char() == EOF) return (T_EOF); switch (get_char_type(in_cur_char())) { case C_NEWLINE: in_read_char(); return (T_NEWLINE); case C_ALPHA: while (is_char_type(in_cur_char(), C_ALPHA_NUMERIC)) in_read_char(); return (T_ID); case C_DIGIT: in_read_char(); if ((in_cur_char() == 'X') || (in_cur_char() == 'x')) { in_read_char(); while (is_char_type(in_cur_char(), C_HEX_DIGIT)) in_read_char(); return (T_NUMBER); } while (is_char_type(in_cur_char(), C_DIGIT)) in_read_char(); return (T_NUMBER); case C_SLASH: /* Check for '/', '*' characters */ if (in_next_char() == '*') { return (read_comment()); } /* Fall through */ case C_OPERATOR: in_read_char(); return (T_OPERATOR); case C_L_PAREN: in_read_char(); return (T_L_PAREN); case C_R_PAREN: in_read_char(); return (T_R_PAREN); case C_L_CURLY: in_read_char(); return (T_L_CURLY); case C_R_CURLY: in_read_char(); return (T_R_CURLY); case C_DOUBLE: while (1) { in_read_char(); /* Check for end of string */ if (in_cur_char() == '"') break; /* Escape character, then skip the next character */ if (in_cur_char() == '\\') in_read_char(); } in_read_char(); return (T_STRING); case C_SINGLE: while (1) { in_read_char(); /* Check for end of character */ if (in_cur_char() == '\'') break; /* Escape character, then skip the next character */ if (in_cur_char() == '\\') in_read_char(); } in_read_char(); return (T_STRING); default: fprintf(stderr, "Internal error: Very strange character\n"); abort(); } fprintf(stderr, "Internal error: We should never get here\n"); abort(); return (T_EOF); /* Should never get here either */ /* But we put in the return to avoid a compiler */ /* warning. */ }
/******************************************************** * next_token -- read the next token in an input stream * * * * Parameters * * in_file -- file to read * * * * Returns * * next token * ********************************************************/ TOKEN_TYPE token::next_token(input_file& in_file) { if (need_to_read_one) in_file.read_char(); need_to_read_one = 0; if (in_comment) return (read_comment(in_file)); while (char_type.is(in_file.cur_char, char_type::C_WHITE)) { in_file.read_char(); } if (in_file.cur_char == EOF) return (T_EOF); switch (char_type.type(in_file.cur_char)) { case char_type::C_NEWLINE: in_file.read_char(); return (T_NEWLINE); case char_type::C_ALPHA: while (char_type.is(in_file.cur_char, char_type::C_ALPHA_NUMERIC)) in_file.read_char(); return (T_ID); case char_type::C_DIGIT: in_file.read_char(); if ((in_file.cur_char == 'X') || (in_file.cur_char == 'x')) { in_file.read_char(); while (char_type.is(in_file.cur_char, char_type::C_HEX_DIGIT)) { in_file.read_char(); } return (T_NUMBER); } while (char_type.is(in_file.cur_char, char_type::C_DIGIT)) in_file.read_char(); return (T_NUMBER); case char_type::C_SLASH: // Check for /* characters if (in_file.next_char == '*') { return (read_comment(in_file)); } // Now check for double slash comments if (in_file.next_char == '/') { while (true) { // Comment starting with // and ending with EOF is legal if (in_file.cur_char == EOF) return (T_COMMENT); if (in_file.cur_char == '\n') return (T_COMMENT); in_file.read_char(); } } // Fall through case char_type::C_OPERATOR: in_file.read_char(); return (T_OPERATOR); case char_type::C_L_PAREN: in_file.read_char(); return (T_L_PAREN); case char_type::C_R_PAREN: in_file.read_char(); return (T_R_PAREN); case char_type::C_L_CURLY: in_file.read_char(); return (T_L_CURLY); case char_type::C_R_CURLY: in_file.read_char(); return (T_R_CURLY); case char_type::C_DOUBLE: while (true) { in_file.read_char(); // Check for end of string if (in_file.cur_char == '"') break; // Escape character, then skip the next character if (in_file.cur_char == '\\') in_file.read_char(); } in_file.read_char(); return (T_STRING); case char_type::C_SINGLE: while (true) { in_file.read_char(); // Check for end of character if (in_file.cur_char == '\'') break; // Escape character, then skip the next character if (in_file.cur_char == '\\') in_file.read_char(); } in_file.read_char(); return (T_STRING); default: assert("Internal error: Very strange character" != 0); } assert("Internal error: We should never get here" != 0); return (T_EOF); // Should never get here either }
void AsxTokenizer::move_next () { char c; while ((c = read_char ()) != -1) { if (in_data) { bool entirely_whitespace; current_token->set_type (TOKEN_DATA); current_token->set_value (read_data (c, entirely_whitespace)); current_token->set_entirely_whitespace (entirely_whitespace); return; } if (c == OP_OPEN_ELEMENT) { if (is_comment_open (c)) { read_comment (); continue; } current_token->set_type (TOKEN_OPEN_ELEMENT); current_token->set_value (NULL); in_data = false; return; } if (c == OP_CLOSE_ELEMENT) { current_token->set_type (TOKEN_CLOSE_ELEMENT); current_token->set_value (NULL); in_data = true; return; } if (c == OP_ASSIGNMENT) { current_token->set_type (TOKEN_ASSIGNMENT); current_token->set_value (NULL); return; } if (c == OP_SLASH) { current_token->set_type (TOKEN_SLASH); current_token->set_value (NULL); return; } if (g_ascii_isspace (c)) { current_token->set_type (TOKEN_WHITESPACE); current_token->set_value (NULL); return; } if (is_quote_char (c)) { current_token->set_type (TOKEN_QUOTED_STRING); current_token->set_value (read_quoted_string (c)); return; } if (is_name_char (c)) { current_token->set_type (TOKEN_NAME); current_token->set_value (read_name (c)); return; } } current_token->set_type (TOKEN_EOF); current_token->set_value (NULL); }
bool LoadPPM(const char *pathname, unsigned char *&pixels, int &width, int &height, int &maxval) { FILE *fp; if ( ( fp = fopen( pathname, "rb" ) ) == NULL ) { printf( "fail to open file %s!\n", pathname ); return false; } //read header read_comment(fp); char magic[16]; fscanf(fp, "%s", magic); if (strcmp(magic, "P6")!=0) { printf("LoadPPM : invalid magic number in %s!\n", pathname); return false; } fgetc(fp); read_comment(fp); fscanf(fp, "%d", &width); if (width <= 0) { printf("LoadPPM : invalid width in %s!\n", pathname); return false; } fgetc(fp); read_comment(fp); fscanf(fp, "%d", &height); if (height <= 0) { printf("LoadPPM : invalid height in %s!\n", pathname); return false; } fgetc(fp); read_comment(fp); fscanf(fp, "%d", &maxval); if (maxval < 1 || maxval > 65535) { printf("LoadPPM : invalid maxval in %s\n", pathname); return false; } fgetc(fp); //read pixels int pixDepth = ( maxval < 256 ? 1 : 2 ); int numPixels = width * height * 3; if (pixels == NULL) { pixels = new unsigned char[pixDepth*numPixels]; } size_t n = fread(pixels, sizeof(unsigned char)*pixDepth, numPixels, fp); fclose(fp); if (n == numPixels) { //PPM is Most Significant Byte First for 16 bit //convert to Little-Endian for PC if (pixDepth == 2) SwapBytes(pixels, numPixels, pixDepth); return true; } else { printf("LoadPGM : fail to read pixels in %s!\n", pathname); return false; } }
static void parse(SaxDrive dr) { char c = skipBOM(dr); int state = START_STATE; while ('\0' != c) { buf_protect(&dr->buf); if (is_white(c) && '\0' == (c = buf_next_non_white(&dr->buf))) { break; } if ('<' == c) { c = buf_get(&dr->buf); switch (c) { case '?': /* instructions (xml or otherwise) */ c = read_instruction(dr); break; case '!': /* comment or doctype */ buf_protect(&dr->buf); c = buf_get(&dr->buf); if ('\0' == c) { ox_sax_drive_error(dr, NO_TERM "DOCTYPE or comment not terminated"); goto DONE; } else if ('-' == c) { c = buf_get(&dr->buf); /* skip first - and get next character */ if ('-' != c) { ox_sax_drive_error(dr, INVALID_FORMAT "bad comment format, expected <!--"); } else { c = buf_get(&dr->buf); /* skip second - */ } c = read_comment(dr); } else { int i; int spaced = 0; int line = dr->buf.line; int col = dr->buf.col; if (is_white(c)) { spaced = 1; c = buf_next_non_white(&dr->buf); } dr->buf.str = dr->buf.tail - 1; for (i = 7; 0 < i; i--) { c = buf_get(&dr->buf); } if (0 == strncmp("DOCTYPE", dr->buf.str, 7)) { if (spaced) { ox_sax_drive_error_at(dr, WRONG_CHAR "<!DOCTYPE can not included spaces", line, col); } if (START_STATE != state) { ox_sax_drive_error(dr, OUT_OF_ORDER "DOCTYPE can not come after an element"); } c = read_doctype(dr); } else if (0 == strncasecmp("DOCTYPE", dr->buf.str, 7)) { ox_sax_drive_error(dr, CASE_ERROR "expected DOCTYPE all in caps"); if (START_STATE != state) { ox_sax_drive_error(dr, OUT_OF_ORDER "DOCTYPE can not come after an element"); } c = read_doctype(dr); } else if (0 == strncmp("[CDATA[", dr->buf.str, 7)) { if (spaced) { ox_sax_drive_error_at(dr, WRONG_CHAR "<![CDATA[ can not included spaces", line, col); } c = read_cdata(dr); } else if (0 == strncasecmp("[CDATA[", dr->buf.str, 7)) { ox_sax_drive_error(dr, CASE_ERROR "expected CDATA all in caps"); c = read_cdata(dr); } else { ox_sax_drive_error_at(dr, WRONG_CHAR "DOCTYPE, CDATA, or comment expected", line, col); c = read_name_token(dr); if ('>' == c) { c = buf_get(&dr->buf); } } } break; case '/': /* element end */ c = read_element_end(dr); if (0 == stack_peek(&dr->stack)) { state = AFTER_STATE; } break; case '\0': goto DONE; default: buf_backup(&dr->buf); if (AFTER_STATE == state) { ox_sax_drive_error(dr, OUT_OF_ORDER "multiple top level elements"); } state = BODY_STATE; c = read_element_start(dr); if (0 == stack_peek(&dr->stack)) { state = AFTER_STATE; } break; } } else { buf_reset(&dr->buf); c = read_text(dr); } } DONE: if (dr->stack.head < dr->stack.tail) { char msg[256]; Nv sp; if (dr->has.line) { rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(dr->buf.line)); } if (dr->has.column) { rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(dr->buf.col)); } for (sp = dr->stack.tail - 1; dr->stack.head <= sp; sp--) { snprintf(msg, sizeof(msg) - 1, "%selement '%s' not closed", EL_MISMATCH, sp->name); ox_sax_drive_error_at(dr, msg, dr->buf.line, dr->buf.col); if (dr->has.end_element) { VALUE args[1]; args[0] = sp->val; rb_funcall2(dr->handler, ox_end_element_id, 1, args); } } } }
/************************************************* * read_token -- read token in input stream * argument * in_file -- input file * return * next token *************************************************/ TOKEN_TYPE token::next_token(input_file& in_file) { if (need_to_read_one) { in_file.read_char(); } need_to_read_one = 0; if (in_comment) { return (read_comment(in_file)); } while (char_type.is(in_file.cur_char, char_type::C_WHITE)) { in_file.read_char(); } if (in_file.cur_char == EOF) { return T_EOF; } switch (char_type.type(in_file.cur_char)) { case char_type::C_NEWLINE: in_file.read_char(); return T_NEWLINE; case char_type::C_ALPHA: while (char_type.is(in_file.cur_char, char_type::C_ALPHA_NUMERIC)) { in_file.read_char(); } return T_ID; case char_type::C_DIGIT: in_file.read_char(); if ((in_file.cur_char == 'X') || (in_file.cur_char == 'x')) { in_file.read_char(); while (char_type.is(in_file.cur_char, char_type::C_HEX_DIGIT)) { in_file.read_char(); } return T_NUMBER; } while (char_type.is(in_file.cur_char, char_type::C_DIGIT)) { in_file.read_char(); } return T_NUMBER; case char_type::C_SLASH: // check '/*' comment if (in_file.next_char == '*') { return (read_comment(in_file)); } // check '//' comment if (in_file.next_char == '/') { while (true) { if (in_file.cur_char == EOF) { return T_COMMENT; } if (in_file.cur_char == '\n') { return T_COMMENT; } in_file.read_char(); } } // fall through case char_type::C_OPERATOR: in_file.read_char(); return T_OPERATOR; case char_type::C_L_PAREN: in_file.read_char(); return T_L_PAREN; case char_type::C_R_PAREN: in_file.read_char(); return T_R_PAREN; case char_type::C_L_CURLY: in_file.read_char(); return T_L_CURLY; case char_type::C_R_CURLY: in_file.read_char(); return T_R_CURLY; case char_type::C_DOUBLE: while (true) { in_file.read_char(); if (in_file.cur_char == '"') { break; } if (in_file.cur_char == '\\') { in_file.read_char(); } } in_file.read_char(); return T_STRING; case char_type::C_SINGLE: while (true) { in_file.read_char(); if (in_file.cur_char == '\'') { break; } if (in_file.cur_char == '\\') { in_file.read_char(); } } in_file.read_char(); return T_STRING; default: assert("Internal error: Very strange character" != 0); } assert("Internal error: We should never get here" != 0); return T_EOF; }