void generate_seqences(char *start, int length, int frame, struct ht_ht *ht) { uint64_t code = 0; uint64_t mask = (1ull << 2*frame) - 1; char *p = start; char *end = start + length; // Pull first frame. for (int i = 0; i < frame; i++) { code = push_char(code, *p); ++p; } ht_find_new(ht, code)->val++; while (p < end) { code = push_char(code, *p) & mask; ht_find_new(ht, code)->val++; ++p; if (*p & 8) { if (*p & 1) { ++p; } else break; } } }
int Scanner::read_num() { clear_token(); bool hex_dec_mode = false; if (cur_char() == '0' && next_char() == 'x') { push_char(cur_char()); go_ahead(); push_char(cur_char()); go_ahead(); hex_dec_mode = true; } while (true) { char c = cur_char(); if (hex_dec_mode) { if (!is_hex_dec(c)) { break; } } else { if (!is_dec(c)) { break; } } push_char(cur_char()); go_ahead(); } return s_info->num_token; }
int main(int argc, char* argv[]){ char c; char last_c = '_'; unsigned int counter = 1; c = getchar(); while( !( (last_c=='0')&&(c=='\n')&&counter==2 )){ if(c=='\n') counter=0; if(counter == 2 && last_c=='0'){ push_char(last_c); } if(!( c=='0' && counter == 1)){ push_char(c); } last_c = c; c = getchar(); counter++; } return 0; }
/*************************************************************** Return the current state of all parts of robot ***************************************************************/ void return_all() { //printf(" in return_all_sensors() "); start_checksum(); push_char(0x50); push_char(0xAF); push_char(0x81); push_word(get_sonar(1)); push_word(get_sonar(2)); push_word(get_sonar(3)); push_word(get_line_follower(1)); push_word(get_line_follower(2)); push_word(get_line_follower(3)); push_word(get_gyro()); push_byte(get_bumper(1)); # check new spec push_byte(get_bumper(2)); push_byte(get_motor(1)); push_byte(get_motor(2)); push_byte(get_motor(3)); send_checksum(); // Now 3 + 6 + 6 + 2 + 2 + 3 + 1 = 23 }
/*************************************************************** Set the state of single motor ***************************************************************/ void set_single_motor(int id, int power) { set_motor(id, _dec(power)); start_checksum(); push_char(0x50); push_char(0xAF); push_char(0x01); push_char(0x10 + id); send_checksum(); }
/*************************************************************** Set the current state of drive motors ***************************************************************/ void set_drive_motors(int power1, int power2) { set_motor(1, _dec(power1)); set_motor(2, _dec(power2)); start_checksum(); push_char(0x50); push_char(0xAF); push_char(0x01); push_char(0x60); send_checksum(); }
/*************************************************************** Set the forward speed and turn rate ***************************************************************/ void set_speed_and_turn(int spd, int turn) { int speed = _dec(spd); int turnrate = _dec(turn); set_motor(1, 0); set_motor(2, 0); start_checksum(); push_char(0x50); push_char(0xAF); push_char(0x01); push_char(0x61); send_checksum(); }
static int P_INLINE end_field(parser_t *self) { // XXX cruft self->numeric_field = 0; // null terminate token push_char(self, '\0'); // set pointer and metadata self->words[self->words_len] = self->pword_start; TRACE(("Char diff: %d\n", self->pword_start - self->words[0])); TRACE(("Saw word %s at: %d. Total: %d\n", self->pword_start, self->word_start, self->words_len + 1)) self->word_starts[self->words_len] = self->word_start; self->words_len++; // increment line field count self->line_fields[self->lines]++; // New field begin in stream self->pword_start = self->stream + self->stream_len; self->word_start = self->stream_len; return 0; }
int Scanner::read_sym() { clear_token(); while (is_symbody(cur_char())) { push_char(cur_char()); go_ahead(); } return s_info->sym_token; }
uint64_t pack_key(char *key, int len) { uint64_t code = 0; for (int i = 0; i < len; i++) { code = push_char(code, *key); key = next_char(key); } return code; }
/*************************************************************** Return the current state of all sensors ***************************************************************/ void return_all_sensors() { //printf(" in return_all_sensors() "); start_checksum(); push_char(0x50); push_char(0xAF); push_char(0x80); // fake data for now push_byte(get_sonar(1)); push_byte(get_sonar(2)); push_byte(get_sonar(3)); push_byte(get_line_follower(1)); push_byte(get_line_follower(2)); push_byte(get_line_follower(3)); push_byte(get_gyro()); push_byte(get_bumper(1)); push_byte(get_bumper(2)); send_checksum(); // Now 3 + 3 + 3 + 3 + 1 = 13 }
static bool push_foo(char **p, size_t *len, const struct foo *foo) { return push_u64(p, len, foo->vu64) && push_u32(p, len, foo->vu32) && push_u16(p, len, foo->vu16) && push_u8(p, len, foo->vu8) && push_uchar(p, len, foo->vuchar) && push_s64(p, len, foo->vs64) && push_s32(p, len, foo->vs32) && push_s16(p, len, foo->vs16) && push_s8(p, len, foo->vs8) && push_char(p, len, foo->vchar) && push_bytes(p, len, foo->bytes, sizeof(foo->bytes)); }
main() { int type; double op2; char c; char s[MAXOP]; while ((type = getop(s)) != EOF) { switch (type) { case NUMBER: push_token(NUMBER, atof(s)); break; case '+': case '-': case '/': case '*': case '%': while (((c = top_char()) != EOF) && islesseq(type, c)) push_token(pop_char(), -1); push_char(type); break; case '(': push_char(type); break; case ')': while (((c = pop_char()) != EOF) && c != '(') push_token(c, -1); break; case '\n': while ((c = pop_char()) != EOF) push_token(c, -1); calc(); break; case 'q': return; default: printf("error: unknown command %s\n", s); break; } } }
static clj_Result read_token(clj_Type type, clj_Reader *r, wint_t initch, size_t initial_capacity, char_pred terminates) { wint_t c; StringBuffer strbuf; strbuf_init(&strbuf, initial_capacity); strbuf_append(&strbuf, initch); while (1) { c = pop_char(r); if (WEOF == c || is_clj_whitespace(c) || terminates(c)) { push_char(r, c); emit(r, type, strbuf.chars); strbuf_free(&strbuf); break; } else { strbuf_append(&strbuf, c); } } return ok_read(c); }
void exec_eil(int field_size){ Odescr *address = pop_tstack(); switch(field_size){ case sizeof(int):{ push_int(*((int *)address->inst.sval)); break; } case sizeof(char):{ push_char(*((char *)address->inst.sval)); break; } case sizeof(char *):{ char** act = (char **)address->inst.sval; push_string(act[0]); break; } default:{ machine_error("EIL field_size error."); break; } } freemem((char*)address, sizeof(Odescr)); // only dealloc the object and not the inst }
int past(t_elem *e, t_string *cpy, t_string *save) { if (e->clipboard) { while (cpy) { my_tputs(e->cap[VI]); push_char(e, cpy->c, 0); cpy = cpy->next; } e->cursor = e->s; my_tputs(e->cap[VI]); while (move_right_write(e) != -1); my_tputs(e->cap[VI]); _bol(e, 0); my_tputs(e->cap[VI]); while (e->cursor != save) move_right(e); } return (0); }
int Scanner::read_str() { clear_token(); go_ahead(); while (1) { int c = cur_char(); if (c == '\n') { return -1; } if (c == '\"') { go_ahead(); break; } if (c == '\\') { go_ahead(); c = cur_char(); } push_char(c); go_ahead(); } return s_info->str_token; }
static clj_Result read_delimited(clj_Type type, clj_Reader *r, const wchar_t *begin, wint_t terminator) { wint_t c; const wchar_t end[] = {terminator, L'\0'}; form_reader macro_reader; emit(r, type, begin); r->depth++; while (1) { c = skip_whitespace(r); if (c == terminator) { r->depth--; emit(r, type | CLJ_END, end); return CLJ_MORE; } else if ((macro_reader = get_macro_reader(c))) { macro_reader(r, c); } else if (c == WEOF) { reader_error(r, CLJ_UNEXPECTED_EOF); } else { push_char(r, c); read_form(r); } } }
Token* Scanner::read_op(fint c) { fint l = line; fint col = column - 1; const char* ss = sourceAddr() - 1; buffer[0] = char(c); fint len = 1; while (is_punct(c = get_char())) buffer[len++] = char(c); push_char(c); buffer[len] = '\0'; Token::TokenType t; String* s = NULL; if (strcmp(buffer, "<-") == 0) t = Token::ARROW; else if (strcmp(buffer, "=") == 0) t = as_TokenType('='); else if (strcmp(buffer, "|") == 0) t = as_TokenType('|'); else if (strcmp(buffer, "^") == 0) t = as_TokenType('^'); else if (strcmp(buffer, "\\") == 0 && (c == '\n' || c == '\r')) { get_char(); return get_token(); } else { t = Token::OPERATOR; s = new String(copy_string(buffer)); } return new Token(t, s, l, col, ss); }
static wint_t peek_char(clj_Reader *r) { wchar_t c = pop_char(r); push_char(r, c); return c; }
void input_schema(Pschema s, char *attr_name, int spaces, int pretty, FILE *in_file){ // reads a schema and puts it on the top op tstack if(attr_name!=NULL && pretty){ print_spaces(spaces, stdout); fprintf(stdout, "Input record attribute \"%s\"\n",attr_name); } if(pretty){ print_spaces(spaces, stdout); } if(s->type == TY_RECORD || s->type == TY_ARRAY || s->type == TY_ATTR){ int size = get_schema_size(s); int nfields = 0; switch(s->type){ case TY_RECORD:{ if(pretty){ fprintf(stdout,"Input for a record\n"); } Pschema temp = s->child; while(temp){ input_schema(temp->child, temp->id, spaces+1, pretty, in_file); nfields++; temp = temp->brother; } break; } case TY_ARRAY:{ int i; if(pretty){ fprintf(stdout, "Input for an array\n"); } nfields = s->size; for(i=0; i<nfields; i++){ input_schema(s->child, NULL, spaces+1, pretty, in_file); } break; } default: print_schema(s,0); machine_error("TY_ATTR cannot be used in input_schema()."); break; } exec_cat(nfields,size); } else{ switch(s->type){ case TY_INT: { int in = read_int(stdout, in_file, "Insert an integer: ", pretty); push_int(in); break; } case TY_CHAR: { char in = read_char(stdout, in_file, "Insert a char: ", pretty); push_char(in); break; } case TY_REAL: { float in = read_real(stdout, in_file, "Insert a number of type real: ", pretty); push_real(in); break; } case TY_STRING: { char *in = read_string(stdout, in_file, "Insert a string: ", pretty); char *strig_to_store = stringtable_store(in, stringtable); freemem(in, strlen(in) + 1); push_string(strig_to_store); break; } case TY_BOOL: { char in = read_char(stdout, in_file, "Insert a boolean (0 or 1): ", pretty); push_bool(in == '1'); break; } default: {machine_error("Unknown type of schema in input_schema()."); break;} } } }
void exec_ldc(char c){ push_char(c); }
Token* Scanner::get_token() { Token* t; if (tokens) { t = tokens->token; tokens = tokens->prev; } else { t = NULL; while (t == NULL) { fint c = get_char(); switch (c) { case EOF: depth = 0; t = new Token(Token::ACCEPT, line, column, sourceAddr()); break; case '\n': case '\r': if (depth <= 0 && !is_string_scanner()) { t = new Token(Token::ACCEPT, line, column - 1, sourceAddr() - 1); depth = 0; } break; case ' ': case '\t': case '\v': case '\b': case '\f': break; case '"': t = skip_comment(); break; case '(': depth ++; t = new Token(as_TokenType('('), line, column - 1, sourceAddr() - 1); break; case ')': depth --; t = new Token(as_TokenType(')'), line, column - 1, sourceAddr() - 1); break; case '[': depth ++; t = new Token(as_TokenType('['), line, column - 1, sourceAddr() - 1); break; case ']': depth --; t = new Token(as_TokenType(']'), line, column - 1, sourceAddr() - 1); break; case '.': t = read_dot(); break; case '\'': t = read_string(); break; case '\\': c = get_char(); if (c == '\n' || c == '\r') { // an escaped newline; ignore } else { push_char(c); c = '\\'; t = read_op(c); } break; case '{': t = new Token(Token::ANNOTATION_START, line, column - 1, sourceAddr() - 1); break; case '}': t = new Token(Token::ANNOTATION_END, line, column - 1, sourceAddr() - 1); break; default: if (is_digit(c) || c == '-') t = read_number(c); else if (is_id_alpha(c) || c == ':') t = read_name(c); else if (is_punct(c)) t = read_op(c); else t = TokenizingError("unknown character in input"); } } } if (t && PrintTokens) t->print(); return t; }
Token* Scanner::read_number(fint c) { const int MAXSELFINT = smiOop_max->value() + 1; // maximum Self integer + 1 fint l = line; fint col = column - 1; const char* ss = sourceAddr() - 1; bool neg = false; Token::TokenType t = Token::INTEGER; if (c == '-') { neg = true; c = get_char(); if (!is_digit(c)) { push_char(c); return read_op('-'); } } int32 i = asnum(c); fint base; double f = 0; if (c == '0') { if (c = get_char(), c == 'x' || c == 'X') { return TokenizingError("invalid numeric constant (use 16r...)"); } else if (is_digit(c)) { return TokenizingError("C-style octals are not supported (use 8r...)"); } else { push_char(c); } } while (is_digit(c = get_char())) { // read decimal number /* The following test is necessary; else i*10 may overflow. */ if (i > MAXSELFINT / 10) return TokenizingError("numeric constant too large"); i *= 10; i += asnum(c); if (i > MAXSELFINT || (i == MAXSELFINT && !neg)) { return TokenizingError("numeric constant too large"); } } if (c == 'r' || c == 'R') { // base specification ? c = get_char(); if (i < 2 || i > 36) { return TokenizingError("illegal base for numeric literal"); } base = i; i = 0; if (is_alphadigit(c)) { do { fint v = asnum(c); if (v >= base) { if (is_digit(c)) { return TokenizingError("digit too large for given base"); } else { return TokenizingError("need spaces between numeric literals and selectors\n\t(letter too large for given base)"); } } int32 newi = i * base + v; int32 maxi = MAXSELFINT / base; if ((i > maxi || (i == maxi && !neg)) || (newi > MAXSELFINT || (newi == MAXSELFINT && !neg))) { return TokenizingError("numeric constant too large"); } i = newi; c = get_char(); } while (is_digit(c) || (base > 10 && is_alphadigit(c))); } else { return TokenizingError("expecting a number after the base specifier"); } } else { if (is_alpha(c) && c != 'e' && c != 'E') { return TokenizingError("need spaces between numeric literals and selectors"); } if (c == '.') { // read fraction part c = get_char(); if (is_digit(c)) { t = Token::FLOAT; double place = 1.0; f = (double) i; do { fint v = asnum(c); f += v * (place /= 10.0); } while (c = get_char(), is_digit(c)); } else { push_char(c); c = '.'; } } if (c == 'e' || c == 'E') { // read exponent if (t == Token::INTEGER) { t = Token::FLOAT; f = (double) i; } bool sign = false; c = get_char(); if (c == '+') { c = get_char(); } else if (c == '-') { c = get_char(); sign = true; } fint exp = asnum(c); if (! is_digit(c)) { return TokenizingError("illegal exponent"); } while (is_alphadigit(c = get_char())) { if (! is_digit(c)) { return TokenizingError("illegal exponent"); } exp *= 10; exp += asnum(c); } if (sign) { while (exp --) f /= 10.0; } else { while (exp --) f *= 10.0; } } } push_char(c); if (neg) { if (t == Token::INTEGER) i = - i; else f = - f; } if (t == Token::INTEGER) { return new Token(t, ss, i, l, col); } else { assert(t == Token::FLOAT, "unexpected token type"); return new Token(t, f, l, col, ss); } }
Token* Scanner::read_name(fint c) { Token::TokenType t; fint l = line; fint col = column - 1; const char* ss = sourceAddr() - 1; fint len; if (c == ':') { t = Token::ARG; len = 0; } else { t = c == '_' ? Token::PRIMNAME : Token::NAME; len = 1; buffer[0] = char(c); } while (c = get_char(), is_id_char(c)) { buffer[len++] = char(c); } if (c == ':' && (t == Token::NAME || t == Token::PRIMNAME)) { buffer[len++] = char(c); if (is_upper((fint)*buffer)) t = Token::CAPKEYWORD; else t = c == '_' ? Token::PRIMKEYWORD : Token::KEYWORD; } else { push_char(c); } buffer[len] = '\0'; if (t == Token::ARG && len == 0) { t = as_TokenType(':'); } else if (t == Token::NAME || t == Token::PRIMNAME) { c = get_char(); if (c == '.') { c = get_char(); push_char(c); if (is_id_alpha(c) || is_punct(c)) { t = Token::DELEGATE; } else { push_char('.'); } } else { push_char(c); } } if (strcmp(buffer, "self") == 0) { if (t == Token::NAME) { t = Token::SELF_TOKEN; } else { return TokenizingError( "using \"self\" as a parent name for a directed resend"); } } else if (strcmp(buffer, "resend") == 0) { if (t == Token::DELEGATE) { t = Token::RESEND_TOKEN; } else { return TokenizingError("not using \"resend\" in a resend"); } } String* s; if (t == Token::NAME || t == Token::PRIMNAME || t == Token::ARG || t == Token::DELEGATE || t == Token::KEYWORD || t == Token::PRIMKEYWORD || t == Token::CAPKEYWORD) { s = new String(copy_string(buffer)); } else { s = NULL; } return new Token(t, s, l, col, ss); }
bool Scanner::is_done() { fint c = get_char(); if (c == EOF) return true; push_char(c); return false; }
int main( int argc, char * argv[] ) { int tmp; int i = 0; int num1; int num2; int new_num; char op; char * src; char cur_op; char top_op; printf( "expression value demo begin !\n" ); #if 0 push_int( 100 ); push_int( 200 ); tmp = pop_int(); printf( "pop is %d \n", tmp ); tmp = pop_int(); printf( "pop is %d \n", tmp ); #endif if( argc > 1 ) printf( "input expression string is %s \n", argv[1] ); else exit(0); src = argv[1]; push_char( '\0'); while( 1 ) { printf( "src[%d] = %c \n", i, src[i] ); get_num: /* get a number */ num1 = get_number( src[i] ); if( num1 >= 0 ) printf( "get a number : %d \n", num1 ); else break; /* push this number */ printf( "push current int : %d \n", num1 ); push_int( num1 ); /* get the next op */ i++; cur_op = get_operator( src[i] ); if( cur_op > 0 ) printf( "get a operator: %c \n", cur_op ); else if( cur_op == '\0' ) { printf( "get a operator == 0: %c \n", cur_op ); } cmp_op: top_op = get_top_char(); printf( "get top stack operator: %c \n", top_op ); /* if current op > stack top op, then push current op */ if( get_prio( cur_op ) > get_prio( top_op ) ) { printf( "<push> push current op : %c \n", cur_op ); push_char( cur_op ); printf( "<push> push ok!\n" ); } else { op = pop_char(); num2 = pop_int(); if( op == '\0' ) { printf( "op == 0, last result = %d \n", num2 ); exit( 0 ); } num1 = pop_int(); printf( "<calc> pop 2 num and 1 op, do calc: %d %c %d \n", num1, op, num2 ); new_num = calc( num1, num2, op ); printf( "get calc result: %d \n", new_num ); /* push this new number */ printf( "push new int : %d \n", new_num ); push_int( new_num ); goto cmp_op; } /* get the next op */ i++; } return 0; }
/* The following is called from the serial driver when bytes/breaks * are received on the Mouse line. */ void sun_mouse_inbyte(unsigned char byte, int is_break) { signed char mvalue; int d, pushed = 0; Firm_event ev; add_mouse_randomness (byte); #if 0 { static int xxx = 0; printk("mouse(%02x:%d) ", byte, is_break); if (byte == 0x87) { xxx = 0; printk("\n"); } } #endif if (mouse_baud_detection(byte, is_break)) return; if(!sunmouse.active) return; /* Ignore this if it is garbage. */ if (sunmouse.byte == 69) { if (byte != 0x87) return; /* Ok, we've begun the state machine. */ sunmouse.byte = 0; } #if 0 /* If the mouse sends us a byte from 0x80 to 0x87 * we are starting at byte zero in the transaction * protocol. */ if(byte >= 0x80 && byte <= 0x87) sunmouse.byte = 0; #endif mvalue = (signed char) byte; switch(sunmouse.byte) { case 0: /* If we get a bogus button byte, just skip it. * When we get here the baud detection code has * passed, so the only other things which can * cause this are dropped serial characters and * confused mouse. We check this because otherwise * begin posting erroneous mouse events. */ if ((byte & 0xf0) != 0x80) return; /* Button state */ sunmouse.button_state = (~byte) & 0x7; #ifdef SMOUSE_DEBUG printk("B<Left %s, Middle %s, Right %s>", ((sunmouse.button_state & 0x4) ? "DOWN" : "UP"), ((sunmouse.button_state & 0x2) ? "DOWN" : "UP"), ((sunmouse.button_state & 0x1) ? "DOWN" : "UP")); #endif sunmouse.byte++; return; case 1: /* Delta-x 1 */ #ifdef SMOUSE_DEBUG printk("DX1<%d>", mvalue); #endif sunmouse.delta_x = mvalue; sunmouse.byte++; return; case 2: /* Delta-y 1 */ #ifdef SMOUSE_DEBUG printk("DY1<%d>", mvalue); #endif sunmouse.delta_y = mvalue; sunmouse.byte++; return; case 3: /* Delta-x 2 */ #ifdef SMOUSE_DEBUG printk("DX2<%d>", mvalue); #endif sunmouse.delta_x += mvalue; sunmouse.delta_x = CLIP(sunmouse.delta_x); sunmouse.byte++; return; case 4: /* Last byte, Delta-y 2 */ #ifdef SMOUSE_DEBUG printk("DY2<%d>", mvalue); #endif sunmouse.delta_y += mvalue; sunmouse.delta_y = CLIP(sunmouse.delta_y); sunmouse.byte = 0; /* Back to button state */ break; case 69: /* Until we get the (0x80 -> 0x87) value we aren't * in the middle of a real transaction, so just * return. */ return; default: printk("sunmouse: bogon transaction state\n"); sunmouse.byte = 69; /* What could cause this? */ return; }; if (!gen_events){ push_char (~sunmouse.button_state & 0x87); push_char (sunmouse.delta_x); push_char (sunmouse.delta_y); return; } d = bstate ^ pstate; pstate = bstate; if (d){ if (d & BUTTON_LEFT){ ev.id = MS_LEFT; ev.value = bstate & BUTTON_LEFT; } if (d & BUTTON_RIGHT){ ev.id = MS_RIGHT; ev.value = bstate & BUTTON_RIGHT; } if (d & BUTTON_MIDDLE){ ev.id = MS_MIDDLE; ev.value = bstate & BUTTON_MIDDLE; } ev.time = xtime; ev.value = ev.value ? VKEY_DOWN : VKEY_UP; pushed += push_event (&ev); } if (sunmouse.delta_x){ ev.id = LOC_X_DELTA; ev.time = xtime; ev.value = sunmouse.delta_x; pushed += push_event (&ev); sunmouse.delta_x = 0; } if (sunmouse.delta_y){ ev.id = LOC_Y_DELTA; ev.time = xtime; ev.value = sunmouse.delta_y; pushed += push_event (&ev); } if(pushed != 0) { /* We just completed a transaction, wake up whoever is awaiting * this event. */ sunmouse.ready = 1; if (sunmouse.fasync) kill_fasync (sunmouse.fasync, SIGIO); wake_up_interruptible(&sunmouse.proc_list); } return; }
/* * Number scanner * * state | ch | next state * ------+-----------------+-------------------------- * 0 | [0] | 1 * 0 | [1-9] | 4 * 0 | . | error (should never occur) * 1 | [xX] | 2 * 1 | [0-7] | 3 * 1 | [89a-wyzA-WYZ_] | error invalid digit * 1 | . | return 0 * 2 | [0-9a-fA-F] | 2 * 2 | [g-zG-Z_] | error invalid hex digit * 2 | . | return (hex-number) if TOS != [xX] else error * 3 | [0-7] | 3 * 3 | [89a-zA-Z_] | error invalid octal digit * 3 | . | return (octal-number) * 4 | [0-9] | 4 * 4 | [a-zA-Z_] | error invalid decimal digit * 4 | . | return (decimal-number) * * All non-identifier characters [^a-zA-Z_0-9] terminate the scan * and return the value. This is not entirely correct, but close * enough (should check punctuators as trailing context, but the * char_table is not adapted to that and it is questionable whether * it is worth the trouble). * All non-iso-8859-1 characters are an error. */ static int scan_number(int ch) { int state = 0; int base = 10; empty_char_stack(); while(1) { if(!isisochar(ch)) xyyerror("Invalid digit\n"); switch(state) { case 0: if(isdigit(ch)) { push_char(ch); if(ch == '0') state = 1; else state = 4; } else internal_error(__FILE__, __LINE__, "Non-digit in first number-scanner state\n"); break; case 1: if(ch == 'x' || ch == 'X') { push_char(ch); state = 2; } else if(ch >= '0' && ch <= '7') { push_char(ch); state = 3; } else if(isalpha(ch) || ch == '_') xyyerror("Invalid number digit\n"); else { unget_unichar(ch); mcy_lval.num = 0; return tNUMBER; } break; case 2: if(isxdigit(ch)) push_char(ch); else if(isalpha(ch) || ch == '_' || !isxdigit(tos_char_stack())) xyyerror("Invalid hex digit\n"); else { base = 16; goto finish; } break; case 3: if(ch >= '0' && ch <= '7') push_char(ch); else if(isalnum(ch) || ch == '_') xyyerror("Invalid octal digit\n"); else { base = 8; goto finish; } break; case 4: if(isdigit(ch)) push_char(ch); else if(isalnum(ch) || ch == '_') xyyerror("Invalid decimal digit\n"); else { base = 10; goto finish; } break; default: internal_error(__FILE__, __LINE__, "Invalid state in number-scanner\n"); } ch = get_unichar(); } finish: unget_unichar(ch); push_char(0); mcy_lval.num = strtoul(get_char_stack(), NULL, base); return tNUMBER; }