Parser.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: Peter Soetens  Mon May 10 19:10:37 CEST 2004  Parser.cxx
00003 
00004                         Parser.cxx -  description
00005                            -------------------
00006     begin                : Mon May 10 2004
00007     copyright            : (C) 2004 Peter Soetens
00008     email                : peter.soetens@mech.kuleuven.ac.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place,                                    *
00024  *   Suite 330, Boston, MA  02111-1307  USA                                *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 #include "parser-debug.hpp"
00029 #include "parser-types.hpp"
00030 #include "parse_exception.hpp"
00031 #include "Parser.hpp"
00032 #include "ProgramGraphParser.hpp"
00033 #include "StateGraphParser.hpp"
00034 #include "ConditionParser.hpp"
00035 #include "ExpressionParser.hpp"
00036 #include "ValueChangeParser.hpp"
00037 #include "ProgramService.hpp"
00038 #include "StateMachineService.hpp"
00039 #include "../internal/DataSourceCommand.hpp"
00040 #include "ConditionInterface.hpp"
00041 #include "CommandComposite.hpp"
00042 #include "../internal/GlobalEngine.hpp"
00043 #include "ScriptParser.hpp"
00044 
00045 #include <iostream>
00046 #include <fstream>
00047 
00048 using namespace boost;
00049 
00050 namespace RTT
00051 {
00052   using namespace detail;
00053 
00054   Parser::Parser(ExecutionEngine* caller) : mcaller(caller) {
00055 
00056       if (mcaller == 0) {
00057           log(Debug) << "WARNING: Parser does not know which TaskContext is executing (calling) the parsed code. Using Global Engine. Please specify the caller explicitly in order to avoid any asynchronous operation problems." <<endlog();
00058           mcaller = GlobalEngine::Instance();
00059       }
00060   }
00061 
00062   void Parser::runScript(std::string const& code, TaskContext* mowner, ScriptingService* service, std::string const& filename ) {
00063       our_buffer_t script(code + "\n"); // work around mandatory trailing newline/eos for statements.
00064       our_pos_iter_t parsebegin( script.begin(), script.end(), filename );
00065       our_pos_iter_t parseend( script.end(), script.end(), filename );
00066 
00067       // will store all in mowner, functions are loaded in service, caller is the one calling us.
00068       ScriptParser gram( parsebegin, mowner, mcaller );
00069 
00070       try {
00071           gram.parse( parsebegin, parseend );
00072       }
00073       catch( const parse_exception& exc )
00074       {
00075         throw file_parse_exception(
00076           exc.copy(), parsebegin.get_position().file,
00077           parsebegin.get_position().line, parsebegin.get_position().column );
00078       }
00079   }
00080 
00081   Parser::ParsedFunctions Parser::parseFunction( const std::string& text, TaskContext* c, const std::string& filename)
00082   {
00083     our_buffer_t function(text);
00084     our_pos_iter_t parsebegin( function.begin(), function.end(), filename );
00085     our_pos_iter_t parseend( function.end(), function.end(), filename );
00086     // The internal parser.
00087     CommonParser cp;
00088     ProgramGraphParser gram( parsebegin, c, c->engine(), cp );
00089     ParsedFunctions ret = gram.parseFunction( parsebegin, parseend );
00090     return ret;
00091   }
00092 
00093   Parser::ParsedPrograms Parser::parseProgram( const std::string& text, TaskContext* c, const std::string& filename)
00094   {
00095     our_buffer_t program(text);
00096     our_pos_iter_t parsebegin( program.begin(), program.end(), filename );
00097     our_pos_iter_t parseend( program.end(),program.end(),filename );
00098 
00099     // The internal parser.
00100     CommonParser cp;
00101     ProgramGraphParser gram( parsebegin, c, c->engine(), cp );
00102     ParsedPrograms ret = gram.parse( parsebegin, parseend );
00103 
00104     return ret;
00105   }
00106 
00107   Parser::ParsedStateMachines Parser::parseStateMachine( const std::string& text, TaskContext* c, const std::string& filename)
00108   {
00109       // This code is copied from parseProgram()
00110 
00111     our_buffer_t program(text);
00112     our_pos_iter_t parsebegin( program.begin(), program.end(), filename );
00113     our_pos_iter_t parseend( program.end(),program.end(),filename );
00114 
00115     // The internal parser.
00116     CommonParser cp;
00117     StateGraphParser gram( parsebegin, c, c->engine(), &cp );
00118     Parser::ParsedStateMachines ret;
00119     try {
00120       ret = gram.parse( parsebegin, parseend );
00121     }
00122     catch( const parse_exception& exc )
00123     {
00124       throw file_parse_exception(
00125         exc.copy(), parsebegin.get_position().file,
00126         parsebegin.get_position().line, parsebegin.get_position().column );
00127     }
00128     return ret;
00129   }
00130 
00131   ConditionInterface* Parser::parseCondition( const std::string& s,
00132                                               TaskContext* tc )
00133   {
00134     our_buffer_t scopy(s);
00135     our_pos_iter_t parsebegin( scopy.begin(), scopy.end(), "teststring" );
00136     our_pos_iter_t parseend( scopy.end(), scopy.end(), "teststring" );
00137 
00138         CommonParser cp;
00139     ConditionParser parser( tc, mcaller ? mcaller : tc->engine(), cp );
00140     bool skipref=true;
00141     try
00142     {
00143       parse( parsebegin, parseend, parser.parser(), SKIP_PARSER );
00144     }
00145     catch( const parse_exception& )
00146     {
00147       throw;
00148     }
00149     catch( const parser_error<std::string, iter_t>& e )
00150         {
00151             throw parse_exception_syntactic_error( e.descriptor );
00152         }
00153     ConditionInterface* ret = parser.getParseResult();
00154     parser.reset();
00155     if ( ret == 0 )
00156         throw parse_exception_parser_fail("Parser did not find a condition in text.");
00157     return ret;
00158   }
00159 
00160   DataSourceBase::shared_ptr Parser::parseExpression( const std::string& _s,
00161                                            TaskContext* tc )
00162   {
00163     std::string s( _s );
00164 
00165     our_pos_iter_t parsebegin( s.begin(), s.end(), "teststring" );
00166     our_pos_iter_t parseend( s.end(), s.end(), "teststring" );
00167 
00168     CommonParser cp;
00169     ExpressionParser parser( tc, mcaller, cp );
00170     bool skipref=true;
00171     try
00172     {
00173         parse( parsebegin, parseend, parser.parser(), SKIP_PARSER );
00174     }
00175     catch( const parse_exception& )
00176     {
00177         throw;
00178     }
00179     catch( const parser_error<std::string, iter_t>& e )
00180         {
00181             throw parse_exception_syntactic_error( e.descriptor );
00182         }
00183     if ( parser.hasResult() ) {
00184         DataSourceBase::shared_ptr ret = parser.getResult();
00185         parser.dropResult();
00186         return ret;
00187     }
00188     throw parse_exception_parser_fail("Parser did not find a valid expression in text.");
00189   }
00190 
00191   DataSourceBase::shared_ptr Parser::parseValueChange( const std::string& _s,
00192                                                        TaskContext* tc )
00193   {
00194       return parseExpression( _s, tc );
00195   }
00196 
00197   DataSourceBase::shared_ptr Parser::parseValueStatement( const std::string& _s,
00198                                                        TaskContext* tc )
00199   {
00200     std::string s( _s );
00201 
00202     our_pos_iter_t parsebegin( s.begin(), s.end(), "teststring" );
00203     our_pos_iter_t parseend( s.end(), s.end(), "teststring" );
00204 
00205     CommonParser cp;
00206     ValueChangeParser parser( tc, cp, tc->provides(), mcaller ? mcaller : tc->engine() );
00207     bool skipref=true;
00208     try
00209     {
00210         parse( parsebegin, parseend, parser.parser(), SKIP_PARSER );
00211     }
00212     catch( const parse_exception& )
00213     {
00214         throw;
00215     }
00216     catch( const parser_error<std::string, iter_t>& e )
00217         {
00218             // this only happens if input is really wrong.
00219             throw parse_exception_syntactic_error( e.descriptor );
00220         }
00221 
00222     ActionInterface* ac = 0;
00223     std::vector<ActionInterface*> acv = parser.assignCommands();
00224     // and not forget to reset()..
00225     if ( acv.empty() && parser.lastDefinedValue() ) {
00226         return parser.lastDefinedValue()->getDataSource();
00227     }
00228     if ( acv.size() == 1 ) {
00229         if (acv.front() ) { // front will be null if its an alias.
00230             ac = acv.front();
00231             ac->readArguments();
00232             ac->execute();
00233             delete ac;
00234         }
00235         return parser.lastDefinedValue()->getDataSource();
00236     }
00237     else if (acv.size() > 1) {
00238         ac = new CommandComposite(acv);
00239     }
00240 
00241     if ( ac ) {
00242         DataSourceBase::shared_ptr ret = new DataSourceCommand( ac );
00243         //parser.reset(); don't do this, we want to keep it.
00244         return ret;
00245     }
00246     return DataSourceBase::shared_ptr();
00247   }
00248 }


rtt
Author(s): RTT Developers
autogenerated on Wed Aug 26 2015 16:15:50