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

📄 programgraphparser.cpp

📁 机器人开源项目orocos的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************  tag: Peter Soetens  Mon May 10 19:10:37 CEST 2004  ProgramGraphParser.cxx                        ProgramGraphParser.cxx -  description                           -------------------    begin                : Mon May 10 2004    copyright            : (C) 2004 Peter Soetens    email                : peter.soetens@mech.kuleuven.ac.be *************************************************************************** *   This library is free software; you can redistribute it and/or         * *   modify it under the terms of the GNU Lesser General Public            * *   License as published by the Free Software Foundation; either          * *   version 2.1 of the License, or (at your option) any later version.    * *                                                                         * *   This library is distributed in the hope that it will be useful,       * *   but WITHOUT ANY WARRANTY; without even the implied warranty of        * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     * *   Lesser General Public License for more details.                       * *                                                                         * *   You should have received a copy of the GNU Lesser General Public      * *   License along with this library; if not, write to the Free Software   * *   Foundation, Inc., 59 Temple Place,                                    * *   Suite 330, Boston, MA  02111-1307  USA                                * *                                                                         * ***************************************************************************/#include "parser-debug.hpp"#include "parse_exception.hpp"#include "ProgramGraphParser.hpp"#include "ArgumentsParser.hpp"#include "CommandNOP.hpp"#include "CommandDataSource.hpp"#include "ConditionTrue.hpp"#include "Logger.hpp"#include "DataSourceCondition.hpp"#include "ConditionComposite.hpp"#include "CommandComposite.hpp"#include "CommandBinary.hpp"#include "TryCommand.hpp"#include "FunctionFactory.hpp"#include <iostream>#include <boost/bind.hpp>#include <boost/lambda/lambda.hpp>namespace RTT{  using namespace boost;  using namespace detail;        namespace {        assertion<std::string> expect_opencurly("Open curly brace '{' expected.");        assertion<std::string> expect_closecurly("Closing curly brace '}' expected ( or could not find out what this line means ).");        assertion<std::string> expect_open("Open brace '(' expected.");        assertion<std::string> expect_close("Closing brace ')' expected.");        assertion<std::string> expect_comma("Expected a comma separator.");        assertion<std::string> expect_ident("Expected a valid identifier.");        assertion<std::string> expect_semicolon("Semicolon ';' expected after statement.");        assertion<std::string> expect_condition("Expected a boolean expression ( a condition ).");        assertion<std::string> expect_expression("Expected an expression.");        assertion<std::string> expect_command("Expected a command after 'do'.");        assertion<std::string> expect_nl("Expected a newline after statement.");        assertion<std::string> expect_eof("Invalid input in file.");        assertion<std::string> expect_term("No valid termination claues found in do ... until { } block.");    }  ProgramGraphParser::ProgramGraphParser( iter_t& positer, TaskContext* t)      : rootc( t ),context( 0 ), fcontext(0), mpositer( positer ),        mcallfunc(),         implcond(0), mcondition(0), try_cond(0),        conditionparser( rootc ),        commandparser( rootc, true ), // as_action == true        valuechangeparser( rootc ),        expressionparser( rootc ),        argsparser(0),        peerparser(rootc),        program_builder( new FunctionGraphBuilder() ),        for_init_command(0),        for_incr_command(0),        exportf(false),        ln_offset(0)  {      // putting the code in setup() works around a GCC 4.1 bug.      this->setup();      this->setup2();  }  void ProgramGraphParser::setup() {    BOOST_SPIRIT_DEBUG_RULE( newline );    BOOST_SPIRIT_DEBUG_RULE( openbrace );    BOOST_SPIRIT_DEBUG_RULE( closebrace );    BOOST_SPIRIT_DEBUG_RULE( opencurly );    BOOST_SPIRIT_DEBUG_RULE( closecurly );    BOOST_SPIRIT_DEBUG_RULE( semicolon );    BOOST_SPIRIT_DEBUG_RULE( condition );    BOOST_SPIRIT_DEBUG_RULE( terminationclause );    BOOST_SPIRIT_DEBUG_RULE( jumpdestination );    BOOST_SPIRIT_DEBUG_RULE( terminationpart );    BOOST_SPIRIT_DEBUG_RULE( dostatement );    BOOST_SPIRIT_DEBUG_RULE( trystatement );    BOOST_SPIRIT_DEBUG_RULE( catchpart );    BOOST_SPIRIT_DEBUG_RULE( statement );    BOOST_SPIRIT_DEBUG_RULE( line );    BOOST_SPIRIT_DEBUG_RULE( content );    BOOST_SPIRIT_DEBUG_RULE( program );    BOOST_SPIRIT_DEBUG_RULE( production );    BOOST_SPIRIT_DEBUG_RULE( valuechange );    BOOST_SPIRIT_DEBUG_RULE( function );    BOOST_SPIRIT_DEBUG_RULE( functions );    BOOST_SPIRIT_DEBUG_RULE( arguments );    BOOST_SPIRIT_DEBUG_RULE( returnstatement );    BOOST_SPIRIT_DEBUG_RULE( funcstatement );    BOOST_SPIRIT_DEBUG_RULE( continuepart );    BOOST_SPIRIT_DEBUG_RULE( callpart );    BOOST_SPIRIT_DEBUG_RULE( returnpart );    BOOST_SPIRIT_DEBUG_RULE( ifstatement );    BOOST_SPIRIT_DEBUG_RULE( whilestatement );    BOOST_SPIRIT_DEBUG_RULE( forstatement );    BOOST_SPIRIT_DEBUG_RULE( breakstatement );    BOOST_SPIRIT_DEBUG_RULE( ifblock );    BOOST_SPIRIT_DEBUG_RULE( funcargs );    //newline = ch_p( '\n' );    openbrace = expect_open( ch_p('(') );    closebrace = expect_close( ch_p(')') );    opencurly = expect_opencurly( ch_p('{') );    closecurly = expect_closecurly( ch_p('}') );    semicolon = expect_semicolon( ch_p(';') );    condition = expect_condition( conditionparser.parser()[ bind(&ProgramGraphParser::seencondition, this) ] );    // program is the production rule of this grammar.  The    // production rule is the rule that the entire input should be    // matched by...  This line basically means that we're finished    // ;)    // Zero or n functions can precede the program.    production = (functions >> *program)[bind(&ProgramGraphParser::programtext,this, _1, _2)] >> expect_eof(end_p) ;    functions = *function;    // a function is very similar to a program, but it also has a name    function = (       !str_p( "export" )[bind(&ProgramGraphParser::exportdef, this)]       >> str_p( "function" )       >> expect_ident( commonparser.identifier[ bind( &ProgramGraphParser::functiondef, this, _1, _2 ) ] )       >> !funcargs       >> opencurly       >> content       >> closecurly[ bind( &ProgramGraphParser::seenfunctionend, this ) ]       );    // the function's definition args :    funcargs = ch_p('(') >> ( ch_p(')') || (        !( valuechangeparser.bareDefinitionParser()[bind(&ProgramGraphParser::seenfunctionarg, this)]             >> *(ch_p(',')>> valuechangeparser.bareDefinitionParser()[bind(&ProgramGraphParser::seenfunctionarg, this)]) )        >> closebrace ));    // a program looks like "program { content }".    program =        str_p( "program" )      >> expect_ident( commonparser.identifier[ bind( &ProgramGraphParser::programdef, this, _1, _2 ) ] )      >> opencurly      >> content      >> closecurly[ bind( &ProgramGraphParser::seenprogramend, this ) ];    // the content of a program can be any number of lines    content = *line;    // a line can be empty or contain a statement. Empty is    // necessary, because comment's are skipped, but newline's    // aren't.  So a line like "/* very interesting comment    // */\n" will reach us as simply "\n"..    //line = !( statement ) >> eol_p;    line = statement[bind(&ProgramGraphParser::noskip_eol, this )] >> commonparser.eos[bind(&ProgramGraphParser::skip_eol, this )];    statement = valuechange | dostatement | trystatement | funcstatement | returnstatement | ifstatement | whilestatement | forstatement | breakstatement;    valuechange_parsers =  valuechangeparser.constantDefinitionParser()        | valuechangeparser.variableDefinitionParser()        | valuechangeparser.aliasDefinitionParser()        | valuechangeparser.variableAssignmentParser();    valuechange = valuechange_parsers[ bind( &ProgramGraphParser::seenvaluechange, this ) ];    // a do statement: "do xxx <and y> <and...> until { terminationclauses }"    dostatement =        (str_p( "do" ) [ bind( &ProgramGraphParser::startofnewstatement, this, "do" ) ]         >> (expect_command ( commandparser.parser()[ bind( &ProgramGraphParser::seencommandcall, this ) ] )             >> *andpart)[bind( &ProgramGraphParser::seencommands, this )] >> !terminationpart          ) [ bind( &ProgramGraphParser::seendostatement, this ) ];    // a try statement: "try xxx <and y> <and...> until { terminationclauses } catch { stuff to do once on any error} "    trystatement =         (str_p("try") [ bind(&ProgramGraphParser::startofnewstatement, this, "try")]         >> (expect_command ( commandparser.parser()[ bind( &ProgramGraphParser::seencommandcall, this ) ] )             >> *andpart)[bind( &ProgramGraphParser::seencommands, this )] >> !terminationpart         ) [ bind( &ProgramGraphParser::seendostatement, this ) ]         >> !catchpart;  }      void ProgramGraphParser::initBodyParser(const std::string& name, OperationInterface* stck, int offset) {        ln_offset = offset;        assert(program_builder != 0 );        program_builder->startFunction(name);        this->setStack( stck );    }    rule_t& ProgramGraphParser::bodyParser() {        // content is the bodyparser of a program or function        return content;    }    ProgramInterfacePtr ProgramGraphParser::bodyParserResult() {        // store the variables in the program's taskcontext object.        valuechangeparser.store( context );        valuechangeparser.reset();                // Fake a 'return' statement at the last line.        program_builder->returnFunction( new ConditionTrue, mpositer.get_position().line - ln_offset );        program_builder->proceedToNext( mpositer.get_position().line - ln_offset);        return program_builder->endFunction( mpositer.get_position().line - ln_offset );    }    void ProgramGraphParser::setStack(OperationInterface* st) {        context = st;    }  void ProgramGraphParser::seencommands()  {      // Chain all implicit termination conditions into 'done' :      std::vector<ConditionInterface*>::iterator it = implcond_v.begin();      implcond = *it;      while ( ++it != implcond_v.end() ) {          implcond = new ConditionBinaryCompositeAND( implcond, *it ) ;      }      implcond_v.clear();      rootc->attributes()          ->setValue( new Alias<bool>("done",                                      new DataSourceCondition( implcond->clone() ) ) );  }  void ProgramGraphParser::seendostatement()  {      // assert(implcond);      // Called after a whole command statement is parsed.      // a CommandNode should have at least one edge      // If it doesn't, then we add a default one,      // which just moves on to the next node..      if ( program_builder->buildEdges() == 0 )          {              program_builder->proceedToNext( implcond->clone(), mpositer.get_position().line - ln_offset );          }      else          {              program_builder->proceedToNext( mpositer.get_position().line - ln_offset );          }      delete implcond;      implcond = 0;      // the done condition is no longer valid..      rootc->attributes()->removeValue( "done" );  }    void ProgramGraphParser::startofprogram()    {    }  void ProgramGraphParser::programdef( iter_t begin, iter_t end )  {      // Now that we got the name, set everything up:      std::string def(begin, end);      if ( rootc->getObject( def ) != 0 )          throw parse_exception_semantic_error("Object with name '" + def + "' already present in task '"+rootc->getName()+"'.");      FunctionGraphPtr pi(program_builder->startFunction( def ));      // ptsk becomes the owner of pi.

⌨️ 快捷键说明

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