⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expr.cxx

📁 eCos1.31版
💻 CXX
📖 第 1 页 / 共 5 页
字号:
        case T_Exclamation:     result = CdlExprOp_LogicalNot; break;        case T_Tilde:           result = CdlExprOp_BitNot; break;        case T_Questionmark:        case T_Colon:           result = CdlExprOp_Cond; break; // best guess                    case T_OpenBracket:        case T_CloseBracket:        case T_Invalid:        default:                result = CdlExprOp_Invalid; break;        }    }    CYG_REPORT_RETVAL(result);    return result;}// A utility routine to turn the current token back into a string// This is used for diagnostics.static std::stringtoken_to_string(){    CYG_REPORT_FUNCNAME("token_to_string");    std::string result = "";    switch(current_token) {      case T_EOD:               result = "<end of data>"; break;      case T_Reference:         result = "reference to " + current_reference; break;      case T_String:            result = "string \"" + current_string + "\""; break;      case T_Integer:      {          std::string tmp;          Cdl::integer_to_string(current_int, tmp, current_format);          result = "integer constant " + tmp;          break;      }      case T_Double:      {          std::string tmp;          Cdl::double_to_string(current_double, tmp, current_format);          result = "double constant " + tmp;          break;      }      case T_Range:             result = "range operator \"to\""; break;      case T_OpenBracket:       result = "open bracket ("; break;      case T_CloseBracket:      result = "close bracket )"; break;      case T_Minus:             result = "minus sign -"; break;      case T_Plus:              result = "plus sign +"; break;      case T_Times:             result = "multiply operator *"; break;      case T_Divide:            result = "divide operator /"; break;      case T_Exclamation:       result = "not operator !"; break;      case T_Tilde:             result = "bitwise not operator ~"; break;      case T_Questionmark:      result = "question mark ?"; break;      case T_Remainder:         result = "remainder operator %"; break;      case T_LeftShift:         result = "left shift operator <<"; break;      case T_RightShift:        result = "right shift operator >>"; break;      case T_LessThan:          result = "less-than operator <"; break;      case T_LessEqual:         result = "less-or-equal operator <="; break;      case T_GreaterThan:       result = "greater-than operator >"; break;      case T_GreaterEqual:      result = "greater-or-equal operator >="; break;      case T_Equal:             result = "equality operator =="; break;      case T_NotEqual:          result = "not-equal operator !="; break;      case T_BitAnd:            result = "bitwise and operator &"; break;      case T_BitXor:            result = "bitwise xor operator ^"; break;      case T_BitOr:             result = "bitwise or operator |"; break;      case T_And:               result = "and operator &&"; break;      case T_Or:                result = "or operator ||"; break;      case T_Colon:             result = "colon"; break;      case T_Invalid:      default:                  result = "<invalid token>"; break;    }    CYG_REPORT_RETURN();    return result;}//}}}//{{{  Literals                         // ----------------------------------------------------------------------------//{{{  process_string()                 // The start of a string has been detected. Work out the entire string,// allowing for backslash escapes.static voidprocess_string()    throw(CdlParseException, std::bad_alloc){    CYG_REPORT_FUNCNAME("process_string");    CYG_ASSERTC('"' == current_char);    CYG_ASSERTC("" == current_string);    std::string result = "";    // Move past the leading quote mark.    next_char();    while ('"' != current_char) {        if (EOF == current_char) {            throw CdlParseException("Premature end of data in string constant.\n" + get_error_location());        } else if ('\\' == current_char) {            // Allow \a, \b, \f, \n, \r, \t, \v, \ddd and \xhh.            // Also copy with \newline space.            // Any other character gets passed through unchanged.            next_char();            switch(current_char) {              case EOF:                throw CdlParseException("Premature end of data after backslash in string constant.\n" + get_error_location());              case 'a':                result += '\a';                break;              case 'b':                result += '\b';                break;              case 'f':                result += '\f';                break;              case 'n':                result += '\n';                break;              case 'r':                result += '\r';                break;              case 't':                result += '\t';                break;              case 'v':                result += '\v';                break;              case 'x':              {                cdl_int tmp = 0;                next_char();                if (!isxdigit(current_char)) {                    throw CdlParseException("Non-hexadecimal digit detected in string \\x escape sequence.\n" +                        get_error_location());                }                // NOTE: there is no overflow detection here.                do {                    tmp *= 16;                    if (('0' <= current_char) && (current_char <= '9')) {                        tmp += (current_char - '0');                    } else if (('a' <= current_char) && (current_char <= 'f')) {                        tmp += 10 + (current_char - 'a');                    } else if (('A' <= current_char) && (current_char <= 'F')) {                        tmp += 10 + (current_char - 'A');                    } else {                        CYG_FAIL("C library error, isxdigit() succeeded on non-hexadecimal character");                    }                    next_char();                } while(isxdigit(current_char));                backup_char();                result += (char) tmp;              }              case '\n':                next_char();                while ((EOF != current_char) && isspace(current_char)) {                    next_char();                }                // We have gone one too far, back up.                backup_char();                result += " ";                break;              default:                if (('0' <= current_char) && (current_char <= '7')) {                    // A sequence of octal digits.                    cdl_int tmp = 0;                    do {                        tmp = (8 * tmp) + (current_char - '0');                        next_char();                    } while (('0' <= current_char) && (current_char <= '7'));                    backup_char();                    result += (char) tmp;                } else {                    // For all other backslash sequences, just add the second character                    result += (char) current_char;                }            }        } else {            result += (char) current_char;        }        next_char();    }    // The closing quote has been reached, move past it.    next_char();    // And all done.    current_token  = T_String;    current_string = result;    CYG_REPORT_RETURN();}//}}}//{{{  process_number()                 // The start of a number has been detected. This number may be an// integer or a double. It is necessary to figure out where the number// ends and invoke the appropriate Cdl:: conversion utility.//// Care has to be taken with termination. Consider a token such as// 134_5. This is not a string because there are no quote marks, nor// is it a valid reference, and because it begins with a digit it// should be interpreted as a number. The 134 bit works fine, then// number processing stops leaving current_char as '_'. If we are// parsing a list expression then the following _5 will actually// be interpreted as a reference. To avoid this, here is a utility// which checks number completion and throws an exception if// necessary.static void check_number_termination()    throw(CdlParseException, std::bad_alloc){    CYG_REPORT_FUNCNAME("check_number_termination");    // End-of-data or any whitespace is ok.    if ((EOF != current_char) && !isspace(current_char)) {        // Any valid operator is ok as well, or brackets for that matter.        if (('-' != current_char) && ('+' != current_char) && ('*' != current_char) &&            ('/' != current_char) && ('!' != current_char) && ('~' != current_char) &&            ('?' != current_char) && ('%' != current_char) && ('<' != current_char) &&            ('>' != current_char) && ('=' != current_char) && ('&' != current_char) &&            ('^' != current_char) && ('|' != current_char) && (':' != current_char) &&            ('(' != current_char) && (')' != current_char)) {            std::string tmp;            Cdl::integer_to_string(current_int, tmp);            throw CdlParseException("Invalid character detected after number " + tmp + "\n" + get_error_location());        }    }        CYG_REPORT_RETURN();}static voidprocess_number()    throw(CdlParseException, std::bad_alloc){    CYG_REPORT_FUNCNAME("process_number");    std::string tmp      = "";    bool        is_float = false;    // Detect the special cases of 0x and octal numbers.    if ('0' == current_char) {        next_char();        if (('x' == current_char) || ('X' == current_char)) {                        next_char();            if (!isxdigit(current_char)) {                throw CdlParseException("Invalid hexadecimal number, expected at least one hexadecimal digit after 0x.\n"                                        + get_error_location());            }            current_int = 0;            do {                current_int *= 16;                if (('0' <= current_char) && (current_char <= '9')) {                    current_int += (current_char - '0');                } else if (('a' <= current_char) && (current_char <= 'f')) {                    current_int += 10 + (current_char - 'a');                } else {                    current_int += 10 + (current_char - 'A');                }                next_char();            } while(isxdigit(current_char));            current_token  = T_Integer;            current_format = CdlValueFormat_Hex;            check_number_termination();            CYG_REPORT_RETURN();            return;                        } else if (('0' <= current_char) && (current_char <= '7')) {            current_int = 0;            do {                current_int *= 8;                current_int += (current_char - '0');                next_char();            } while (('0' <= current_char) && (current_char <= '7'));            current_token  = T_Integer;            current_format = CdlValueFormat_Octal;            check_number_termination();            CYG_REPORT_RETURN();            return;                    } else if (('8' == current_char) || ('9' == current_char)) {            throw CdlParseException("08... and 09... are not valid  octal numbers.\n" + get_error_location());        } else {            // This could be plain 0, or 0.123            // Backup, and let the rest of the code take care of things            backup_char();        }    }        do {        tmp += (char) current_char;        next_char();    } while(isdigit(current_char));    // If we have found a . then we have a floating point number with a fraction.    if ('.' == current_char) {        tmp += '.';        next_char();        if (!isdigit(current_char)) {            throw CdlParseException("Invalid floating point constant, expected a digit for the fractional part.\n" +                                    get_error_location());        }        is_float = true;        do {            tmp += (char) current_char;            next_char();        } while(isdigit(current_char));    }    // If we have found e or E then we have a floating point number with an exponent    if (('e' == current_char) || ('E' == current_char)) {        tmp += 'E';        next_char();        if (('+' == current_char) || ('-' == current_char)) {            tmp += current_char;            next_char();        }        if (!isdigit(current_char)) {            throw CdlParseException("Invalid floating point constant, expected a digit for the exponent.\n" +                                    get_error_location());        }        is_float = true;        do {            tmp += (char) current_char;            next_char();        } while(isdigit(current_char));    }    if (is_float) {        if (!Cdl::string_to_double(tmp, current_double)) {            throw CdlParseException("Invalid floating point constant `" + tmp + "'.\n" + get_error_location());        } else {            current_token = T_Double;        }    } else {        if (!Cdl::string_to_integer(tmp, current_int)) {            throw CdlParseException("Invalid integer constant `" + tmp + "'.\n" + get_error_location());        } else {            current_token = T_Integer;        }    }        check_number_termination();    CYG_REPORT_RETURN();}//}}}//{{{  process_reference()              // The start of a reference has been detected.// A reference name must be a valid C preprocessor name, so the// only characters allowed are underscore, upper and lower case// characters, and digits. The first character cannot be a digit,// but that has been checked already.//// Some care has to be taken with locale's, the C library may decide// that a character is a letter even though the same character is not// valid as far as the preprocessor is concerned.static voidprocess_reference()    throw(CdlParseException, std::bad_alloc){    CYG_REPORT_FUNCNAME("process_reference");    do {       current_reference += (char) current_char;       next_char();    } while (('_' == current_char) || isdigit(current_char) ||             (('a' <= current_char) && (current_char <= 'z')) ||             (('A' <= current_char) && (current_char <= 'Z')));    current_token = T_Reference;    CYG_REPORT_RETURN();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -