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

📄 expr.cxx

📁 移植到WLIT项目的redboot源代码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//}}}//{{{  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_int         = 0;    current_double      = 0.0;    current_format      = CdlValueFormat_Default;    // 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;      default:          // String constants have been handled already. The only          // valid tokens that are left are numbers, references and          // the rang eoperator.          //          // 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_reference();              if ("to" == current_reference) {                  current_reference = "";                  current_token  = T_Range;              } else {                  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>  ::= <or> ? <conditional> : <conditional> | <or>//   <or>           ::= <and>    [<or op>     <and>]           ||//   <and>          ::= <bitor>  [<and op>    <bitor>]         ??//   <bitor>        ::= <bitxor> [<bitor op>  <bitxor>]        |//   <bitxor>       ::= <bitand> [<bitxor op> <bitand>]        ^//   <bitand>       ::= <eq>     [<bitand op> <eq>]            &//   <eq>           ::= <comp>   [<eq op>     <comp>]          == !=//   <comp>         ::= <shift>  [<comp op>   <shift>]         < <= > >=//   <shift>        ::= <add>    [<shift op>  <add>]           << >>//   <add>          ::= <mult>   [<add op>    <mult>]          + -//   <mult>         ::= <unary>  [<mult op>   <unary>]         * / %//   <unary>        ::= -<unary> | +<unary> | !<unary> | *<unary> | ?<unary> |//                      ~<unary> |//                      <string constant> | <integer constant> |//                      <double constant> | <reference> |//                      ( <expression> )//// 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");    CYG_PRECONDITION_CLASSC(expr);    CdlReference ref(reference);    expr->references.push_back(ref);    int result = (int) expr->references.size() - 1;    CYG_REPORT_RETVAL(result);    return result;}// A utility to add a subexpression, returning its index.static voidpush_subexpression(CdlExpression expr, const CdlSubexpression& subexpr){    CYG_REPORT_FUNCNAME("push_subexpression");    CYG_PRECONDITION_CLASSC(expr);    expr->sub_expressions.push_back(subexpr);    expr->first_subexpression = ((int) expr->sub_expressions.size()) - 1;    CYG_REPORT_RETURN();}// Another utility to hold of the most recent subexpressionstatic CdlSubexpression&current_subexpression(CdlExpression expr){    CYG_REPORT_FUNCNAME("current_subexpression");    CdlSubexpression& result = expr->sub_expressions[expr->first_subexpression];    CYG_REPORT_RETURN();    return result;}static voidparse_unary(CdlExpression expr){    CYG_REPORT_FUNCNAME("parse_operand");    CYG_REPORT_FUNCARG1XV(expr);    CYG_PRECONDITION_CLASSC(expr);    CdlSubexpression subexpr;    switch(current_token) {      case T_EOD :      {        // This warrants a special case        throw CdlParseException("End of expression reached when expecting an operand.\n" + get_error_location());      }            case T_Reference :      {        subexpr.op              = CdlExprOp_Reference;        subexpr.reference_index = push_reference(expr, current_reference);        push_subexpression(expr, subexpr);        next_token();        break;      }            case T_String :      {        subexpr.op              = CdlExprOp_StringConstant;        subexpr.constants       = current_string;        push_subexpression(expr, subexpr);        next_token();        break;      }            case T_Integer :      {        subexpr.op               = CdlExprOp_IntegerConstant;        subexpr.constants.set_integer_value(current_int, current_format);        push_subexpression(expr, subexpr);        next_token();        break;      }            case T_Double :      {        subexpr.op              = CdlExprOp_DoubleConstant;        subexpr.constants.set_double_value(current_double, current_format);        push_subexpression(expr, subexpr);        next_token();        break;      }            case T_OpenBracket :      {        next_token();        parse_expression(expr);        if (T_CloseBracket != current_token) {            throw CdlParseException("Missing close bracket after subexpression.\n" + get_error_location());        }        next_token();        break;      }            case T_Minus :      {        next_token();

⌨️ 快捷键说明

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