// reading PPM_Image from a file PPM_Image::PPM_Image(const std::string &fn): bgcolor_{0}, vals_{} { std::ifstream ifs {fn, std::ios_base::binary}; if (!ifs) throw std::runtime_error("cannot open file " + fn); ifs.exceptions(ifs.exceptions() | std::ios_base::badbit); std::string header; ifs >> header; if (header != "P6") throw std::runtime_error("cannot read input file"); skip_comment(ifs); int w, h, temp; ifs >> w >> h >> temp; skip_comment(ifs); const int num_values {w * h * 3}; vals_ = std::vector<std::vector<uint>>(w, std::vector<uint>(h)); char *v = new char[num_values]; ifs.read(v, num_values); if (!ifs) delete [] v; for (int j {0}; j < h; ++j) for (int i {0}; i < w; ++i) { const int idx {(j * h + i) * 3}; vals_[i][j] = static_cast<uchar>(v[idx]) << 16 | static_cast<uchar>(v[idx + 1]) << 8 | static_cast<uchar>(v[idx + 2]); } delete [] v; }
char* scan_string(const char** document) { const char* cursor = *document; int length = 0; char* buffer = NULL; int i; while(*cursor != ARGLISTSEPARATESYM && *cursor != ARGLISTCLOSESYM && *cursor != '\0') { if(*cursor == COMMENTSYM) { skip_comment(&cursor); continue; } if(*cursor == TAGSYM) cursor++; if(*cursor == '\n') { skin_error(UNEXPECTED_NEWLINE, cursor); return NULL; } length++; cursor++; } /* Copying the string */ cursor = *document; buffer = skin_alloc_string(length); if (!buffer) return NULL; buffer[length] = '\0'; for(i = 0; i < length; i++) { if(*cursor == TAGSYM) cursor++; if(*cursor == COMMENTSYM) { skip_comment(&cursor); i--; continue; } buffer[i] = *cursor; cursor++; } *document = cursor; return buffer; }
void MutableVars::ReadValues(std::istream& is) { while (is) { skip_comment(is); ReadVariable(is); } }
ini_t *ini_parse(const gchar *buf, gsize len) { ini_parser_t *parser; if (buf == NULL || len == 0) { return NULL; } parser = g_new0(ini_parser_t, 1); parser->tokenizer = ini_tokenizer_new(buf, len); parser->ini = ini_new(); while (next_token(parser)->type != INI_TOKEN_EOF) { skip_whitespace(parser); switch (parser->curr_token->type) { case INI_TOKEN_EOL: case INI_TOKEN_EOF: continue; case INI_TOKEN_BRACKET_LEFT: parse_section_header(parser); break; case INI_TOKEN_TEXT: parse_key_value_pair(parser); break; case INI_TOKEN_SEMICOLON: skip_comment(parser); break; default: // XXX: Error. Log error and continue or shut down? break; } } return parser->ini; };
static void skip_comment(void) { safe_input(); /* '/' has already skipped, skip '*' */ for (;;) { switch (nextc) { case '*': safe_input(); /* '*' */ if (nextc == '/') { safe_input(); /* skip '/' */ return; } break; case '/': safe_input(); /* skip '/' */ if (nextc == '*') { skip_comment(); } break; case 0: /* EOF */ error("unexpected end-of-file in /* */ comment"); return; default: safe_input(); } } }
void skip_enumlist(const char** document) { if(**document == ENUMLISTOPENSYM) (*document)++; while(**document && **document != ENUMLISTCLOSESYM) { if(**document == TAGSYM) { (*document)++; if(**document == '\0') break; (*document)++; } else if(**document == ARGLISTOPENSYM) skip_arglist(document); else if(**document == ENUMLISTOPENSYM) skip_enumlist(document); else if(**document == COMMENTSYM) skip_comment(document); else (*document)++; } if(**document == ENUMLISTCLOSESYM) (*document)++; }
/* First pass of the assembler. You should implement pass_two() first. This function should read each line, strip all comments, scan for labels, and pass instructions to write_pass_one(). The input file may or may not be valid. Here are some guidelines: 1. Only one label may be present per line. It must be the first token present. Once you see a label, regardless of whether it is a valid label or invalid label, treat the NEXT token as the beginning of an instruction. 2. If the first token is not a label, treat it as the name of an instruction. 3. Everything after the instruction name should be treated as arguments to that instruction. If there are more than MAX_ARGS arguments, call raise_extra_arg_error() and pass in the first extra argument. Do not write that instruction to memory. 4. Only one instruction should be present per line. You do not need to do anything extra to detect this - it should be handled by guideline 3. 5. A line containing only a label is valid. The address of the label should be the byte offset of the next instruction, regardless of whether there is a next instruction or not. Just like in pass_two(), if the function encounters an error it should NOT exit, but process the entire file and return -1. If no errors were encountered, it should return 0. */ int pass_one(FILE* input, FILE* output, SymbolTable* symtbl) { /* YOUR CODE HERE */ char buf[BUF_SIZE]; uint32_t input_line = 0, byte_offset = 0; int ret_code = 0; // Read lines and add to instructions while(fgets(buf, BUF_SIZE, input)) { input_line++; // Ignore comments skip_comment(buf); // Scan for the instruction name char* token = strtok(buf, IGNORE_CHARS); // Scan for arguments char* args[MAX_ARGS]; int num_args = 0; // Checks to see if there were any errors when writing instructions unsigned int lines_written = write_pass_one(output, token, args, num_args); if (lines_written == 0) { raise_inst_error(input_line, token, args, num_args); ret_code = -1; } byte_offset += lines_written * 4; } return -1; }
/* * search for the next non-white character starting from the * current position */ static size_t find_nonwhite(const struct cfg_string *str, size_t current, enum cfg_status *status) { size_t i=0, loc=0; loc=current; *status=CFG_EOF; // this accounts for case where current is out of bounds for (i=current; i<str->size; i++) { if (!isspace(str->data[i])) { if (str->data[i] == CFG_COMMENT) { // found a comment, skip to next EOL i = skip_comment(str, i, status); // also set loc in case we exit the loop loc=i; if (*status==CFG_EOF) { // EOF, loc remains at current break; } continue; } *status=CFG_SUCCESS; loc=i; break; } } return loc; }
struct Token* get_token() { struct Token newToken; struct Token* retToken; char c = '\0'; retToken = (struct Token*)malloc(sizeof(struct Token)); c = skip_blanks(); if(peek_char() == '{') { c = skip_comment(); } if(char_table[c] == LETTER) { newToken = get_word(c); } else if(char_table[c] == DIGIT) { newToken = get_number(c); } else if(char_table[c] == QUOTE) { newToken = get_string(c); } else if(c == EOF) { newToken.literalValue.valString[0] = '.'; newToken.literalType = INTEGER_LIT; newToken.tokenCode = END_OF_FILE; } else if(char_table[c] == SPECIAL) { newToken = get_special(c); } memcpy(retToken, &newToken, sizeof(struct Token)); return retToken; }
static int trim_opening_comment( BFile file, long *funcOffPtr, long *funcLenPtr, long protoOff ) { #define funcOff (*funcOffPtr) #define funcLen (*funcLenPtr) long startOff = bfile_get_off(file); long newCommentOff = -1; long commentOff = -1; long funcLenDiff = 0; long newFuncOff = 0; COMMENT_TYPE commentType; BOOL done = FALSE; bfile_set_off(file, funcOff); bfile_forward(file); while (!done) { commentType = find_comment_start(file, &newCommentOff); if ( (commentType == COMMENT_UNDEF) || (newCommentOff >= protoOff) ) { done = TRUE; } else { commentOff = newCommentOff; skip_comment(file, commentType); } } if (commentOff > 0) { funcLenDiff = (funcOff - commentOff); funcOff = commentOff; funcLen += funcLenDiff; } /* * trim white space */ bfile_set_off(file, funcOff); skip_white(file); newFuncOff = bfile_get_off(file); funcLenDiff = (funcOff - newFuncOff); funcOff = newFuncOff; funcLen += funcLenDiff; bfile_set_off(file, startOff); return 0; #undef funcOff #undef funcLen }
/* First pass of the assembler. You should implement pass_two() first. This function should read each line, strip all comments, scan for labels, and pass instructions to write_pass_one(). The input file may or may not be valid. Here are some guidelines: 1. Only one label may be present per line. It must be the first token present. Once you see a label, regardless of whether it is a valid label or invalid label, treat the NEXT token as the beginning of an instruction. 2. If the first token is not a label, treat it as the name of an instruction. 3. Everything after the instruction name should be treated as arguments to that instruction. If there are more than MAX_ARGS arguments, call raise_extra_arg_error() and pass in the first extra argument. Do not write that instruction to the output file (eg. don't call write_pass_one()) 4. Only one instruction should be present per line. You do not need to do anything extra to detect this - it should be handled by guideline 3. 5. A line containing only a label is valid. The address of the label should be the byte offset of the next instruction, regardless of whether there is a next instruction or not. Just like in pass_two(), if the function encounters an error it should NOT exit, but process the entire file and return -1. If no errors were encountered, it should return 0. */ int pass_one(FILE* input, FILE* output, SymbolTable* symtbl) { //my own: setting the buffer and putting the input into it char buf[BUF_SIZE]; fgets(buf, BUF_SIZE, input); //my own: lines start at 1, and the byte offset at 0 uint32_t byte_offset = 0; int line_number = 1; //my own: tokenize by lines first strtok(buf, "\n"); while (strcmp(buf, "") == 0) { line_number++; strtok(buf, "\n"); } int errored = 0; while (buf != NULL) { skip_comment(buf); //myown: gets rid of comments for every line //my own: tokenize now by the args in each line char* args[50]; int num_args = 0; //my own: set it to 50, because... whos stupid enough to put in 50 args in MIPS... only idiots //my own: just have to do this because if the num_args > args size, GG. NO FIT. strtok(buf, " :,\n"); //myown: all the delimiters that could in MIPScode " :, and an new line" num_args = sizeof(args)/sizeof(args[0]); if (num_args > MAX_ARGS) { raise_extra_arg_error(line_number, args[1]); errored++; } int label1 = add_if_label(line_number, args[0], byte_offset, symtbl); int label2 = add_if_label(line_number, args[1], byte_offset, symtbl); if (label1 == -1) { errored++; line_number++; strtok(buf, "\n"); } else if (label2 == 1) { raise_extra_arg_error(line_number, args[1]); errored++; line_number++; strtok(buf, "\n"); } else if (label1 == 0) { //Myown:It's not a label. Treat like a reg instruction //Myown: pass in instructions into write_pass_one write_pass_one(output, args[0], args, num_args); byte_offset += 4; } else if (label1 == 1) { //My own: Adding label to the symbol table add_to_table(symtbl, args[0], byte_offset); byte_offset += 4; } line_number++; strtok(buf, "\n"); } if (errored > 0) { return -1; } else { return 0; } }
/*----------------------------------------------------------------------*/ static void skip_comments_and_whitespace(lex_state_t *l) { for (;;) { const char *old = l->ptr; skip_whitespace(l); skip_comment(l); if (old == l->ptr) break; } }
int scan_int(const char** document) { const char *cursor = *document, *end; int length = 0; char buffer[16]; int retval; int i; while(isdigit(*cursor) || *cursor == COMMENTSYM || *cursor == '-') { if(*cursor == COMMENTSYM) { skip_comment(&cursor); continue; } length++; cursor++; } if (length > 15) length = 15; end = cursor; /* Copying to the buffer while avoiding comments */ cursor = *document; buffer[length] = '\0'; for(i = 0; i < length; i++) { if(*cursor == COMMENTSYM) { skip_comment(&cursor); i--; continue; } buffer[i] = *cursor; cursor++; } retval = atoi(buffer); *document = end; return retval; }
Token *ScannerImp::nextToken() { if(skip_spaces())return NULL; runMachines(); TType typ = manager->getType(); skip_comment(&typ); int wortlaenge = manager->getLexemLength(); int wrongChars = manager->ungetCtr(); buffer->ungetChar(wrongChars); return createToken(typ,wortlaenge,x,y); }
void Scanner::skip_non_token() { while (1) { if ((is_space(cur_char()))) { go_ahead(); } else if (is_comment_start()) { skip_comment(); } else { return ; } } }
static char get_char(char token_string[]) { /* If at the end of the current line (how do you check for that?), we should call get source line. If at the EOF (end of file) we should set the character ch to EOF and leave the function. Write some code to set the character ch to the next character in the buffer checks the current state of the source_buffer and gets a new line of code if it is at the end of a line. If it sees a Pascal Comment it skips the comment (a pascal comment is anything between ‘{‘ and ‘}’). */ static char source_buffer[MAX_SOURCE_LINE_LENGTH]; static size_t i = 0; size_t nextIndex = 0; char ch; if ((source_buffer[i] == '\0') || (source_buffer[i] == '\n')) { i = 0; BOOLEAN ret = get_source_line(source_buffer); if (ret == FALSE) { ch = EOF; return ch; } else { i = skip_blanks(source_buffer, i); i = skip_comment(source_buffer, i); ch = source_buffer[i]; } } else { ch = source_buffer[i]; } nextIndex = buildToken(source_buffer, token_string, i); i = nextIndex; return ch; }
char get_token() { // char token_string[MAX_TOKEN_STRING_LENGTH]; //Store your token here as you build it. get_source_line(token_string); while(token_string[0] != '\0') { //printf("I went through the while loop: %d times\n", debugCount); //debug line transfer(skipArray,token_string); skip_blanks(skipArray); //1. Skip past all of the blanks transfer(token_string,skipArray); //printf("This is token_string after skip_blanks :2%s2\n", token_string); //debug //printf("ldksaf"); if(token_string[0] == '\n') { return 'a'; } if(token_string[0] == '.') { printf("\t>> .\t.\n"); return '.'; } if(isalpha(token_string[0])) { get_word(); } else if(isdigit(token_string[0])) { //token_string = get_number(token_string); get_number(); } else if(token_string[0] == '\'') { //token_string = get_string(token_string); get_string(); } else if(token_string[0] == '{'){ skip_comment(token_string); } else { if(token_string[0] == '.') { return '.'; } get_special(); } } return 'a'; //What should be returned here? }
PPM_Image read_ppm_image(const std::string &fn) { std::ifstream ifs {fn, std::ios_base::binary}; if (!ifs) throw std::runtime_error("cannot open file " + fn); ifs.exceptions(ifs.exceptions() | std::ios_base::badbit); std::string header; ifs >> header; if (header != "P6") throw std::runtime_error("cannot read input file"); skip_comment(ifs); int w, h, t; ifs >> w >> h >> t; skip_comment(ifs); PPM_Image img {w, h}; const int num_pixels {w * h}, num_values {num_pixels * 3}; char *v = new char[num_values]; ifs.read(v, num_values); for (int i {0}; i < num_pixels; ++i) img.pixel_color(i, PPM_Color(v[i * 3], v[i * 3 + 1], v[i * 3 + 2])); delete [] v; return img; }
static char* get_char(char source_buffer[MAX_TOKEN_STRING_LENGTH], char *token_ptr) { if(source_buffer[0] == NULL) { if(!get_source_line(source_buffer)) { return '.'; } token_ptr = &source_buffer[0]; } if((*(token_ptr)) == 10) { if(!get_source_line(source_buffer)) { return '.'; } token_ptr = source_buffer; if(*(token_ptr) == '\n') { token_ptr = get_char(source_buffer,token_ptr); } } if((*(token_ptr)) == 46) { *token_ptr = '.'; return token_ptr; } if((*(token_ptr)) == 123) { token_ptr = skip_comment(token_ptr); } if(*token_ptr == 9) // Horizontal Tabs are a pain in my rump!!! { token_ptr++; if(*(token_ptr) == 9) //Recursively make them go away. { token_ptr = get_char(source_buffer,token_ptr); } } if((*(token_ptr)) == 32) { token_ptr = skip_blanks(token_ptr); //1. Skip past all of the blanks } /* If at the end of the current line (how do you check for that?), we should call get source line. If at the EOF (end of file) we should set the character ch to EOF and leave the function. */ return token_ptr; }
Token* get_token() { char ch; //This can be the current character you are examining during scanning. static char* current_char = src_name; //This is the pointer to the current character being read char token_string[MAX_TOKEN_STRING_LENGTH]; //Store your token here as you build it. char *token_ptr = token_string; //write some code to point this to the beginning of token_string Token* token = (Token *) malloc(sizeof(Token)); //I am missing the most important variable in the function, what is it? Hint: what should I return? ch = get_char(¤t_char); //1. Skip past all of the blanks //2. figure out which case you are dealing with LETTER, DIGIT, QUOTE, EOF, or special, by examining ch //3. Call the appropriate function to deal with the cases in 2. if (ch == ' '){ ch = *(skip_blanks(¤t_char)); } else if (ch == '{'){ ch = *(skip_comment(¤t_char)); } if (ch == '\n'){ ch = get_char(¤t_char); } if (char_table[ch] = DIGIT){ token_string[0] = ch; token -> literal_type = INTEGER_LIT; token -> token_code = NUMBER; get_number(¤t_char, token_string, token_ptr); } else if (ch == '\''){ token -> literal_type = STRING_LIT; token -> token_code = STRING; get_string(¤t_char,token_string, token_ptr); } else if (char_table[ch] = LETTER){ token_string[0] = ch; token -> literal_type = REAL_LIT; get_word(¤t_char,token_string, token_ptr, token); } else if (char_table[ch] = SPECIAL){ token -> literal_type = REAL_LIT; token_string[0] = ch; get_special(¤t_char,token_string, token_ptr, token); } token -> content = (char *) malloc(sizeof(char) * strlen(token_string)); strcpy(token -> content, token_string); return token; //What should be returned here? }
void imread(uint8_t* *_I,unsigned int *_sy,unsigned int *_sx, unsigned int *_dim, unsigned int *_mode, const char *fname ) { FILE *pf; unsigned int dim,mode; unsigned int iFormat; unsigned int sy,sx,tone; unsigned int nPix; unsigned int szImgByte; if((pf = fopen(fname,"r")) ==NULL) { printf("Can not open file\n"); exit(-1); } fscanf( pf,"P%d\n",&iFormat); switch(iFormat) { case 5: mode = GRAY; dim = 1; break; default: printf("Do not support format\n"); exit(-1); break; } skip_comment(pf); fscanf(pf,"%d %d %d ",&sx,&sy,&tone); nPix = sy * sx; szImgByte = nPix * dim * sizeof(uint8_t); uint8_t *I = (uint8_t*)malloc( nPix * dim * sizeof(uint8_t) ); fread(I,szImgByte,1,pf); *_I = I; *_sy = sy; *_sx = sx; *_dim = dim; *_mode = mode; }
static int cmygetc(void) { int c; for (;;) { c = mygetc(); if (c == '/') { if (gobble('*')) skip_comment(); else return c; } else return c; } }
inline static void next_non_white(ParseInfo pi) { for (; 1; pi->s++) { switch(*pi->s) { case ' ': case '\t': case '\f': case '\n': case '\r': break; case '/': skip_comment(pi); break; default: return; } } }
char skip_comment() { char c; do { c = get_char(); } while(c != '}'); c = get_char(); if(c == ' ' || c == '\n' || c == '\0') { c = skip_blanks(); } if(c == '{') { return skip_comment(); } else { return c; } }
// Image stuff void skip_comment(FILE * fin) { int c; // Skip whitespace; do { c = fgetc(fin); } while (isspace(c)); ungetc(c, fin); // Check for another comment if (c != '#') return; // Read until a newline do { c = fgetc(fin); } while (c != '\n'); skip_comment(fin); }
/************************************************************************ ** skip_cwhite : while the current character is whitespace or a comment. ** a newline is NOT whitespace. ************************************************************************/ WCHAR skip_cwhite(void) { REG WCHAR c; skip_cwhite_again: while((c = GETCH()) <= L'/') { /* many chars are above this */ if(c == L'/') { if( ! skip_comment()) { return(L'/'); } } else if(c > L' ') { /* char is between '!' and '.' */ return(c); } else { switch(CHARMAP(c)) { case LX_EOS: handle_eos(); break; case LX_WHITE: continue; break; case LX_CR: continue; break; default: return(c); break; } } } if((c == L'\\') && (checknl())) { goto skip_cwhite_again; } return(c); }
void mark_comments(char c, char *str) { char *ptr = str; char *e = str + strlen(str); while(*ptr) { char_class_t cc = char_class(*ptr); switch(cc) { case CC_NONE: ptr++; break; case CC_COMMENT: { char *start = ptr; ptr = (char *)skip_comment(ptr, e); if(ptr == start) { ptr++; } else { memset(start, c, ptr - start); } break; } default: while(char_class(*++ptr) != CC_NONE); } } }
// --- bool get_token( const char*& s, CStr& t ) { if ( !s ) return false; while( isspace(*s) ) s++; while( skip_comment(s) ) ; switch( *s ) { case TERM: return false; case STAR : case BRACKET_O : case BRACKET_C : case BRACE_O : case COMMA : case SEMICOLON : case COLON : ((char*)memcpy( t=new char[2], s++, 1 ))[1] = 0; return true; } const char* b = s; while( iscsym(*s) ) s++; if ( s > b ) { ((char*)memcpy( t=new char[s-b+1], b, s-b ))[s-b] = 0; return true; } else { t = 0; return false; } }
/* skips whitespaces (and comment lines). parameter "single" determines whether only one whitespace character (besides comments) should be skipped */ static int skip_whitespace(FILE *f, int single) { size_t n = 0; int err; clearerr(f); for (;;) { err = fgetc(f); if (err == REMARK_CHAR) { if ((err = skip_comment(f)) != PIXF_ERR_OK) return err; else continue; } if (err == EOF || !IS_PNM_SPACE(err)) break; if (single && n > 0) break; n++; } if (err == EOF && ferror(f)) { #ifdef PIXF_ENABLE_VERBOSE if (pixf_verbose) fprintf(stderr, "%s: Error reading from file: %s\n", __func__, strerror(errno)); #endif return PIXF_ERR_READ; } ungetc(err, f); /* return first non-whitespace char back to the stream */ return PIXF_ERR_OK; }
static int next_token(parser_ctx_t *ctx, void *lval) { do { skip_spaces(ctx); if(ctx->ptr == ctx->end) return tEOF; }while(skip_comment(ctx) || skip_html_comment(ctx)); if(isalphaW(*ctx->ptr)) { int ret = check_keywords(ctx, lval); if(ret) return ret; return parse_identifier(ctx, lval); } if(isdigitW(*ctx->ptr)) return parse_numeric_literal(ctx, lval); switch(*ctx->ptr) { case '{': case '(': case ')': case '[': case ']': case ';': case ',': case '~': case '?': case ':': return *ctx->ptr++; case '}': *(const WCHAR**)lval = ctx->ptr++; return '}'; case '.': if(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) return parse_double_literal(ctx, 0, lval); return '.'; case '<': if(++ctx->ptr == ctx->end) { *(int*)lval = EXPR_LESS; return tRelOper; } switch(*ctx->ptr) { case '=': /* <= */ ctx->ptr++; *(int*)lval = EXPR_LESSEQ; return tRelOper; case '<': /* << */ if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* <<= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNLSHIFT; return tAssignOper; } *(int*)lval = EXPR_LSHIFT; return tShiftOper; default: /* < */ *(int*)lval = EXPR_LESS; return tRelOper; } case '>': if(++ctx->ptr == ctx->end) { /* > */ *(int*)lval = EXPR_GREATER; return tRelOper; } switch(*ctx->ptr) { case '=': /* >= */ ctx->ptr++; *(int*)lval = EXPR_GREATEREQ; return tRelOper; case '>': /* >> */ if(++ctx->ptr < ctx->end) { if(*ctx->ptr == '=') { /* >>= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNRSHIFT; return tAssignOper; } if(*ctx->ptr == '>') { /* >>> */ if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* >>>= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNRRSHIFT; return tAssignOper; } *(int*)lval = EXPR_RRSHIFT; return tRelOper; } } *(int*)lval = EXPR_RSHIFT; return tShiftOper; default: *(int*)lval = EXPR_GREATER; return tRelOper; } case '+': ctx->ptr++; if(ctx->ptr < ctx->end) { switch(*ctx->ptr) { case '+': /* ++ */ ctx->ptr++; return tINC; case '=': /* += */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNADD; return tAssignOper; } } return '+'; case '-': ctx->ptr++; if(ctx->ptr < ctx->end) { switch(*ctx->ptr) { case '-': /* -- or --> */ ctx->ptr++; if(ctx->is_html && ctx->nl && ctx->ptr < ctx->end && *ctx->ptr == '>') { ctx->ptr++; return tHTMLCOMMENT; } return tDEC; case '=': /* -= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNSUB; return tAssignOper; } } return '-'; case '*': if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* *= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNMUL; return tAssignOper; } return '*'; case '%': if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* %= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNMOD; return tAssignOper; } return '%'; case '&': if(++ctx->ptr < ctx->end) { switch(*ctx->ptr) { case '=': /* &= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNAND; return tAssignOper; case '&': /* && */ ctx->ptr++; return tANDAND; } } return '&'; case '|': if(++ctx->ptr < ctx->end) { switch(*ctx->ptr) { case '=': /* |= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNOR; return tAssignOper; case '|': /* || */ ctx->ptr++; return tOROR; } } return '|'; case '^': if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* ^= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNXOR; return tAssignOper; } return '^'; case '!': if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* != */ if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* !== */ ctx->ptr++; *(int*)lval = EXPR_NOTEQEQ; return tEqOper; } *(int*)lval = EXPR_NOTEQ; return tEqOper; } return '!'; case '=': if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* == */ if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* === */ ctx->ptr++; *(int*)lval = EXPR_EQEQ; return tEqOper; } *(int*)lval = EXPR_EQ; return tEqOper; } return '='; case '/': if(++ctx->ptr < ctx->end) { if(*ctx->ptr == '=') { /* /= */ ctx->ptr++; *(int*)lval = EXPR_ASSIGNDIV; return kDIVEQ; } } return '/'; case '\"': case '\'': return parse_string_literal(ctx, lval, *ctx->ptr); case '_': case '$': return parse_identifier(ctx, lval); case '@': return '@'; } WARN("unexpected char '%c' %d\n", *ctx->ptr, *ctx->ptr); return 0; }