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

📄 expressionparser.cpp

📁 机器人开源项目orocos的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    comma = expect_comma( ch_p(',') );    close_brace = expect_close( ch_p(')') );    expression = ifthenelseexp;    // We parse expressions without regard of the types.  First we    // parse the expressions, then we worry about whether what the    // user says is actually valid.  You can try to add up two    // booleans, and the parser will parse it, but it will notice    // you're writing bogus when it tries to pass it to an operator    // structure from Operators.hpp    // TODO: implement the ifthenelse operator ?    ifthenelseexp = andexp;    andexp =      orexp >> *( ( str_p( "&&" ) | "and" ) >> orexp[                    bind( &ExpressionParser::seen_binary, this, "&&" ) ] );    orexp =      notequalexp >> *( ( str_p( "||" ) | "or" ) >> notequalexp[                        bind( &ExpressionParser::seen_binary, this, "||" ) ] );    notequalexp =      equalexp >> *( "!=" >> equalexp[                       bind( &ExpressionParser::seen_binary, this, "!=" ) ] );    equalexp =         greatereqexp      >> *( "==" >> greatereqexp[              bind( &ExpressionParser::seen_binary, this, "==" ) ] );    greatereqexp =         greaterexp      >> *( ">=" >> greaterexp[              bind( &ExpressionParser::seen_binary, this, ">=" ) ] );    greaterexp =         smallereqexp      >> *( '>' >> smallereqexp[              bind( &ExpressionParser::seen_binary, this, ">" ) ] );    smallereqexp =         smallerexp      >> *( "<=" >> smallerexp[              bind( &ExpressionParser::seen_binary, this, "<=" ) ] );    smallerexp =      minusexp >> *( '<' >> minusexp[                       bind( &ExpressionParser::seen_binary, this, "<" ) ] );    minusexp =      plusexp >> *( '-' >> plusexp[                      bind( &ExpressionParser::seen_binary, this, "-" ) ] );    plusexp =      modexp >> *( '+' >> modexp[                     bind( &ExpressionParser::seen_binary, this, "+" ) ] );    modexp =      divexp >> *( '%' >> divexp[                     bind( &ExpressionParser::seen_binary, this, "%" ) ] );    divexp =      multexp >> *( '/' >> multexp[                      bind( &ExpressionParser::seen_binary, this, "/" ) ] );    multexp =         unaryplusexp      >> *( '*' >> unaryplusexp[              bind( &ExpressionParser::seen_binary, this, "*" ) ] );    unaryplusexp =        '+' >> unaryminusexp[          bind( &ExpressionParser::seen_unary, this, "+" ) ]      | unaryminusexp;    unaryminusexp =        '-' >> unarynotexp[          bind( &ExpressionParser::seen_unary, this, "-" ) ]      | unarynotexp;    unarynotexp =        ( str_p( "not" ) | '!' ) >> atomicexpression[            bind( &ExpressionParser::seen_unary, this, "!" ) ]        | atomicexpression;    // note the order is important: commonparser.identifier throws a    // useful "cannot use x as identifier" error if it fails, so we    // must first show all non-identifier rules.    atomicexpression = (        // A parenthesis group.      groupexp        // or a time expression      | time_expression        // or a constant or user-defined value..      | my_guard( valueparser.parser())[ &handle_no_value ]               [ bind( &ExpressionParser::seenvalue, this ) ]      | my_guard( datacallparser.parser() )[&handle_no_datacall]                            [bind( &ExpressionParser::seendatacall, this ) ]        // or an index or dot expression        ) >> ! dotexp >> !indexexp;    // take index of an atomicexpression    indexexp =        (ch_p('[') >> expression[bind(&ExpressionParser::seen_binary, this, "[]")] >> expect_close( ch_p( ']') ) );    dotexp =         +( ch_p('.') >> commonparser.identifier[ bind(&ExpressionParser::seen_dotmember, this, _1, _2)]);    // needs no semantic action, its result is already on top of    // the stack, where it should be..    groupexp = '(' >> expression >> close_brace;    // the day i find a clean way to temporarily disable 'eol' skipping, a lot of    // grammar will look better...    time_expression =        (str_p("time")>>eps_p(~commonparser.identchar | eol_p | end_p ))[bind(&ExpressionParser::seentimeexpr, this)]        |        ( (eps_p[boost::lambda::var(eol_skip_functor::skipeol) = false] >> uint_p[ bind( &ExpressionParser::seentimespec, this, _1 ) ]           >> (str_p( "s" ) | "ms" | "us" | "ns" )[boost::lambda::var(eol_skip_functor::skipeol) = true][bind( &ExpressionParser::seentimeunit, this, _1, _2 ) ])          | (eps_p[boost::lambda::var(eol_skip_functor::skipeol) = true] >> nothing_p) // eps_p succeeds always, then fail.          )          ; // enable skipeol.//         >> expect_timespec( (( str_p( ">=" ) | ">" )//                             |//                             (str_p("<=") | "<")[bind( &ExpressionParser::inverttime, this)])//         >> time_spec);//     time_spec =//         ( uint_p[ bind( &ExpressionParser::seentimespec, this, _1 ) ]//         >>//       ( str_p( "s" ) | "ms" | "us" | "ns" )[//         bind( &ExpressionParser::seentimeunit, this, _1, _2 ) ] ) | expression[bind(&ExpressionParser::seentimeexpr, this)];  };    void ExpressionParser::inverttime()    {        _invert_time = true;    }    void ExpressionParser::seentimeexpr()    {        parsestack.push( new DataSourceTime() );//         DataSourceBase::shared_ptr res = parsestack.top();//         parsestack.pop();//         DataSource<double>::shared_ptr dres = dynamic_cast<DataSource<double>*>( res.get() );//         if ( !dres )//             throw parse_exception_semantic_error("Expected time in seconds but expression is not a floating point number.");//         DataSourceBase::shared_ptr dsb( new DataSourceCondition( new ConditionDSDuration( dres, _invert_time ) ) );//         _invert_time = false;//         parsestack.push( dsb );    }  void ExpressionParser::seentimeunit( iter_t begin, iter_t end)  {    // the string starting at begin, ending at end is either ms, us,    // ns or s, so we only need to check the first letter...      // Convert to seconds...      TimeService::Seconds total = 0;    switch( *begin )    {    case 's': total = tsecs;        break;    case 'm': total = tsecs / 1000.0;        break;    case 'u': total = tsecs / 1000000.0;        break;    case 'n': total = tsecs / 1000000000.0;        break;    default:         std::string arg(begin, end);        throw parse_exception_semantic_error("Expected time expression 's', 'ms', 'us' or 'ns' after integer value, got "+arg);    };    parsestack.push( new ConstantDataSource<double>( total ) ); //     DataSourceBase::shared_ptr dsb( new DataSourceCondition(//       new ConditionDuration( total, _invert_time ) ) );//     _invert_time = false;//     parsestack.push( dsb );  }  void ExpressionParser::seentimespec( int n )  {    tsecs = n;  }  void ExpressionParser::seenvalue()  {    DataSourceBase::shared_ptr ds = valueparser.lastParsed();    parsestack.push( ds );  }  void ExpressionParser::seendatacall()  {      DataSourceBase::shared_ptr n( datacallparser.getParseResult() );      parsestack.push( n );  }  ExpressionParser::~ExpressionParser()  {      // if parsestack is not empty, then something went wrong, someone      // threw an exception, so we clean up..      while ( !parsestack.empty() )          parsestack.pop();  }  rule_t& ExpressionParser::parser()  {    return expression;  }  DataSourceBase::shared_ptr ExpressionParser::getResult()  {    assert( !parsestack.empty() );    return parsestack.top();  }  void ExpressionParser::seen_unary( const std::string& op )  {    DataSourceBase::shared_ptr arg( parsestack.top() );    parsestack.pop();    DataSourceBase::shared_ptr ret =        opreg->applyUnary( op, arg.get() );    if ( ! ret )        throw parse_exception_fatal_semantic_error( "Cannot apply unary operator \"" + op +                                                    "\" to " + arg->getType() +"." );    parsestack.push( ret );  };  void ExpressionParser::seen_dotmember( iter_t s, iter_t f )  {      std::string member(s,f);      // inspirired on seen_unary    DataSourceBase::shared_ptr arg( parsestack.top() );    parsestack.pop();    DataSourceBase::shared_ptr ret =      opreg->applyDot( member, arg.get() );    if ( ! ret )      throw parse_exception_fatal_semantic_error( arg->getType() + " does not have member \"" + member +                                            "\"." );    parsestack.push( ret );  };  void ExpressionParser::seen_binary( const std::string& op )  {    DataSourceBase::shared_ptr arg1( parsestack.top() );    parsestack.pop();    DataSourceBase::shared_ptr arg2( parsestack.top() );    parsestack.pop();    // Arg2 is the first (!) argument, as it was pushed on the stack    // first.    DataSourceBase::shared_ptr ret =      opreg->applyBinary( op, arg2.get(), arg1.get() );    if ( ! ret )      throw parse_exception_fatal_semantic_error( "Cannot apply binary operation "+ arg2->getType() +" " + op +                                            " "+arg1->getType() +"." );    parsestack.push( ret );  };  void ExpressionParser::dropResult()  {    parsestack.pop();  }}

⌨️ 快捷键说明

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