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

📄 expr.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 5 页
字号:
CdlParse::get_expression_error_location(void){    return get_error_location();}//}}}//{{{  Token translation                // ----------------------------------------------------------------------------// Convert a token into a binary expression operatorstatic CdlExprOptoken_to_binary_expr_op(){    CYG_REPORT_FUNCNAMETYPE("token_to_expr_op", "op %d");    CdlExprOp result = CdlExprOp_Invalid;    switch(current_token) {      case T_Minus:             result = CdlExprOp_Subtract; break;      case T_Plus:              result = CdlExprOp_Add; break;      case T_Times:             result = CdlExprOp_Multiply; break;      case T_Divide:            result = CdlExprOp_Divide; break;      case T_Remainder:         result = CdlExprOp_Remainder; break;      case T_LeftShift:         result = CdlExprOp_LeftShift; break;      case T_RightShift:        result = CdlExprOp_RightShift; break;      case T_LessThan:          result = CdlExprOp_LessThan; break;      case T_LessEqual:         result = CdlExprOp_LessEqual; break;      case T_GreaterThan:       result = CdlExprOp_GreaterThan; break;      case T_GreaterEqual:      result = CdlExprOp_GreaterEqual; break;      case T_Equal:             result = CdlExprOp_Equal; break;      case T_NotEqual:          result = CdlExprOp_NotEqual; break;      case T_BitAnd:            result = CdlExprOp_BitAnd; break;      case T_BitXor:            result = CdlExprOp_BitXor; break;      case T_BitOr:             result = CdlExprOp_BitOr; break;      case T_And:               result = CdlExprOp_And; break;      case T_Or:                result = CdlExprOp_Or; break;      case T_StringConcat:      result = CdlExprOp_StringConcat; break;      case T_Implies:           result = CdlExprOp_Implies; break;      case T_Xor:               result = CdlExprOp_Xor; break;      case T_Eqv:               result = CdlExprOp_Eqv; break;      default:                  result = CdlExprOp_Invalid; break;    }        CYG_REPORT_RETVAL(result);    return result;}// Convert a token into an ExprOp. This way the internal token enum does// not need to be exported in order to define the interface.//// In practice the higher level code will only look for a handful of// cases, mainly EOD and the range operator, but we might as well// do the job property.static CdlExprOptoken_to_expr_op(){    CYG_REPORT_FUNCNAMETYPE("token_to_expr_op", "expr op %d");    CdlExprOp result;    // Many of the tokens are already handled for binary operators.    result = token_to_binary_expr_op();    if (CdlExprOp_Invalid == result) {        switch(current_token) {        case T_EOD:             result = CdlExprOp_EOD; break;        case T_Reference:       result = CdlExprOp_Reference; break;        case T_String:          result = CdlExprOp_StringConstant; break;        case T_Integer:         result = CdlExprOp_IntegerConstant; break;        case T_Double:          result = CdlExprOp_DoubleConstant; break;        case T_Range:           result = CdlExprOp_Range; break;        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_Function:        result = CdlExprOp_Function; break;        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_StringConcat:      result = "string concatenation operator ."; break;      case T_Implies:           result = "implies operator"; break;      case T_Xor:               result = "logical xor operator"; break;      case T_Eqv:               result = "logical equivalence operator eqv"; break;      case T_Function:          result = std::string("function call ") + CdlFunction::get_name(current_function_id); 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(){    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(){    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(){    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();

⌨️ 快捷键说明

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