static int scan_oct_byte(void) { int c1, c2, c3; int b; b = 0; c1 = scanc(); if (!isodigit(c1)) { yyerror("malformed octal digit"); return (0); } b = c1 - '0'; c2 = scanc(); if (!isodigit(c2)) { yyerror("malformed octal digit"); return (0); } b *= 8; b += (c2 - '0'); c3 = scanc(); if (!isodigit(c3)) { unscanc(c3); } else { b *= 8; b += (c3 - '0'); } return (b); }
/** * Unquote Python or octal-style quoting of a string */ string feature_recorder::unquote_string(const string &s) { size_t len = s.size(); if(len<4) return s; // too small for a quote string out; for(size_t i=0;i<len;i++){ /* Look for octal coding */ if(i+3<len && s[i]=='\\' && isodigit(s[i+1]) && isodigit(s[i+2]) && isodigit(s[i+3])){ uint8_t code = (s[i+1]-'0') * 64 + (s[i+2]-'0') * 8 + (s[i+3]-'0'); out.push_back(code); i += 3; // skip over the digits continue; } /* Look for hex coding */ if(i+3<len && s[i]=='\\' && s[i+1]=='x' && isxdigit(s[i+2]) && isxdigit(s[i+3])){ uint8_t code = (hexval(s[i+2])<<4) | hexval(s[i+3]); out.push_back(code); i += 3; // skip over the digits continue; } out.push_back(s[i]); } return out; }
/* Convert sequence \0XXXX */ static inline bool deoctify(char *p, int avail, int *eat) { uint8_t byte; char *rep = p; p += 2, (*eat)++, avail -= 2; /* Remove '\0' */ if (avail >= 1) { if (!isodigit(*p)) return false; byte = dec2bin(*p++); (*eat)++, avail--; } else { return false; } if (avail >= 1 && isodigit(*p)) { byte <<= 3; byte |= dec2bin(*p++); (*eat)++, avail--; } if (avail >= 1 && isodigit(*p)) { byte <<= 3; byte |= dec2bin(*p++); (*eat)++, avail--; } if (avail >= 1 && isodigit(*p)) { byte <<= 3; byte |= dec2bin(*p++); (*eat)++, avail--; } *rep = byte; return true; }
/* * formOctalToken() forms a number token which could be an octal number * It is called when the first character of the token is '0' * The function returns the token type */ TokenT formOctalToken(char** curPos, int* length){ // If the leading character is 0. addCurCharToToken(curPos,length); if(**curPos =='x' || **curPos == 'X'){ //To Hexadecimal branch return formHexToken(curPos,length); }else if(isodigit(**curPos)){ // Octal branch addCurCharToToken(curPos,length); while(isodigit( **curPos )){ addCurCharToToken(curPos,length); } if('8'<= **curPos && **curPos <='9'){ // Move from octal branch to decimal branch return formDecimalToken(curPos, length); }else if (**curPos == '.'){ // Move from octal branch to floating point branch return formFloatToken(curPos, length); }else{ return OCTAL; } }else if(**curPos=='.'){ return formFloatToken(curPos,length); }else{ //if it was just 0 return DEC; } }
int decode_oct(const char *str, unsigned char *ch) { int i; *ch = 0; for(i = 0; i < 4; i++) { if(!isodigit(str[i])) { break; } *ch = *ch << 3; *ch = *ch | oct_to_int(str[i]); } if(i == 0) { printf("Missing following octal characters\n"); return 0; } if(*ch == 0) { printf("Invalid octal character (not allowed NULs)\n"); return 0; } return i; }
static void test_isodigit_macro (void) { int i, j; for (i = -127; i < 256; ) j = i, printf ("%s: %d -> %d\n", __FUNCTION__, j, isodigit (i++) ? 1 : 0); }
static int oatoi(const char* s) { register int i; if (*s == 0) return -1; for (i = 0; isodigit(*s); ++s) i = i * 8 + *s - '0'; if (*s) return -1; return i; }
char read_escape(std::istream & ifs) { switch(ifs.get()) { case '\'': return '\''; case '\"': return '\"'; case '?': return '?'; case '\\': return '\\'; case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; case 'X': { // hex std::string s; while(std::isxdigit(ifs.peek())) { if(s.size() == 2) { std::cerr << "wide hex character sequences are not supported" << std::endl; throw ParseError(); } s.push_back(ifs.get()); } if(s.size() == 0) throw ParseError(); return static_cast<char>(std::stoul(s, nullptr, 16)); } case 'u': case 'U': std::cerr << "Unicode character literal not supported." << std::endl; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { // octal std::string s; while(isodigit(ifs.peek()) && s.size() != 3) s.push_back(ifs.get()); if(s.size() == 0) throw ParseError(); return static_cast<char>(std::stoul(s, nullptr, 8)); } } throw ParseError(); }
BOOL IsValidValue(const TCHAR* psz, DWORD& dwValue) { if (*psz == 0 || !_istdigit(*psz)) return FALSE; DWORD dw = 0; if (psz[0] == '0' && (psz[1] == 'x' || psz[1] == 'X')) { if (psz[1] == 0) return FALSE; psz += 2; while (_istxdigit(*psz)) { dw *= 16; dw += _istdigit(*psz) ? *psz - '0' : 10 + (*psz|0x20) - 'a'; ++psz; } } else if (psz[0] == '0') { while (isodigit(*psz)) { dw *= 8; dw += *psz - '0'; ++psz; } } else { while (_istdigit(*psz)) { dw *= 10; dw += *psz - '0'; ++psz; } } if (*psz != 0) return FALSE; dwValue = dw; return TRUE; }
/* * Quick and dirty octal conversion. * * Result is -1 if the field is invalid (all blank, or nonoctal). */ static int from_oct(int digs, char *where) { int value; while (isspace((unsigned char)*where)) { /* Skip spaces */ where++; if (--digs <= 0) return -1; /* All blank field */ } value = 0; while (digs > 0 && isodigit(*where)) { /* Scan til nonoctal */ value = (value << 3) | (*where++ - '0'); --digs; } if (digs > 0 && *where && !isspace((unsigned char)*where)) return -1; /* Ended on non-space/nul */ return value; }
/* * Print "standard" escape characters */ static char * conv_escape(char *str, int *conv_ch) { int value; int ch; ch = *str; switch (ch) { default: case 0: value = '\\'; goto out; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': ch = 3; value = 0; do { value <<= 3; value += octtobin(*str++); } while (isodigit(*str) && --ch); goto out; case '\\': value = '\\'; break; /* backslash */ case 'a': value = '\a'; break; /* alert */ case 'b': value = '\b'; break; /* backspace */ case 'f': value = '\f'; break; /* form-feed */ case 'n': value = '\n'; break; /* newline */ case 'r': value = '\r'; break; /* carriage-return */ case 't': value = '\t'; break; /* tab */ case 'v': value = '\v'; break; /* vertical-tab */ } str++; out: *conv_ch = value; return str; }
/* * Print SysV echo(1) style escape string * Halts processing string and returns 1 if a \c escape is encountered. */ static int print_escape_str(const char *str) { int value; int c; while (*str) { if (*str == '\\') { str++; /* * %b string octal constants are not like those in C. * They start with a \0, and are followed by 0, 1, 2, * or 3 octal digits. */ if (*str == '0') { str++; for (c = 3, value = 0; c-- && isodigit(*str); str++) { value <<= 3; value += octtobin(*str); } putchar (value); str--; } else if (*str == 'c') { return 1; } else { str--; str += print_escape(str); } } else { putchar (*str); } str++; } return 0; }
//static inline num_result_t parse_number(const char* c, size_t i){ num_result_t num_result; num_result.type = CH_NO_TYPE; if( c[i] == '\0'){ return num_result; } uint64_t uint_accumulator = 0; int64_t int_accumulator = 0; double float_accumulator = 0; double float_base_accumulator = 1; int64_t sign = 1; char prefix = 0; size_t state = STATE_INIT; for( ; state != STATE_NONE_FOUND && state != STATE_FINISHED_INT && state != STATE_FINISHED_UINT && state != STATE_FINISHED_FLOAT; i++ ){ switch(state){ case STATE_INIT:{ uint_accumulator = 0; float_accumulator = 0; float_base_accumulator = 1; sign = 1; if( c[i] == '-') { sign = -1; state = STATE_FOUND_SIGN; continue; } if( c[i] == '+') { state = STATE_FOUND_SIGN; continue; } if( c[i] == '.') { state = STATE_GET_FLO_DIGITS; continue; } if( c[i] == '0') { state = STATE_FOUND_INIT_ZERO; continue; } if( isdigit(c[i]) ) { uint_accumulator = (c[i] - '0'); state = STATE_GET_DEC_DIGITS; continue; } if( iswhite(c[i]) ) { state = STATE_INIT; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_FOUND_SIGN:{ if( c[i] == '0' ) { state = STATE_MUST_BE_ZERO_OR_PERIOD; continue; } if( c[i] == '.' ) { state = STATE_GET_FLO_DIGITS; continue; } if( isdigit(c[i]) ) { uint_accumulator = (c[i] - '0'); state = STATE_GET_DEC_DIGITS; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_MUST_BE_ZERO_OR_PERIOD: { if( c[i] == '0' ) { state = STATE_MUST_BE_ZERO_OR_PERIOD; continue; } if( c[i] == '.' ) { state = STATE_GET_FLO_DIGITS; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_FOUND_INIT_ZERO: { if( c[i] == 'x') { state = STATE_GET_HEX_DIGITS; continue; } if( c[i] == 'X') { state = STATE_GET_HEX_DIGITS; continue; } if( c[i] == 'b') { state = STATE_GET_BIN_DIGITS; continue; } if( c[i] == 'B') { state = STATE_GET_BIN_DIGITS; continue; } if( c[i] == '.') { state = STATE_GET_FLO_DIGITS; continue; } if( c[i] == '\0') { state = STATE_FINISHED_UINT; continue; } if( isprefix(c[i])) { prefix = c[i]; state = STATE_END_UINT; continue; } if( isodigit(c[i])) { uint_accumulator = (c[i] - '0'); state = STATE_GET_OCT_DIGITS; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_GET_DEC_DIGITS:{ if( isdigit(c[i]) ) { uint_accumulator *= 10; uint_accumulator += c[i] - '0'; state = STATE_GET_DEC_DIGITS; continue; } if( c[i] == '.') { float_accumulator = (double)uint_accumulator; state = STATE_GET_FLO_DIGITS; continue; } if( isprefix(c[i])) { prefix = c[i]; state = STATE_END_UINT; continue; } if( issci(c[i]) ) if( iswhite(c[i]) ) { state = STATE_END_UINT; continue; } if( isnull(c[i]) ) { state = STATE_FINISHED_UINT; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_GET_BIN_DIGITS: { if( isbdigit(c[i]) ) { uint_accumulator <<= 1; uint_accumulator += c[i] - '0'; state = STATE_GET_BIN_DIGITS; continue; } if( isprefix(c[i])) { prefix = c[i]; state = STATE_END_UINT; continue; } if( iswhite(c[i]) ) { state = STATE_END_UINT; continue; } if( isnull(c[i]) ) { state = STATE_FINISHED_UINT; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_GET_OCT_DIGITS: { if( isodigit(c[i]) ) { uint_accumulator *= 8; uint_accumulator += c[i] - '0'; state = STATE_GET_OCT_DIGITS; continue; } if( isprefix(c[i])) { prefix = c[i]; state = STATE_END_UINT; continue; } if( iswhite(c[i]) ) { state = STATE_END_UINT; continue; } if( isnull(c[i]) ) { state = STATE_FINISHED_UINT; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_GET_HEX_DIGITS: { if( isdigit(c[i]) ) { uint_accumulator *= 16; uint_accumulator += c[i] - '0'; state = STATE_GET_HEX_DIGITS; continue; } if( isxdigit(c[i]) ) { uint_accumulator *= 16; uint_accumulator += getxdigit(c[i]); state = STATE_GET_HEX_DIGITS; continue; } if( isprefix(c[i])) { prefix = c[i]; state = STATE_END_UINT; continue; } if( iswhite(c[i]) ) { state = STATE_END_UINT; continue; } if( isnull(c[i]) ) { state = STATE_FINISHED_UINT; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_GET_FLO_DIGITS: { if( isdigit(c[i]) ) { float_base_accumulator *= 10.0; float_accumulator += (double)(c[i] - '0') / float_base_accumulator; state = STATE_GET_FLO_DIGITS; continue; } if( isprefix(c[i])) { prefix = c[i]; state = STATE_END_FLOAT; continue; } if( iswhite(c[i]) ) { state = STATE_END_FLOAT; continue; } if( isnull(c[i]) ) { state = STATE_FINISHED_FLOAT; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_END_UINT:{ if( iswhite(c[i]) ) { state = STATE_END_UINT; continue; } if( isbin( c[i]) && isprefix(prefix)) { uint_accumulator *= get_bin_prefix(prefix); state = STATE_FINISHED_UINT; continue; } if( isprefix(prefix)) { uint_accumulator *= get_prefix(prefix); state = STATE_FINISHED_UINT; continue; } if( isnull(c[i]) ) { state = STATE_FINISHED_UINT; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_END_INT: { if( iswhite(c[i]) ) { state = STATE_END_INT; continue; } if( isprefix(prefix)) { int_accumulator *= get_prefix(prefix); state = STATE_FINISHED_INT; continue; } if( isbin(c[i]) && isprefix(prefix)) { int_accumulator *= get_bin_prefix(prefix); state = STATE_FINISHED_INT; continue; } if( isnull(c[i]) ) { state = STATE_FINISHED_INT; continue; } else { state = STATE_NONE_FOUND; continue; } } case STATE_END_FLOAT: { if( iswhite(c[i]) ) { state = STATE_END_FLOAT; continue; } if( isprefix(prefix)) { float_accumulator *= get_prefix(prefix); state = STATE_FINISHED_FLOAT; continue; } if( isbin( c[i] && isprefix(prefix))) { float_accumulator *= get_bin_prefix(prefix); state = STATE_FINISHED_FLOAT; continue; } if( isnull(c[i]) ) { state = STATE_FINISHED_FLOAT; continue; } else { state = STATE_NONE_FOUND; continue; } } default:{ ch_log_error("Undefined state parsing numeric %lu\n", state); num_result.type = CH_NO_TYPE; return num_result; } } } switch(state){ case STATE_NONE_FOUND:{ num_result.type = CH_NO_TYPE; break; } case STATE_FINISHED_INT: { num_result.type = CH_INT64; num_result.val_int = int_accumulator; break; } case STATE_FINISHED_UINT:{ if(sign == -1){ int_accumulator = uint_accumulator * sign; num_result.type = CH_INT64; num_result.val_int = int_accumulator; break; } num_result.type = CH_UINT64; num_result.val_uint = uint_accumulator; break; } case STATE_FINISHED_FLOAT:{ num_result.type = CH_DOUBLE; num_result.val_dble = float_accumulator * (double)sign; break; } default:{ ch_log_error("Undefined state parsing numeric %lu\n", state); num_result.type = CH_NO_TYPE; return num_result; } } return num_result; }
void zpcgetfloat(struct zpctoken *token, const char *str, char **retstr) { char *ptr = (char *)str; float flt = 0.0; float div; if (*ptr == '0') { ptr++; if (*ptr == 'x' || *ptr == 'X') { /* hexadecimal value */ ptr++; while (*ptr != '.' && isxdigit(*ptr)) { flt *= 16.0f; flt += tohexflt(*ptr); ptr++; } ptr++; div = 16.0f; while (isxdigit(*ptr)) { flt += tohexflt(*ptr) / div; div *= 16.0f; ptr++; } token->radix = 16; token->data.f32 = flt; } else if (*ptr == 'b' || *ptr == 'B') { /* binary value */ ptr++; while (*ptr != '.' && isbdigit(*ptr)) { flt *= 2.0f; flt += tobinflt(*ptr); ptr++; } ptr++; div = 2.0f; while (isbdigit(*ptr)) { flt += tohexflt(*ptr) / div; div *= 2.0f; ptr++; } token->radix = 2; token->data.f32 = flt; } else { /* octal value */ ptr++; while (*ptr != '.' && isodigit(*ptr)) { flt *= 8.0f; flt += tobinflt(*ptr); ptr++; } ptr++; div = 8.0f; while (isodigit(*ptr)) { flt += tohexflt(*ptr) / div; div *= 8.0f; ptr++; } token->radix = 8; token->data.f32 = flt; } } else { /* decimal value */ while (*ptr != '.' && isdigit(*ptr)) { flt *= 10.0f; flt += tobinflt(*ptr); ptr++; } ptr++; div = 10.0; while (isdigit(*ptr)) { flt += tohexflt(*ptr) / div; div *= 10.0; ptr++; } token->radix = 10; token->data.f32 = flt; } if (*ptr == 'f' || *ptr == 'F' || *ptr == ',') { ptr++; } *retstr = (char *)ptr; return; }
int Lexan::getNextToken() { int State = 0; char Char; int Exp = 0, ExpSign = 1; /* Velikost a znamenko exponentu */ double DmsPos = 0.1; /* prave zpracovavany desetinny rad */ while (true) { Char = getChar(); switch (State) { case 0: if (Char == ' ' || Char == '\n' || Char == '\t' || Char == '\r') break; if (Char == ';') return (LEX_SEMICOLON); if (Char == '/') { State = 2; break; } if (Char == '=') { State = 29; break; } if (Char == '*') { State = 25; break; } if (Char == '(') return (LEX_LPA); if (Char == ')') return (LEX_RPA); if (Char == '}') return (LEX_END); if (Char == '{') return (LEX_BEGIN); if (isalpha(Char)) { identifierName = ""; //na zacatku je string nazvu prazdny identifierName += Char; //prvni znak identifikatoru State = 38; break; } if (Char == '0') { intValue = 0; floatValue = 0.0; State = 7; break; } if (isdigit(Char)) //nula je chycana drive { intValue = Char - '0'; floatValue = Char - '0'; State = 11; break; } if (Char == '+') { State = 17; break; } if (Char == '-') { State = 20; break; } if (Char == '%') { State = 27; break; } if (Char == '!') { State = 31; break; } if (Char == '<') { State = 33; break; } if (Char == '>') { State = 35; break; } if (Char == '.') { floatValue = 0.0; DmsPos = 0.1; State = 16; break; } if (Char == EOF) return (LEX_NULL); return (LEX_ERROR); case 2: if (Char == '/') { //jednoradkovy komentar State = 4; break; } if (Char == '=') { //operator /= return (LEX_DIVASSIGN); } if (Char == '*') { State = 5; break; } ungetChar(Char); //operator / return (LEX_DIV); case 4: if (Char == '\n') { State = 0; break; } if (Char == EOF) return (LEX_ERROR); break; //pokud by byl eof uvnitr // komentare zustava ve stavu 4 case 5: if (Char == '*') { State = 6; break; } if(Char == LEX_EOF) return (LEX_ERROR); case 6: if (Char == '/') { //konec komentare State = 0; break; } if (Char != '*') { State = 5; break; } break; //state porad = 6 pri * case 7: if (isodigit(Char)) { State = 8; intValue = Char - '0'; break; } if(Char == 'x' || Char == 'X') { State = 9; break; } if(Char == '.') { State = 12; break; } if (Char == EOF) return (LEX_ERROR); if(isalpha(Char)) return (LEX_ERROR); ungetChar(Char); cout << "intValue = " << intValue << endl; return (LEX_INT); //pokud neni ani okta ani hexa case 8: if (isodigit(Char)) { intValue = (intValue << 3) + (Char - '0'); State = 8; //state bude porad 8 break; } if(isalpha(Char)) return (LEX_ERROR); ungetChar(Char); cout << "intValue = " << intValue << endl; return(LEX_INT); case 9: if(isxdigit(Char)) { Char = (char)toupper(Char); intValue = (Char >= 'A') ? Char - 'A' + 10 : Char - '0'; State = 10; break; } return(LEX_ERROR); case 10: if (isxdigit(Char)) { Char = (char)toupper(Char); intValue = (intValue << 4) + ((Char >= 'A') ? Char - 'A' + 10 : Char - '0'); break; } case 11: if(isdigit(Char)) { intValue = intValue * 10 + Char - '0'; floatValue = floatValue * 10.0 + Char - '0'; break; } if(Char == '.') { State = 12; break; } if(isalpha(Char)) return (LEX_ERROR); ungetChar(Char); // nalezen integer cout << "intValue = " << intValue << endl; return (LEX_INT); case 12: if(isdigit(Char)) { floatValue += DmsPos * (Char - '0'); DmsPos /= 10.0; // pocitat intValue break; } if(Char == 'E' || Char == 'e') { Exp = 0; ExpSign = 1; State = 13; break; } if(isalpha(Char)) return (LEX_ERROR); ungetChar(Char); //desetinne cislo s jednim destinnym mistem cout << "floatValue = " << floatValue << endl; return (LEX_FLOAT); case 13: if(isdigit(Char)) { Exp = Char - 0x30; State = 15; break; } if (Char == '+' || Char == '-') { ExpSign = (Char == '-') ? -1 : 1; State = 14; break; } return (LEX_ERROR); case 14: if(isdigit(Char)) { Exp = Char - 0x30; State = 15; break; } return (LEX_ERROR); case 15: if(isdigit(Char)) { Exp = 10 * Exp + Char - 0x30; //dalsi cifry exponentu break; } ungetChar(Char); floatValue *= pow(10.0, Exp * ExpSign); cout << "floatValue = " << floatValue << endl; return (LEX_FLOAT); case 16: if(isdigit(Char)) { floatValue = 0.1 * (Char - '0'); DmsPos = 0.01; //priste jsou zpracovavany setiny State = 12; break; } case 17: if (Char == '=' || Char == '+') // == { if(Char == '=') { State = 18; ungetChar(Char); break; } if (Char == '+') { State = 19; ungetChar(Char); break; } } else { ungetChar(Char); return (LEX_ADD); } case 18: if(Char == '=') return LEX_ADDASSIGN; else { ungetChar(Char); // jenom = return LEX_ADD; } case 19: if(Char == '+') return (LEX_INCREMENT); else { ungetChar(Char); return (LEX_ADD); } case 20: if(Char == '=' || Char == '-') { if(Char == '=') { State = 22; ungetChar(Char); break; } if(Char == '-') { State = 21; ungetChar(Char); break; } } else { ungetChar(Char); return (LEX_SUB); } case 21: if(Char == '-') return (LEX_DECREMENT); else { ungetChar(Char); return (LEX_SUB); } case 22: if(Char == '=') return (LEX_SUBASSIGN); else { ungetChar(Char); return (LEX_SUB); } case 25: if(Char == '=') return (LEX_MULASSIGN); else { ungetChar(Char); return (LEX_MUL); } case 27: if(Char == '=') return (LEX_MODASSIGN); else { ungetChar(Char); return (LEX_MOD); } case 29: if(Char == '=') return (LEX_ISEQUAL); else { ungetChar(Char); return (LEX_ASSIGN); } case 31: if(Char == '=') return (LEX_ISNEQUAL); else { ungetChar(Char); return (LEX_EXCLAMATION); } case 33: if(Char == '=') return (LEX_LESS_EQU_THAN); else { ungetChar(Char); return (LEX_LESS_THAN); } case 35: if(Char == '=') return (LEX_GREATER_EQU_THAN); else { ungetChar(Char); return (LEX_GREATER_THAN); } case 38: if(isalpha(Char) || isdigit(Char)) { identifierName += Char; break; } else { ungetChar(Char); map<int, string>::iterator i; for (i = keywords.begin(); i != keywords.end(); i++) if (identifierName.compare(i->second) == 0) { cout << "keyword: " << i->second << endl; return (i->first); } //identifikator nebyl nalezen v klicovych slovech cout << "identifier: " << identifierName << endl; return (LEX_IDENT); } default: throw "Lexical ERROR: unknown state"; break; } } }
extern int yylex(void) { static Boolean dollar = FALSE; int c; size_t i; /* The purpose of all these local assignments is to */ const char *meta; /* allow optimizing compilers like gcc to load these */ char *buf = tokenbuf; /* values into registers. On a sparc this is a */ YYSTYPE *y = &yylval; /* win, in code size *and* execution time */ if (goterror) { goterror = FALSE; return NL; } /* rc variable-names may contain only alnum, '*' and '_', so use dnw if we are scanning one. */ meta = (dollar ? dnw : nw); dollar = FALSE; if (newline) { --input->lineno; /* slight space optimization; print_prompt2() always increments lineno */ print_prompt2(); newline = FALSE; } top: while ((c = GETC()) == ' ' || c == '\t') w = NW; if (c == EOF) return ENDFILE; if (!meta[(unsigned char) c]) { /* it's a word or keyword. */ InsertFreeCaret(); w = RW; i = 0; do { buf[i++] = c; if (i >= bufsize) buf = tokenbuf = erealloc(buf, bufsize *= 2); } while ((c = GETC()) != EOF && !meta[(unsigned char) c]); UNGETC(c); buf[i] = '\0'; w = KW; if (buf[1] == '\0') { int k = *buf; if (k == '@' || k == '~') return k; } else if (*buf == 'f') { if (streq(buf + 1, "n")) return FN; if (streq(buf + 1, "or")) return FOR; } else if (*buf == 'l') { if (streq(buf + 1, "ocal")) return LOCAL; if (streq(buf + 1, "et")) return LET; } else if (streq(buf, "~~")) return EXTRACT; else if (streq(buf, "%closure")) return CLOSURE; w = RW; y->str = gcdup(buf); return WORD; } if (c == '`' || c == '!' || c == '$' || c == '\'') { InsertFreeCaret(); if (c == '!') w = KW; } switch (c) { case '!': return '!'; case '`': c = GETC(); if (c == '`') return BACKBACK; UNGETC(c); return '`'; case '$': dollar = TRUE; switch (c = GETC()) { case '#': return COUNT; case '^': return FLAT; case '&': return PRIM; default: UNGETC(c); return '$'; } case '\'': w = RW; i = 0; while ((c = GETC()) != '\'' || (c = GETC()) == '\'') { buf[i++] = c; if (c == '\n') print_prompt2(); if (c == EOF) { w = NW; scanerror("eof in quoted string"); return ERROR; } if (i >= bufsize) buf = tokenbuf = erealloc(buf, bufsize *= 2); } UNGETC(c); buf[i] = '\0'; y->str = gcdup(buf); return QWORD; case '\\': if ((c = GETC()) == '\n') { print_prompt2(); UNGETC(' '); goto top; /* Pretend it was just another space. */ } if (c == EOF) { UNGETC(EOF); goto badescape; } UNGETC(c); c = '\\'; InsertFreeCaret(); w = RW; c = GETC(); switch (c) { case 'a': *buf = '\a'; break; case 'b': *buf = '\b'; break; case 'e': *buf = '\033'; break; case 'f': *buf = '\f'; break; case 'n': *buf = '\n'; break; case 'r': *buf = '\r'; break; case 't': *buf = '\t'; break; case 'x': case 'X': { int n = 0; for (;;) { c = GETC(); if (!isxdigit(c)) break; n = (n << 4) | (c - (isdigit(c) ? '0' : ((islower(c) ? 'a' : 'A') - 0xA))); } if (n == 0) goto badescape; UNGETC(c); *buf = n; break; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { int n = 0; do { n = (n << 3) | (c - '0'); c = GETC(); } while (isodigit(c)); if (n == 0) goto badescape; UNGETC(c); *buf = n; break; } default: if (isalnum(c)) { badescape: scanerror("bad backslash escape"); return ERROR; } *buf = c; break; } buf[1] = 0; y->str = gcdup(buf); return QWORD; case '#': while ((c = GETC()) != '\n') /* skip comment until newline */ if (c == EOF) return ENDFILE; /* FALLTHROUGH */ case '\n': input->lineno++; newline = TRUE; w = NW; return NL; case '(': if (w == RW) /* not keywords, so let & friends work */ c = SUB; /* FALLTHROUGH */ case ';': case '^': case ')': case '=': case '{': case '}': w = NW; return c; case '&': w = NW; c = GETC(); if (c == '&') return ANDAND; UNGETC(c); return '&'; case '|': { int p[2]; w = NW; c = GETC(); if (c == '|') return OROR; if (!getfds(p, c, 1, 0)) return ERROR; if (p[1] == CLOSED) { scanerror("expected digit after '='"); /* can't close a pipe */ return ERROR; } y->tree = mk(nPipe, p[0], p[1]); return PIPE; } { char *cmd; int fd[2]; case '<': fd[0] = 0; if ((c = GETC()) == '>') if ((c = GETC()) == '>') { c = GETC(); cmd = "%open-append"; } else cmd = "%open-write"; else if (c == '<') if ((c = GETC()) == '<') { c = GETC(); cmd = "%here"; } else cmd = "%heredoc"; else if (c == '=') return CALL; else cmd = "%open"; goto redirection; case '>': fd[0] = 1; if ((c = GETC()) == '>') if ((c = GETC()) == '<') { c = GETC(); cmd = "%open-append"; } else cmd = "%append"; else if (c == '<') { c = GETC(); cmd = "%open-create"; } else cmd = "%create"; goto redirection; redirection: w = NW; if (!getfds(fd, c, fd[0], DEFAULT)) return ERROR; if (fd[1] != DEFAULT) { y->tree = (fd[1] == CLOSED) ? mkclose(fd[0]) : mkdup(fd[0], fd[1]); return DUP; } y->tree = mkredircmd(cmd, fd[0]); return REDIR; } default: assert(c != '\0'); w = NW; return c; /* don't know what it is, let yacc barf on it */ } }
void zpcgetdouble(struct zpctoken *token, const char *str, char **retstr) { char *ptr = (char *)str; float dbl = 0.0; float div; if (*ptr == '0') { ptr++; if (*ptr == 'x' || *ptr == 'X') { /* hexadecimal value */ ptr++; while (*ptr != '.' && isxdigit(*ptr)) { dbl *= 16.0; dbl += tohexdbl(*ptr); ptr++; } ptr++; div = 16.0; while (isxdigit(*ptr)) { dbl += tohexdbl(*ptr) / div; div *= 16.0; ptr++; } token->radix = 16; token->data.f64 = dbl; } else if (*ptr == 'b' || *ptr == 'B') { /* binary value */ ptr++; while (*ptr != '.' && isbdigit(*ptr)) { dbl *= 2.0; dbl += tobindbl(*ptr); ptr++; } ptr++; div = 2.0; while (isbdigit(*ptr)) { dbl += tohexdbl(*ptr) / div; div *= 2.0; ptr++; } token->radix = 2; token->data.f64 = dbl; } else { /* octal value */ ptr++; while (*ptr != '.' && isodigit(*ptr)) { dbl *= 8.0; dbl += tobindbl(*ptr); ptr++; } ptr++; div = 8.0; while (isodigit(*ptr)) { dbl += tohexdbl(*ptr) / div; div *= 8.0; ptr++; } token->radix = 8; token->data.f64 = dbl; } } else { /* decimal value */ while (*ptr != '.' && isdigit(*ptr)) { dbl *= 10.0; dbl += tobindbl(*ptr); ptr++; } ptr++; div = 10.0; while (isdigit(*ptr)) { dbl += tohexdbl(*ptr) / div; div *= 10.0; ptr++; } token->radix = 10; token->data.f64 = dbl; } if (*ptr == ',') { ptr++; } *retstr = (char *)ptr; return; }
/* * Print "standard" escape characters */ static int print_escape(const char *str) { const char *start = str; int value; int c; str++; switch (*str) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': for (c = 3, value = 0; c-- && isodigit(*str); str++) { value <<= 3; value += octtobin(*str); } putchar(value); return str - start - 1; /* NOTREACHED */ case 'x': str++; for (value = 0; isxdigit(*str); str++) { value <<= 4; value += hextobin(*str); } if (value > UCHAR_MAX) { warnx ("escape sequence out of range for character"); rval = 1; } putchar (value); return str - start - 1; /* NOTREACHED */ case '\\': /* backslash */ putchar('\\'); break; case '\'': /* single quote */ putchar('\''); break; case '"': /* double quote */ putchar('"'); break; case 'a': /* alert */ putchar('\a'); break; case 'b': /* backspace */ putchar('\b'); break; case 'e': /* escape */ #ifdef __GNUC__ putchar('\e'); #else putchar(033); #endif break; case 'f': /* form-feed */ putchar('\f'); break; case 'n': /* newline */ putchar('\n'); break; case 'r': /* carriage-return */ putchar('\r'); break; case 't': /* tab */ putchar('\t'); break; case 'v': /* vertical-tab */ putchar('\v'); break; default: putchar(*str); warnx("unknown escape sequence `\\%c'", *str); rval = 1; } return 1; }
// Tokenize number constants: // 1. Integers: [-] 0[0-7]+ | 0[xX][0-9a-fA-F]+ | [0-9]+ // 2. Reals : [-] [0-9]*\.[0-9]* (e|E) [+-]? [0-9]+ int Lexer:: tokenizeNumber (void) { enum { NONE, INTEGER, REAL }; int numberType = NONE; Value::NumberFactor f; long long integer=0; double real=0; int och; och = ch; mark( ); wind( ); if ( och == '-' ) { // This may be a negative number or the unary minus operator // The subsequent two characters will tell us which. if ( isdigit( ch ) ) { // It looks like a negative number, keep reading. och = ch; wind(); } else if ( ch == '.' ) { // This could be a real number or an attribute reference // starting with dot. Look at the second character. int ch2 = lexSource->ReadCharacter(); if ( ch2 >= 0 ) { lexSource->UnreadCharacter(); } if ( !isdigit( ch2 ) ) { // It's not a real number, return a minus token. cut(); tokenType = LEX_MINUS; return tokenType; } // It looks like a negative real, keep reading. } else { // It's not a number, return a minus token. cut(); tokenType = LEX_MINUS; return tokenType; } } if( och == '0' ) { // number is octal, hex or real if( tolower( ch ) == 'x' ) { // get hex digits only; parse hex-digit+ numberType = INTEGER; wind( ); if( !isxdigit( ch ) ) { cut( ); tokenType = LEX_TOKEN_ERROR; return( tokenType ) ; } while( isxdigit( ch ) ) { wind( ); } } else { // get octal or real numberType = INTEGER; while( isdigit( ch ) ) { wind( ); if( !isodigit( ch ) ) { // not an octal number numberType = REAL; } } if( ch == '.' || tolower( ch ) == 'e' ) { numberType = REAL; } else if( numberType == REAL ) { // non-octal digits, but not a real (no '.' or 'e') // so, illegal octal constant cut( ); tokenType = LEX_TOKEN_ERROR; return( tokenType ); } } } else if( isdigit( och ) ) { // decimal or real; get digits while( isdigit( ch ) ) { wind( ); } numberType = ( ch=='.' || tolower( ch )=='e' ) ? REAL : INTEGER; } if( och == '.' || ch == '.' ) { // fraction part of real or selection operator if( ch == '.' ) wind( ); if( isdigit( ch ) ) { // real; get digits after decimal point numberType = REAL; while( isdigit( ch ) ) { wind( ); } } else { if( numberType != NONE ) { // initially like a number, but no digit following the '.' cut( ); tokenType = LEX_TOKEN_ERROR; return( tokenType ); } // selection operator cut( ); tokenType = LEX_SELECTION; return( tokenType ); } } // if we are tokenizing a real, the (optional) exponent part is left // i.e., [eE][+-]?[0-9]+ if( numberType == REAL && tolower( ch ) == 'e' ) { wind( ); if( ch == '+' || ch == '-' ) wind( ); if( !isdigit( ch ) ) { cut( ); tokenType = LEX_TOKEN_ERROR; return( tokenType ); } while( isdigit( ch ) ) { wind( ); } } if( numberType == INTEGER ) { cut( ); long long l; int base = 0; if ( _useOldClassAdSemantics ) { // Old ClassAds don't support octal or hexidecimal // representations for integers. base = 10; } #ifdef WIN32 l = _strtoi64( lexBuffer.c_str(), NULL, base ); #else l = strtoll( lexBuffer.c_str(), NULL, base ); #endif integer = l; } else if( numberType == REAL ) { cut( ); real = strtod( lexBuffer.c_str(), NULL ); } else { /* If we've reached this point, we have a serious programming * error: tokenizeNumber should only be called if we are * lexing a number or a selection, and we didn't find a number * or a selection. This should really never happen, so we * bomb if it does. It should be reported as a bug. */ CLASSAD_EXCEPT("Should not reach here"); } switch( toupper( ch ) ) { case 'B': f = Value::B_FACTOR; wind( ); break; case 'K': f = Value::K_FACTOR; wind( ); break; case 'M': f = Value::M_FACTOR; wind( ); break; case 'G': f = Value::G_FACTOR; wind( ); break; case 'T': f = Value::T_FACTOR; wind( ); break; default: f = Value::NO_FACTOR; } if( numberType == INTEGER ) { yylval.SetIntValue( integer, f ); yylval.SetTokenType( LEX_INTEGER_VALUE ); tokenType = LEX_INTEGER_VALUE; } else { yylval.SetRealValue( real, f ); yylval.SetTokenType( LEX_REAL_VALUE ); tokenType = LEX_REAL_VALUE; } return( tokenType ); }