lexical scanner of number token in lcc

    技术2022-05-19  19

    . how to recognize integer constant (1) get the value from literal string & check overflow     > integer in hex

           int d = 0;       while(*++rcp) {         if (map[*rcp] & DIGIT) {           d = *rcp - '0';         }         else if(*rcp > 'a' && *rcp < 'f') {           d = *rcp - 'a' + 10;         }         else if(*rcp > 'A' && *rcp < 'F') {           d = *rcp - 'A' + 10;         }         else // maybe 0x1234u, or 0x1ul           break;

             if( n & ~(~0UL >> 4) ) {           overflow = 1; // !!! overflow         }         else {           n = (n << 4) + d;         }       }

         > integer in oct

           int err = 0;       for(; map[*rcp++] & DIGIT; ) {         if( *rcp == '8' || *rcp == '9' ) {           err = 1;         }         if( n & ~(~0UL >> 3) ) {           overflow = 1; // !!! overflow         }         else {           n = (n << 3) + (*rcp - '0');         }       }

         > integer in decimal       for( n = *token - '0'; map[*rcp] & DIGIT; ) {          int d = *rcp - '0';

              if( n > (ULONG_MAX -d) /10 ) {  // !!! overflow, 10 * n + d > ULONG_MAX            overflow = 1;          }          else {            n = n * 10 + d;          }       }

     (2) give an appropriate integer type & value     store in a high-level integer type than that cause overflows.

         IF with suffix string{'u'|'U' . 'l'|'L'} // stored in unsigned long type        tval.type <- unsignedlong     ELSE IF with suffix 'u'|'U'  // stored in unsigned int or unsigned long        IF overflow || n > unsignedtype->u.sym->u.limits.max.i           tval.type <- unsignedlong //store in unsigned long, if unsigned is insufficient        ELSE           tval.type <- unsignedtype     ELSE IF with suffix 'l'|'L'        IF overflow || n > longtype->u.sym->u.limits.max.i           tval.type <- unsignedlong        ELSE           tval.type <- longtype     ELSE IF overflow || n > longtype->u.sym->u.limits.max.i        tval.type <- unsignedlong     ELSE IF n > inttype->u.sym->u.limits.max.i        tval.type <- longtype     ELSE IF base != 10 && n > inttype->u.sym->u.limits.max.i        tval.type <- unsignedtype     ELSE        tval.type <- inttype

         // store an appropriate value     CASE tval.type->op:       INT)         IF overflow || n > tval.type->u.sym->u.limits.max.i            warning overflows            tval.u.c.v.i <- tval.type->u.sym->u.limits.max.i         ELSE            tval.u.c.v.i <- n       UNSIGNED)         IF overflow || n > tval.type->u.sym->u.limits.max.u            warning overflows            tval.u.c.v.u <- tval.type->u.sym->u.limits.max.u         ELSE            tval.u.c.v.u <- n     ESAC

    . how to recognize floating const (1) DFA of a floating constant    f -> [+|-] f_part [exp_part]    f_part -> i_part | i_part.[i_part]    exp_part -> e|E +|- i_part     i_part -> [0-9]+   // [2]

     (2) how to get the value of floating constant & check flow    lcc calculates the value of a floating constant and check overflow by POSIX API strtod().    This can be see in function fcon().

     (3) give an appropriate floating type & value        // 0. !!! different from type assignment of integer constant    // 1. give a corresponding floating type according to suffix direction    // 2. stores in double type, if no suffix direction    tval.u.c.v.d = strtod(token, NULL)    if (errno == ERANGE) {       warning overflow...    }    if (*cp == 'f' || *cp == 'F') {       ++cp;       if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d) {         warning overflow...       }       tval.type = floattype;    }    else if (*cp == 'l' || *cp == 'L') {       ++cp;       tval.type = longdouble;    }    else {       if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d) {          warning overflow...       }       tval.type = doubletype;    }

    . lcc source codes arrangement DFA of integer constant:          |-> static Symbol icon(unsigned long n, int overflow, int base) // see note1: DFA of floating constant:          |-> static Symbol fcon(void) // see note2:

     note1:   icon() reads suffix of a integer constant, like "u", "l", or "ul" combination, and return a symbol   of integer constant. [3] note2:   fcon scans the floating constant string after decimal point (i.e, decimal point, digits after the    decimal point, and exponent part), explains suffix like "l", "L", "f", or "F", and returns a symbol    of floating constant. 

    [1]unsigned long long;  // it's interpreted 64bits even if in word length of 32 machineOn the IA32 architecture, 64-bit integer are implemented in using two 32-bit registers (eax and edx).

    however, lcc-4.1 does not support c99 yet.

    [2] 0123      // oct integer   0123.134   // floating number, and convert it to a floating number by API strtod()

    [3]see ch3.6 for integeral impression of constant symbols.


    最新回复(0)