00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "parser-debug.hpp"
00029 #include "parse_exception.hpp"
00030 #include "ProgramGraphParser.hpp"
00031 #include "ArgumentsParser.hpp"
00032
00033 #include "CommandNOP.hpp"
00034 #include "CommandDataSource.hpp"
00035 #include "ConditionTrue.hpp"
00036 #include "../Logger.hpp"
00037 #include "DataSourceCondition.hpp"
00038
00039 #include "ConditionComposite.hpp"
00040 #include "ConditionFalse.hpp"
00041 #include "ConditionOnce.hpp"
00042 #include "CommandComposite.hpp"
00043 #include "CommandBinary.hpp"
00044
00045 #include "TryCommand.hpp"
00046 #include "FunctionFactory.hpp"
00047 #include "../TaskContext.hpp"
00048 #include "../internal/GlobalService.hpp"
00049
00050 #include <iostream>
00051 #include <boost/bind.hpp>
00052 #include <boost/lambda/lambda.hpp>
00053
00054 #ifdef WIN32
00055 #ifdef NDEBUG
00056 #pragma optimize( "", off)
00057 #endif
00058 #endif
00059
00060 namespace RTT
00061 {
00062 using namespace boost;
00063 using namespace detail;
00064
00065
00066
00067 namespace {
00068 boost::spirit::classic::assertion<std::string> expect_opencurly("Open curly brace '{' expected.");
00069 boost::spirit::classic::assertion<std::string> expect_closecurly("Closing curly brace '}' expected in statement block (or could not find out what this line means).");
00070 boost::spirit::classic::assertion<std::string> expect_closefunction("Closing curly brace '}' expected at end of program or function (or could not find out what this line means).");
00071 boost::spirit::classic::assertion<std::string> expect_open("Open brace '(' expected.");
00072 boost::spirit::classic::assertion<std::string> expect_close("Closing brace ')' expected.");
00073 boost::spirit::classic::assertion<std::string> expect_comma("Expected a comma separator.");
00074 boost::spirit::classic::assertion<std::string> expect_ident("Expected a valid identifier.");
00075 boost::spirit::classic::assertion<std::string> expect_semicolon("Semicolon ';' expected after statement.");
00076 boost::spirit::classic::assertion<std::string> expect_condition("Expected a boolean expression ( a condition ).");
00077 boost::spirit::classic::assertion<std::string> expect_expression("Expected an expression.");
00078 boost::spirit::classic::assertion<std::string> expect_command("Expected a command after 'do'.");
00079 boost::spirit::classic::assertion<std::string> expect_nl("Expected a newline after statement.");
00080 boost::spirit::classic::assertion<std::string> expect_eof("Invalid input in file.");
00081 boost::spirit::classic::assertion<std::string> expect_term("No valid termination claues found in do ... until { } block.");
00082 }
00083
00084
00085 ProgramGraphParser::ProgramGraphParser( iter_t& positer, TaskContext* t, ExecutionEngine* caller, CommonParser& cp)
00086 : rootc( t ),context(), fcontext(0), mpositer( positer ),
00087 mcallfunc(),
00088 implcond(0), mcondition(0), try_cond(0),
00089 commonparser(cp),
00090 conditionparser( rootc, caller, cp ),
00091 valuechangeparser( rootc, cp, t->provides(), caller ),
00092 expressionparser( rootc, caller, cp ),
00093 argsparser(0),
00094 peerparser(rootc, commonparser),
00095 program_builder( new FunctionGraphBuilder() ),
00096 for_init_command(0),
00097 exportf(false),globalf(false),
00098 ln_offset(0)
00099 {
00100
00101 this->setup();
00102 this->setup2();
00103 }
00104
00105 ProgramGraphParser::~ProgramGraphParser() {
00106
00107
00108
00109 cleanup(true);
00110 }
00111
00112 void ProgramGraphParser::setup() {
00113 BOOST_SPIRIT_DEBUG_RULE( newline );
00114 BOOST_SPIRIT_DEBUG_RULE( openbrace );
00115 BOOST_SPIRIT_DEBUG_RULE( closebrace );
00116 BOOST_SPIRIT_DEBUG_RULE( opencurly );
00117 BOOST_SPIRIT_DEBUG_RULE( closecurly );
00118 BOOST_SPIRIT_DEBUG_RULE( semicolon );
00119 BOOST_SPIRIT_DEBUG_RULE( condition );
00120 BOOST_SPIRIT_DEBUG_RULE( terminationclause );
00121 BOOST_SPIRIT_DEBUG_RULE( jumpdestination );
00122 BOOST_SPIRIT_DEBUG_RULE( terminationpart );
00123 BOOST_SPIRIT_DEBUG_RULE( dostatement );
00124 BOOST_SPIRIT_DEBUG_RULE( trystatement );
00125 BOOST_SPIRIT_DEBUG_RULE( catchpart );
00126 BOOST_SPIRIT_DEBUG_RULE( statement );
00127 BOOST_SPIRIT_DEBUG_RULE( line );
00128 BOOST_SPIRIT_DEBUG_RULE( content );
00129 BOOST_SPIRIT_DEBUG_RULE( program );
00130 BOOST_SPIRIT_DEBUG_RULE( production );
00131 BOOST_SPIRIT_DEBUG_RULE( valuechange );
00132 BOOST_SPIRIT_DEBUG_RULE( function );
00133 BOOST_SPIRIT_DEBUG_RULE( functions );
00134 BOOST_SPIRIT_DEBUG_RULE( arguments );
00135 BOOST_SPIRIT_DEBUG_RULE( returnstatement );
00136 BOOST_SPIRIT_DEBUG_RULE( funcstatement );
00137 BOOST_SPIRIT_DEBUG_RULE( continuepart );
00138 BOOST_SPIRIT_DEBUG_RULE( callpart );
00139 BOOST_SPIRIT_DEBUG_RULE( returnpart );
00140 BOOST_SPIRIT_DEBUG_RULE( ifstatement );
00141 BOOST_SPIRIT_DEBUG_RULE( whilestatement );
00142 BOOST_SPIRIT_DEBUG_RULE( forstatement );
00143 BOOST_SPIRIT_DEBUG_RULE( breakstatement );
00144 BOOST_SPIRIT_DEBUG_RULE( ifblock );
00145 BOOST_SPIRIT_DEBUG_RULE( funcargs );
00146
00147
00148 openbrace = expect_open( ch_p('(') );
00149 closebrace = expect_close( ch_p(')') );
00150 opencurly = expect_opencurly( ch_p('{') );
00151 closecurly = expect_closecurly( ch_p('}') );
00152 semicolon = expect_semicolon( ch_p(';') );
00153 condition = expect_condition( conditionparser.parser()[ boost::bind(&ProgramGraphParser::seencondition, this) ] );
00154
00155
00156
00157
00158
00159
00160 production = *( program | function )[boost::bind(&ProgramGraphParser::programtext,this, _1, _2)] >> expect_eof(end_p) ;
00161
00162
00163 function = (
00164
00165 !( keyword_p( "export" )[boost::bind(&ProgramGraphParser::exportdef, this)] | keyword_p( "global" )[boost::bind(&ProgramGraphParser::globaldef, this)] | keyword_p("local") )
00166 >> (keyword_p( "function" ) | commonparser.notassertingidentifier[boost::bind( &ProgramGraphParser::seenreturntype, this, _1, _2)])
00167 >> expect_ident( commonparser.identifier[ boost::bind( &ProgramGraphParser::functiondef, this, _1, _2 ) ] )
00168 >> !funcargs
00169 >> opencurly
00170 >> content
00171 >> expect_closefunction( ch_p('}') )[ boost::bind( &ProgramGraphParser::seenfunctionend, this ) ]
00172 );
00173
00174
00175 funcargs = ch_p('(') >> ( !str_p("void") >> ch_p(')') | ((
00176 valuechangeparser.bareDefinitionParser()[boost::bind(&ProgramGraphParser::seenfunctionarg, this)]
00177 >> *(ch_p(',')>> valuechangeparser.bareDefinitionParser()[boost::bind(&ProgramGraphParser::seenfunctionarg, this)]) )
00178 >> closebrace ));
00179
00180
00181 program =
00182 keyword_p( "program" )
00183 >> expect_ident( commonparser.identifier[ boost::bind( &ProgramGraphParser::programdef, this, _1, _2 ) ] )
00184 >> opencurly
00185 >> content
00186 >> expect_closefunction( ch_p('}') )[ boost::bind( &ProgramGraphParser::seenprogramend, this ) ];
00187
00188
00189 content = *line;
00190
00191
00192
00193
00194
00195
00196 line = statement[boost::bind(&ProgramGraphParser::noskip_eol, this )] >> commonparser.eos[boost::bind(&ProgramGraphParser::skip_eol, this )];
00197
00198 statement = valuechange | trystatement | funcstatement | returnstatement | ifstatement | whilestatement | forstatement | breakstatement | dostatement;
00199
00200 valuechange = valuechangeparser.parser()[ boost::bind( &ProgramGraphParser::seenvaluechange, this ) ];
00201
00202
00203 dostatement = !keyword_p("do") >> !keyword_p("set") >> !keyword_p("call") >>
00204 (
00205 ( keyword_p("yield") | keyword_p("nothing"))[boost::bind(&ProgramGraphParser::seenyield,this)]
00206 | expressionparser.parser()[ boost::bind(&ProgramGraphParser::seenstatement,this) ]
00207 );
00208
00209
00210 trystatement =
00211 keyword_p("try")
00212 >> expect_command ( expressionparser.parser()[ boost::bind( &ProgramGraphParser::seentrystatement, this ) ] )
00213 >> !catchpart;
00214
00215 }
00216
00217 void ProgramGraphParser::initBodyParser(const std::string& name, Service::shared_ptr stck, int offset) {
00218 ln_offset = offset;
00219 assert(program_builder != 0 );
00220 program_builder->startFunction(name);
00221 this->setStack( stck );
00222 this->clearParseState();
00223 }
00224
00225 rule_t& ProgramGraphParser::programParser() {
00226 return program;
00227 }
00228
00229 rule_t& ProgramGraphParser::functionParser() {
00230 return function;
00231 }
00232
00233 rule_t& ProgramGraphParser::bodyParser() {
00234
00235 return content;
00236 }
00237
00238 rule_t& ProgramGraphParser::statementParser() {
00239
00240 return line;
00241 }
00242
00243 ProgramInterfacePtr ProgramGraphParser::programParserResult() {
00244 ProgramInterfacePtr result;
00245 if (program_list.empty())
00246 return result;
00247 program_text = "Bug: Program Text to be set by Parser.";
00248
00249 program_list.front()->setText( program_text );
00250 result=program_list.front();
00251 this->cleanup(false);
00252 program_list.clear();
00253 return result;
00254 }
00255
00256 ProgramInterfacePtr ProgramGraphParser::bodyParserResult() {
00257
00258
00259 valuechangeparser.store( context );
00260 valuechangeparser.reset();
00261
00262
00263 program_builder->returnFunction( new ConditionTrue, mpositer.get_position().line - ln_offset );
00264 program_builder->proceedToNext( mpositer.get_position().line - ln_offset);
00265 return program_builder->endFunction( mpositer.get_position().line - ln_offset );
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 void ProgramGraphParser::setStack(Service::shared_ptr st) {
00277 context = st;
00278 valuechangeparser.load(context);
00279 }
00280
00281 void ProgramGraphParser::clearParseState() {
00282 exportf = false;
00283 rettype.clear();
00284 }
00285
00286 void ProgramGraphParser::startofprogram()
00287 {
00288 }
00289
00290 void ProgramGraphParser::programdef( iter_t begin, iter_t end )
00291 {
00292
00293
00294 std::string def(begin, end);
00295
00296 if ( rootc->provides()->hasService( def ) )
00297 throw parse_exception_semantic_error("Service with name '" + def + "' already present in task '"+rootc->getName()+"'.");
00298
00299 FunctionGraphPtr pi(program_builder->startFunction( def ));
00300
00301 ProgramServicePtr ptsk(new ProgramService( pi, rootc ));
00302 pi->setProgramService(ptsk);
00303 pi->setUnloadOnStop( false );
00304 context = ptsk;
00305 rootc->provides()->addService( ptsk );
00306 }
00307
00308 void ProgramGraphParser::programtext( iter_t begin, iter_t end )
00309 {
00310
00311
00312 }
00313
00314 void ProgramGraphParser::exportdef()
00315 {
00316 exportf = true;
00317 }
00318
00319 void ProgramGraphParser::globaldef()
00320 {
00321 globalf = true;
00322 }
00323
00324 void ProgramGraphParser::seenreturntype( iter_t begin, iter_t end )
00325 {
00326 rettype = std::string(begin, end);
00327 }
00328 void ProgramGraphParser::functiondef( iter_t begin, iter_t end )
00329 {
00330
00331
00332 std::string funcdef(begin, end);
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 if ( mfuncs.count( funcdef ) )
00346 throw parse_exception_semantic_error("function " + funcdef + " redefined.");
00347
00348 AttributeBase* retarg = 0;
00349 if ( !rettype.empty() && rettype != "void") {
00350 TypeInfo* type = TypeInfoRepository::Instance()->type( rettype );
00351 if ( type == 0 )
00352 throw_( iter_t(), "Return type '" + rettype + "' for function '"+ funcdef +"' is an unknown type." );
00353 retarg = type->buildAttribute("result");
00354 }
00355
00356 mfuncs[funcdef] = program_builder->startFunction( funcdef );
00357 program_builder->getFunction()->setResult( retarg );
00358
00359 rettype.clear();
00360
00361
00362
00363 fcontext = new TaskContext(funcdef, rootc->engine() );
00364 context = fcontext->provides();
00365 }
00366
00367 void ProgramGraphParser::seenfunctionarg()
00368 {
00369
00370
00371
00372 program_builder->getFunction()->addArgument( valuechangeparser.lastDefinedValue()->clone() );
00373 valuechangeparser.clear();
00374 }
00375
00376 void ProgramGraphParser::seenfunctionend()
00377 {
00378
00379 program_builder->returnFunction( new ConditionTrue, mpositer.get_position().line - ln_offset );
00380 program_builder->proceedToNext( mpositer.get_position().line - ln_offset );
00381 boost::shared_ptr<ProgramInterface> mfunc = program_builder->endFunction( mpositer.get_position().line - ln_offset );
00382
00383
00384 if (exportf) {
00385 std::map<const DataSourceBase*, DataSourceBase*> dummy;
00386 FunctionFactory* cfi = new FunctionFactory(ProgramInterfacePtr(mfunc->copy(dummy)), rootc->engine() );
00387 if (rootc->provides()->hasMember( mfunc->getName() ) )
00388 log(Warning) << "Redefining function '"<< rootc->getName() << "." << mfunc->getName() << "': only new programs will use this new function." <<endlog();
00389 rootc->provides()->add(mfunc->getName(), cfi );
00390 Logger::log() << Logger::Info << "Exported Function '" << mfunc->getName() << "' added to task '"<< rootc->getName() << "'" <<Logger::endl;
00391 }
00392
00393 else if (globalf){
00394 std::map<const DataSourceBase*, DataSourceBase*> dummy;
00395 FunctionFactory* cfi = new FunctionFactory(ProgramInterfacePtr(mfunc->copy(dummy)), rootc->engine() );
00396 if (GlobalService::Instance()->provides()->hasMember( mfunc->getName() ) )
00397 log(Warning) << "Redefining function '"<< GlobalService::Instance()->getName() << "."<< mfunc->getName() << "': only new programs will use this new function." <<endlog();
00398 GlobalService::Instance()->provides()->add(mfunc->getName(), cfi );
00399 Logger::log() << Logger::Debug << "Seen Function '" << mfunc->getName() << "' for Global Service." <<Logger::endl;
00400 } else {
00401 std::map<const DataSourceBase*, DataSourceBase*> dummy;
00402 FunctionFactory* cfi = new FunctionFactory(ProgramInterfacePtr(mfunc->copy(dummy)), rootc->engine() );
00403 if (rootc->provides("scripting")->hasMember( mfunc->getName() ) )
00404 log(Warning) << "Redefining function '"<< rootc->getName() << ".scripting."<< mfunc->getName() << "': only new programs will use this new function." <<endlog();
00405 rootc->provides("scripting")->add(mfunc->getName(), cfi );
00406 Logger::log() << Logger::Debug << "Seen Function '" << mfunc->getName() << "' for scripting service of '"<< rootc->getName() << "'" <<Logger::endl;
00407 }
00408
00409
00410 delete fcontext;
00411 fcontext = 0;
00412 context.reset();
00413
00414
00415 exportf = false; globalf = false;
00416
00417 valuechangeparser.reset();
00418 }
00419
00420 void ProgramGraphParser::seencondition()
00421 {
00422 mcondition = conditionparser.getParseResult();
00423 assert( mcondition );
00424
00425
00426
00427
00428
00429
00430
00431 }
00432
00433 void ProgramGraphParser::seenreturnstatement()
00434 {
00435
00436 program_builder->returnFunction( new ConditionTrue, mpositer.get_position().line - ln_offset );
00437 program_builder->proceedToNext( mpositer.get_position().line - ln_offset );
00438 }
00439
00440 void ProgramGraphParser::seenreturnvalue()
00441 {
00442 AttributeBase* ar =program_builder->getFunction()->getResult();
00443 if ( ar == 0) {
00444 throw parse_exception_syntactic_error("Returning a value in a function returning (void).");
00445 }
00446 DataSourceBase::shared_ptr expr = expressionparser.getResult().get();
00447 expressionparser.dropResult();
00448 try {
00449 ActionInterface* assigncomm = ar->getDataSource()->updateAction( expr.get() );
00450
00451 program_builder->setCommand( assigncomm );
00452 program_builder->proceedToNext( new ConditionTrue(), mpositer.get_position().line - ln_offset );
00453 }
00454 catch(...) {
00455
00456 throw parse_exception_syntactic_error("Could not convert '" + expr->getType() + "' to '"+ ar->getDataSource()->getType() +"' in return statement.");
00457 }
00458 }
00459
00460 void ProgramGraphParser::seenbreakstatement()
00461 {
00462 if ( program_builder->inLoop() ) {
00463 program_builder->breakLoop();
00464 program_builder->proceedToNext( mpositer.get_position().line - ln_offset );
00465 } else
00466 throw parse_exception_syntactic_error("Illegal use of 'break'. Can only be used within for and while loops.");
00467 }
00468
00469 void ProgramGraphParser::seenfuncidentifier( iter_t begin, iter_t end )
00470 {
00471
00472 std::string fname(begin, end);
00473 if ( mfuncs.count(fname) == 0 )
00474 throw parse_exception_semantic_error("calling function " + fname + " but it is not defined ( remove the 'call' keyword ).");
00475 if ( fname == program_builder->getFunction()->getName() )
00476 throw parse_exception_semantic_error("calling function " + fname + " recursively is not allowed.");
00477
00478 mcallfunc = mfuncs[ fname ];
00479
00480
00481 argsparser = new ArgumentsParser( expressionparser, rootc, rootc->provides(),
00482 "this", fname );
00483 arguments = argsparser->parser();
00484
00485 }
00486
00487 void ProgramGraphParser::seencallfuncargs()
00488 {
00489 callfnargs = argsparser->result();
00490 }
00491
00492 void ProgramGraphParser::seencallfuncstatement()
00493 {
00494 log(Warning) << " 'call' has been deprecated. Please remove this keyword." << endlog();
00495
00496
00497
00498
00499 assert( mcallfunc );
00500 try
00501 {
00502 program_builder->setFunction( mcallfunc, callfnargs );
00503
00504 delete argsparser;
00505 argsparser = 0;
00506 callfnargs.clear();
00507 }
00508 catch( const wrong_number_of_args_exception& e )
00509 {
00510 throw parse_exception_wrong_number_of_arguments
00511 ( rootc->getName(), mcallfunc->getName(), e.wanted, e.received );
00512 }
00513 catch( const wrong_types_of_args_exception& e )
00514 {
00515 throw parse_exception_wrong_type_of_argument
00516 ( rootc->getName(), mcallfunc->getName(), e.whicharg, e.expected_, e.received_ );
00517 }
00518 catch( ... )
00519 {
00520 assert( false );
00521 }
00522
00523
00524
00525 program_builder->proceedToNext(mpositer.get_position().line - ln_offset);
00526 }
00527
00528 void ProgramGraphParser::skip_eol() {
00529 commonparser.skipeol = true;
00530 }
00531
00532 void ProgramGraphParser::noskip_eol() {
00533 commonparser.skipeol = false;
00534 }
00535
00536 void ProgramGraphParser::startcatchpart() {
00537
00538
00539 assert( try_cond );
00540 program_builder->startIfStatement( try_cond, mpositer.get_position().line - ln_offset );
00541 try_cond = 0;
00542 }
00543
00544 void ProgramGraphParser::seencatchpart() {
00545 this->endifblock();
00546 this->endifstatement();
00547 }
00548
00549 void ProgramGraphParser::seenifstatement() {
00550 assert(mcondition);
00551
00552
00553 std::pair<ActionInterface*, ConditionInterface*> comcon;
00554 comcon = conditionparser.getParseResultAsCommand();
00555 program_builder->setCommand( comcon.first );
00556 program_builder->startIfStatement( comcon.second, mpositer.get_position().line - ln_offset );
00557
00558
00559 delete mcondition;
00560 mcondition = 0;
00561 }
00562
00563 void ProgramGraphParser::endifblock() {
00564 program_builder->endIfBlock(mpositer.get_position().line - ln_offset);
00565 }
00566
00567
00568 void ProgramGraphParser::endifstatement() {
00569 program_builder->endElseBlock(mpositer.get_position().line - ln_offset);
00570 }
00571
00572 void ProgramGraphParser::seenwhilestatement() {
00573
00574
00575 assert(mcondition);
00576 std::pair<ActionInterface*, ConditionInterface*> comcon;
00577 comcon = conditionparser.getParseResultAsCommand();
00578 program_builder->setCommand( comcon.first );
00579 program_builder->startWhileStatement( comcon.second, mpositer.get_position().line - ln_offset );
00580
00581 delete mcondition;
00582 mcondition = 0;
00583 }
00584
00585 void ProgramGraphParser::endwhilestatement() {
00586 program_builder->endWhileBlock(mpositer.get_position().line - ln_offset);
00587 }
00588
00589
00590 void ProgramGraphParser::seenforinit()
00591 {
00592
00593
00594 ActionInterface* ac = 0;
00595 std::vector<ActionInterface*> acv = valuechangeparser.assignCommands();
00596
00597 valuechangeparser.clear();
00598 if ( acv.size() == 1) {
00599 ac = acv.front();
00600 }
00601 else if (acv.size() > 1) {
00602 ac = new CommandComposite( acv );
00603 }
00604 for_init_command = ac;
00605 }
00606
00607 void ProgramGraphParser::seenforinit_expr()
00608 {
00609 DataSourceBase::shared_ptr expr = expressionparser.getResult();
00610 expressionparser.dropResult();
00611 for_init_command = new CommandDataSource( expr );
00612 }
00613
00614 void ProgramGraphParser::seenforincr()
00615 {
00616 DataSourceBase::shared_ptr expr = expressionparser.getResult();
00617 expressionparser.dropResult();
00618 for_incr_command.push( new CommandDataSource( expr ) );
00619 }
00620
00621 void ProgramGraphParser::seenemptyforincr()
00622 {
00623 for_incr_command.push( 0 );
00624 }
00625
00626 void ProgramGraphParser::seenforstatement() {
00627 assert( mcondition );
00628
00629
00630 if ( for_init_command )
00631 {
00632 program_builder->setCommand( for_init_command );
00633 program_builder->proceedToNext( new ConditionTrue, mpositer.get_position().line - ln_offset );
00634 }
00635 for_init_command = 0;
00636
00637
00638 std::pair<ActionInterface*, ConditionInterface*> comcon;
00639 comcon = conditionparser.getParseResultAsCommand();
00640 program_builder->setCommand( comcon.first );
00641 program_builder->startWhileStatement( comcon.second, mpositer.get_position().line - ln_offset );
00642 delete mcondition;
00643 mcondition = 0;
00644 }
00645
00646 void ProgramGraphParser::endforstatement() {
00647
00648 ActionInterface* incr = for_incr_command.top();
00649 for_incr_command.pop();
00650
00651 if ( incr )
00652 {
00653 program_builder->setCommand( incr );
00654
00655
00656 program_builder->proceedToNext( new ConditionTrue, mpositer.get_position().line - ln_offset );
00657 }
00658 program_builder->endWhileBlock(mpositer.get_position().line - ln_offset);
00659 }
00660
00661 void ProgramGraphParser::seenprogramend()
00662 {
00663
00664 program_builder->returnFunction( new ConditionTrue, mpositer.get_position().line - ln_offset );
00665 program_builder->proceedToNext( mpositer.get_position().line - ln_offset );
00666 program_list.push_back(program_builder->endFunction( mpositer.get_position().line - ln_offset ) );
00667
00668
00669 valuechangeparser.store( context );
00670 valuechangeparser.reset();
00671 }
00672
00673 std::vector< ProgramInterfacePtr > ProgramGraphParser::parse( iter_t& begin, iter_t end )
00674 {
00675
00676 iter_t begin_copy = begin;
00677
00678
00679 iter_pol_t iter_policy( ( comment_p( "#" ) | comment_p( "//" ) | comment_p( "/*", "*/" ) | (space_p - eol_p) | commonparser.skipper ) );
00680 scanner_pol_t policies( iter_policy );
00681 scanner_t scanner( begin, end, policies );
00682 program_list.clear();
00683
00684
00685
00686
00687 try {
00688 if ( ! production.parse( scanner ) )
00689 {
00690
00691 cleanup(true);
00692 throw file_parse_exception(new parse_exception_syntactic_error( " no valid input found." ),
00693 mpositer.get_position().file, mpositer.get_position().line,
00694 mpositer.get_position().column );
00695 }
00696 program_text = std::string( begin_copy, begin );
00697
00698 for (std::vector<FunctionGraphPtr>::iterator it= program_list.begin();it!=program_list.end();++it)
00699 (*it)->setText( program_text );
00700 this->cleanup(false);
00701 std::vector<ProgramInterfacePtr> result;
00702 for (std::vector<FunctionGraphPtr>::iterator it= program_list.begin();it!=program_list.end();++it)
00703 result.push_back( *it );
00704 program_list.clear();
00705 return result;
00706 }
00707 catch( const parser_error<std::string, iter_t>& e )
00708 {
00709 cleanup(true);
00710 program_list.clear();
00711 throw file_parse_exception(
00712 new parse_exception_syntactic_error( e.descriptor ),
00713 mpositer.get_position().file, mpositer.get_position().line,
00714 mpositer.get_position().column );
00715
00716 }
00717
00718 catch( const parse_exception& e )
00719 {
00720 cleanup(true);
00721 program_list.clear();
00722 throw file_parse_exception(
00723 e.copy(), mpositer.get_position().file,
00724 mpositer.get_position().line, mpositer.get_position().column );
00725 }
00726 }
00727
00728 std::vector< ProgramInterfacePtr > ProgramGraphParser::parseFunction( iter_t& begin, iter_t end )
00729 {
00730
00731 iter_t begin_copy = begin;
00732
00733
00734 iter_pol_t iter_policy( ( comment_p( "#" ) | comment_p( "//" ) | comment_p( "/*", "*/" ) | (space_p - eol_p) | commonparser.skipper ) );
00735 scanner_pol_t policies( iter_policy );
00736 scanner_t scanner( begin, end, policies );
00737
00738 std::vector< ProgramInterfacePtr > function_list;
00739
00740 try {
00741 if ( ! functions.parse( scanner ) )
00742 {
00743
00744 cleanup(false);
00745 throw file_parse_exception(new parse_exception_syntactic_error( " no valid input found." ),
00746 mpositer.get_position().file, mpositer.get_position().line,
00747 mpositer.get_position().column );
00748 }
00749 program_text = std::string( begin_copy, begin );
00750
00751 for (funcmap::iterator it= mfuncs.begin();it!=mfuncs.end();++it) {
00752 it->second->setText( program_text );
00753 function_list.push_back( it->second );
00754 }
00755
00756 this->cleanup(false);
00757 return function_list;
00758 }
00759
00760 catch( const parser_error<std::string, iter_t>& e )
00761 {
00762 cleanup(false);
00763 throw file_parse_exception(
00764 new parse_exception_syntactic_error( e.descriptor ),
00765 mpositer.get_position().file, mpositer.get_position().line,
00766 mpositer.get_position().column );
00767
00768 }
00769
00770 catch( const parse_exception& e )
00771 {
00772 cleanup(false);
00773 throw file_parse_exception(
00774 e.copy(), mpositer.get_position().file,
00775 mpositer.get_position().line, mpositer.get_position().column );
00776 }
00777 }
00778
00779 void ProgramGraphParser::cleanup(bool unload_service)
00780 {
00781 if (unload_service && rootc && context)
00782 rootc->provides()->removeService( context->getName() );
00783
00784
00785 delete argsparser;
00786 argsparser = 0;
00787 delete implcond;
00788 implcond = 0;
00789 delete mcondition;
00790 mcondition = 0;
00791 delete try_cond;
00792 try_cond = 0;
00793 delete for_init_command;
00794 for_init_command = 0;
00795 while (!for_incr_command.empty() ) {
00796 delete for_incr_command.top();
00797 for_incr_command.pop();
00798 }
00799
00800 delete fcontext;
00801 fcontext = 0;
00802 exportf = false; globalf = false;
00803 rettype.clear();
00804 if ( rootc == 0)
00805 return;
00806
00807
00808
00809
00810
00811
00812 while ( ! mfuncs.empty() ) {
00813 mfuncs.erase( mfuncs.begin() );
00814 }
00815 context.reset();
00816
00817 valuechangeparser.reset();
00818 conditionparser.reset();
00819 peerparser.reset();
00820 }
00821
00822 void ProgramGraphParser::seentrystatement()
00823 {
00824
00825 ActionInterface* command;
00826 DataSourceBase::shared_ptr expr = expressionparser.getResult().get();
00827 expressionparser.dropResult();
00828 DataSource<bool>* bexpr = dynamic_cast<DataSource<bool>*>(expr.get());
00829 if (bexpr == 0) {
00830
00831 command = new CommandDataSource( expr );
00832 try_cond = new ConditionFalse();
00833 program_builder->setCommand(command);
00834 } else {
00835 command = new CommandDataSourceBool( bexpr );
00836
00837
00838 TryCommand* trycommand = new TryCommand( command );
00839
00840 TryCommandResult* tryresult = new TryCommandResult( trycommand->result(), true );
00841 program_builder->setCommand( trycommand );
00842 try_cond = tryresult;
00843 }
00844 if ( program_builder->buildEdges() == 0 )
00845 program_builder->proceedToNext( new ConditionTrue(), mpositer.get_position().line - ln_offset );
00846 else
00847 program_builder->proceedToNext( mpositer.get_position().line - ln_offset );
00848 }
00849
00850 void ProgramGraphParser::seenstatement()
00851 {
00852
00853 DataSourceBase::shared_ptr expr = expressionparser.getResult().get();
00854 expressionparser.dropResult();
00855 DataSource<bool>* bexpr = dynamic_cast<DataSource<bool>*>(expr.get());
00856 if (bexpr)
00857 program_builder->setCommand( new CommandDataSourceBool( bexpr ) );
00858 else
00859 program_builder->setCommand( new CommandDataSource( expr ) );
00860 if ( program_builder->buildEdges() == 0 )
00861 program_builder->proceedToNext( new ConditionTrue(), mpositer.get_position().line - ln_offset );
00862 else
00863 program_builder->proceedToNext( mpositer.get_position().line - ln_offset );
00864 }
00865
00866 void ProgramGraphParser::seenyield()
00867 {
00868
00869 program_builder->setCommand( new CommandNOP );
00870 program_builder->proceedToNext( new ConditionOnce(false), mpositer.get_position().line - ln_offset );
00871 }
00872
00873 void ProgramGraphParser::seenvaluechange()
00874 {
00875
00876
00877 ActionInterface* ac = 0;
00878 std::vector<ActionInterface*> acv = valuechangeparser.assignCommands();
00879
00880 valuechangeparser.clear();
00881 if ( acv.size() == 1) {
00882 ac = acv.front();
00883 }
00884 else if (acv.size() > 1) {
00885 ac = new CommandComposite(acv);
00886 }
00887 if (ac) {
00888 program_builder->setCommand( ac );
00889
00890
00891 program_builder->proceedToNext( new ConditionTrue, mpositer.get_position().line - ln_offset );
00892 }
00893 }
00894
00895 void ProgramGraphParser::seencallfunclabel( iter_t begin, iter_t end )
00896 {
00897
00898
00899 seenfuncidentifier( begin, end );
00900
00901 assert( mcondition );
00902 assert( mcallfunc );
00903 program_builder->appendFunction( mcondition, mcallfunc, callfnargs);
00904 mcondition = 0;
00905
00906 }
00907
00908 void ProgramGraphParser::seencontinue( )
00909 {
00910
00911
00912 assert ( mcondition );
00913
00914
00915 program_builder->addConditionEdge( mcondition, program_builder->nextNode() );
00916
00917 mcondition = 0;
00918 }
00919 }