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

📄 expr.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 5 页
字号:
        }        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_alphanumeric()           // The start of an alphanumeric sequence has been detected. This may// be a reference, a function call, or an operator like eq or to. All// such sequences 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_alphanumeric(){    CYG_REPORT_FUNCNAME("process_alphanumeric");    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')));    CYG_REPORT_RETURN();}//}}}//{{{  process_special()                // Usually an alphanumeric sequence of characters is a reference, e.g.// CYGPKG_KERNEL. However there are only so many special characters// available so some operators are implemented as a sequence, e.g. // "to". CDL also supports functions like is_substr().//// The data will have been collected into the current_reference string// by a call to process_alphanumeric().static boolprocess_special(){    CYG_REPORT_FUNCNAMETYPE("process_special", "special %d");    bool result = false;        if ("to" == current_reference) {        current_token  = T_Range;        result = true;    } else if ("implies" == current_reference) {        current_token  = T_Implies;        result = true;    } else if ("xor" == current_reference) {        current_token  = T_Xor;        result = true;    } else if ("eqv" == current_reference) {        current_token  = T_Eqv;        result = true;    } else if (CdlFunction::is_function(current_reference.c_str(), current_function_id)) {        current_token  = T_Function;        result = true;    }    if (result) {        current_special     = current_reference;        current_reference   = "";    }    CYG_REPORT_RETVAL(result);    return result;}//}}}//}}}//{{{  next_token()                     // ----------------------------------------------------------------------------// Work out what the next token is. This includes the handling of// strings, integers, doubles, and references.static voidnext_token(){    CYG_REPORT_FUNCNAMETYPE("next_token", "token %d");    // Make sure there is no dross left lying around from the previous call.    current_token       = T_Invalid;    current_string      = "";    current_reference   = "";    current_special     = "";    current_int         = 0;    current_double      = 0.0;    current_format      = CdlValueFormat_Default;    current_function_id = 0;    // Skip leading white space. This includes newlines, tabs, etc,    // consider the case of:    //    ...    //    legal_values {    //        1    //        2    //        4    //        ..    //    }    //    ...    // which is perfectly legitimate. White space inside strings    // is handled by the string literal code, and does not get filtered    // out here.    //    // Exactly which characters are white-space is implementation-defined,    // so a special check for EOF is in order.    while ((EOF != current_char) && isspace(current_char)) {        next_char();    }    // Remember the token starting point. next_char() has actually moved    // the index on by one.    token_start = current_index - 1;    // The simple cases can be handled inline, the more complicated cases    // involve other functions    switch(current_char) {      case EOF:          current_token = T_EOD;          break;      case '"':          process_string();          break;      case '(':          current_token = T_OpenBracket;          next_char();          break;      case ')':          current_token = T_CloseBracket;          next_char();          break;          // At this level it is not possible to distinguish between          // unary and binary operators, so no attempt is made to          // turn - and + into part of a number.      case '-':          current_token = T_Minus;          next_char();          break;      case '+':          current_token = T_Plus;          next_char();          break;      case '*':          current_token = T_Times;          next_char();          break;      case '/':          current_token = T_Divide;          next_char();          break;      case '!':          next_char();          if ('=' == current_char) {              current_token = T_NotEqual;              next_char();          } else {              current_token = T_Exclamation;          }          break;      case '~':          current_token = T_Tilde;          next_char();          break;      case '?':          current_token = T_Questionmark;          next_char();          break;      case '%':          current_token = T_Remainder;          next_char();          break;      case '<':          next_char();          if ('<' == current_char) {              current_token = T_LeftShift;              next_char();          } else if ('=' == current_char) {              current_token = T_LessEqual;              next_char();          } else {              current_token = T_LessThan;          }          break;      case '>':          next_char();          if ('>' == current_char) {              current_token = T_RightShift;              next_char();          } else if ('=' == current_char) {              current_token = T_GreaterEqual;              next_char();          } else {              current_token = T_GreaterThan;          }          break;      case '=':          next_char();          if ('=' != current_char) {              throw CdlParseException(std::string("Incomplete == operator in expression.\n") + get_error_location());          } else {              current_token = T_Equal;              next_char();          }          break;      case '&':          next_char();          if ('&' == current_char) {              current_token = T_And;              next_char();          } else {              current_token = T_BitAnd;          }          break;      case '^':          current_token = T_BitXor;          next_char();          break;      case '|':          next_char();          if ('|' == current_char) {              current_token = T_Or;              next_char();          } else {              current_token = T_BitOr;          }          break;      case ':':          current_token = T_Colon;          next_char();          break;      case '.':          current_token = T_StringConcat;          next_char();          break;      case ',':          current_token = T_Comma;          next_char();          break;              default:          // String constants have been handled already. The only          // valid tokens that are left are numbers, references,          // "specials" such as the range and string equality          // operators, and functions.          //          // Numbers should begin with a digit (plus and minus are          // tokenized separately).          //          // References must be valid C preprocessor symbols, i.e.          // they must begin with either a letter or an underscore.          // The range operator is handled most conveniently as          // a special case of a reference.          if (isdigit(current_char)) {              process_number();          } else if (('_' == current_char) ||                     (('a' <= current_char) && (current_char <= 'z')) ||                     (('A' <= current_char) && (current_char <= 'Z'))) {              process_alphanumeric();              if (!process_special()) {                  current_token = T_Reference;              }          } else {              std::string msg = "Unexpected character '";              msg += (char) current_char;              msg += "' in expression.\n";              msg += get_error_location();              throw CdlParseException(msg);          }          break;    }    CYG_REPORT_RETVAL(current_token);}//}}}//{{{  initialise_tokenisation()        // ----------------------------------------------------------------------------// This is called at the start of expression parsing. It// sets up the appropriate statics, and provides initial// values for current_char and current_token.static voidinitialise_tokenisation(std::string data, int index){    CYG_REPORT_FUNCNAME("initialise_tokenization");    current_data        = data;    current_index       = static_cast<unsigned int>(index);    token_start         = current_index;    next_char();    next_token();    CYG_REPORT_RETURN();}//}}}//}}}//{{{  Syntactic analysis               // ----------------------------------------------------------------------------// Syntactic analysis.//// The BNF of CDL expressions is something like this:////   <expression>   ::= <conditional>//   <conditional>  ::= <implies> ? <conditional> : <conditional> | <implies>//   <implies>      ::= <eqv>    [<implies op>  <implies>]      implies//   <eqv>          ::= <or>     [<eqv op>      <eqv>]          xor, eqv        //   <or>           ::= <and>    [<or op>       <or>]           ||//   <and>          ::= <bitor>  [<and op>      <and>]          &&//   <bitor>        ::= <bitxor> [<bitor op>    <bitor>]        |//   <bitxor>       ::= <bitand> [<bitxor op>   <bitxor>]       ^//   <bitand>       ::= <eq>     [<bitand op>   <and>]          &//   <eq>           ::= <comp>   [<eq op>       <eq>]           == !=//   <comp>         ::= <shift>  [<comp op>     <comp>]         < <= > >=//   <shift>        ::= <add>    [<shift op>    <shift>]        << >>//   <add>          ::= <mult>   [<add op>      <add>]          + - .//   <mult>         ::= <unary>  [<mult op>     <mult>]         * / %//   <unary>        ::= -<unary> | +<unary> | !<unary> | *<unary> | ?<unary> |//                      ~<unary> |//                      <string constant> | <integer constant> |//                      <double constant> | <reference> |//                      ( <expression> ) | <function>//// There are separate functions for each of these terms.// A forward declaration, needed for bracketed subexpressions.static void parse_expression(CdlExpression);// A utility to add a reference to the current expression, returning// the index.static intpush_reference(CdlExpression expr, const std::string& reference){    CYG_REPORT_FUNCNAMETYPE("push_reference", "new index %d");

⌨️ 快捷键说明

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