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