Parsers_BT.cpp
Go to the documentation of this file.
00001 // http://www.compileonline.com/compile_cpp0x_online.php
00002 #include <iostream>
00003 #include <fstream>
00004 #include <deque>
00005 
00006 #include "Tokenizer.h"
00007 #include "BTConstructor.h"
00008 #include "ParserExceptions.h"
00009 
00010 using bt_constructor::BTConstructor;
00011 
00012 template<class A, class B>
00013 std::string operator+(const A& s, const B& t){
00014         std::stringstream ss; ss<<s<<t;
00015         return ss.str();
00016 }
00017 
00018 #define PRINT(X) //cout<<"parser: "<<X<<endl
00019 
00020 class BTParser {
00021 public:
00022         enum TokenType{
00023                 tkn_null=0,
00024                 tkn_text=1,
00025 
00026                 tkn_bopen,
00027                 tkn_bclose,
00028                 tkn_fopen,
00029                 tkn_fclose,
00030                 tkn_semicol,
00031                 tkn_col,
00032 
00033                 tkn_bt_bgn,
00034                 tkn_bt_root_bgn,
00035                 tkn_par_bgn,
00036                 tkn_seq_bgn,
00037                 tkn_sel_bgn,
00038                 tkn_task_bgn,
00039 
00040                 tkn_dec_not_bgn,
00041                 tkn_dec_success_bgn,
00042                 tkn_dec_fail_bgn,
00043 
00044                 tkn_bt_end,
00045                 tkn_par_end,
00046                 tkn_seq_end,
00047                 tkn_sel_end,
00048                 tkn_task_end,
00049 
00050                 tkn_dec_not_end,
00051         tkn_dec_success_end,
00052         tkn_dec_fail_end,
00053 
00054         tkn_set_task_result,
00055         tkn_set_task_result_after,
00056 
00057                 tkn_call_bt,
00058                 tkn_call_task,
00059                 tkn_call_fsm,
00060         };
00061 
00062 
00063         //============= TOKENAZER ===============================
00064 
00065         struct TokenizerInit{
00066                 void init(Parser::TokenizerData<TokenType>& tkn){
00067                         tkn.string_token["BT_BGN"]=tkn_bt_bgn;
00068                         tkn.string_token["BT_PAR_BGN"]=tkn_par_bgn;
00069                         tkn.string_token["BT_SEQ_BGN"]=tkn_seq_bgn;
00070                         tkn.string_token["BT_SEL_BGN"]=tkn_sel_bgn;
00071                         tkn.string_token["BT_ROOT_BGN"]=tkn_bt_root_bgn;
00072                         tkn.string_token["BT_TASK_BGN"]=tkn_task_bgn;
00073 
00074                         tkn.string_token["BT_DEC_NOT_BGN"]=tkn_dec_not_bgn;
00075                         tkn.string_token["BT_DEC_SUCCESS_BGN"]=tkn_dec_success_bgn;
00076                         tkn.string_token["BT_DEC_FAIL_BGN"]=tkn_dec_fail_bgn;
00077 
00078                         tkn.string_token["BT_END"]=tkn_bt_end;
00079                         tkn.string_token["BT_PAR_END"]=tkn_par_end;
00080                         tkn.string_token["BT_SEQ_END"]=tkn_seq_end;
00081                         tkn.string_token["BT_SEL_END"]=tkn_sel_end;
00082                         tkn.string_token["BT_TASK_END"]=tkn_task_end;
00083 
00084                         tkn.string_token["BT_DEC_NOT_END"]=tkn_dec_not_end;
00085             tkn.string_token["BT_DEC_SUCCESS_END"]=tkn_dec_success_end;
00086             tkn.string_token["BT_DEC_FAIL_END"]=tkn_dec_fail_end;
00087 
00088             tkn.string_token["BT_SET_TASK_RESULT"]=tkn_set_task_result;
00089             tkn.string_token["BT_SET_TASK_RESULT_AFTER"]=tkn_set_task_result_after;
00090 
00091                         tkn.string_token["BT_CALL_FSM"]=tkn_call_fsm;
00092                         tkn.string_token["BT_CALL_BT"]=tkn_call_bt;
00093                         tkn.string_token["BT_CALL_TASK"]=tkn_call_task;
00094 
00095                         tkn.spec_token['(']=tkn_bopen;
00096                         tkn.spec_token[')']=tkn_bclose;
00097                         tkn.spec_token['{']=tkn_fopen;
00098                         tkn.spec_token['}']=tkn_fclose;
00099                         tkn.spec_token[',']=tkn_col;
00100                         //tkn.spec_token[';']=tkn_semicol;
00101                 }
00102                 bool isTokenSumbol(char c){
00103                         return
00104                                 ('0'<=c and c<='9') or
00105                                 ('a'<=c and c<='z') or
00106                                 ('A'<=c and c<='Z') or
00107                                 (c=='_')
00108                         ;
00109                 }
00110                 bool isDelimiter(char c){
00111                         return not isTokenSumbol(c);
00112                 }
00113                 bool isFlowControl(char c){
00114                         return c==10 or c==13;
00115                 }
00116         };
00117 
00118         //============= LEXEM PARSER =================================
00119 
00120         typedef Parser::TokenStream<TokenType> tstream;
00121         typedef Parser::Token<TokenType> Token;
00122 
00123         bool name(tstream& stream, string txt, string& output, int& line, int& pos){
00124                 Token tkn;
00125                 TKN_NEXT( tkn_bopen )
00126                 TKN_NEXT( tkn_text )
00127                 PRINT( txt<<" name is "<<tkn.text );
00128                 output=tkn.text;
00129                 searchLineInfo(tkn.start, line, pos);
00130                 TKN_NEXT( tkn_bclose )
00131                 return true;
00132         }
00133 
00134         size_t findClosingBracket(tstream& stream, TokenType openToken, TokenType closeToken) {
00135         size_t foundIndex = tkn_search_close_parent(stream, openToken, closeToken);
00136 
00137 //        if (foundIndex == size_t(-1))
00138 //            throw ClosingBracketNotFound();
00139 
00140         return foundIndex;
00141     }
00142 
00143         bool parse_bracket_content(tstream& stream, string& outputText) {
00144         Token tkn;
00145         TokenType openingBracket;
00146         TokenType closingBracket;
00147         stream >> tkn;
00148 
00149         if (tkn.type == tkn_bopen) {
00150             openingBracket = tkn.type;
00151             closingBracket = tkn_bclose;
00152         } else if (tkn.type == tkn_fopen) {
00153             openingBracket = tkn.type;
00154             closingBracket = tkn_fclose;
00155         } else
00156             return false;
00157 
00158 
00159         size_t foundIndex = findClosingBracket(stream, openingBracket, closingBracket);
00160 
00161         if (foundIndex == size_t(-1))
00162             return false;
00163 
00164         string resultString;
00165         long startPosition = -1;
00166         long endPosition = -1;
00167 
00168         while (foundIndex > stream.i + 1) {
00169             stream >> tkn;
00170             resultString += tkn.text;
00171 
00172             if (startPosition < 0)
00173                 startPosition = tkn.start;
00174         }
00175 
00176         endPosition = tkn.end;
00177 
00178         // Closing bracket
00179         stream >> tkn;
00180 
00181         if (startPosition >= 0 and endPosition > startPosition)
00182             resultString = fullText.substr(startPosition, endPosition - startPosition);
00183 
00184         outputText = resultString;
00185         return true;
00186     }
00187 
00188         bool name(tstream& stream, string txt, string& output){
00189                 int line, pos;
00190                 return name(stream, txt, output, line, pos);
00191         }
00192 
00193         bool root_name(tstream& stream, string txt, string& output){
00194                 Token tkn;
00195                 TKN_NEXT( tkn_bopen )
00196                 TKN_NEXT( tkn_text )
00197                 PRINT( txt<<" name is "<<tkn.text );
00198                 output=tkn.text;
00199                 while(stream.eof()==false and tkn.type!=tkn_bclose ){
00200                         stream >> tkn;
00201                 }
00202                 return true;
00203         }
00204 
00205         std::deque<Token> tknStack;
00206         TokenType endOfTask(TokenType bgn){
00207                 switch(bgn){
00208                 case tkn_par_bgn: return tkn_par_end;
00209                 case tkn_seq_bgn: return tkn_seq_end;
00210                 case tkn_sel_bgn: return tkn_sel_end;
00211                 case tkn_task_bgn: return tkn_task_end;
00212                 case tkn_bt_bgn: return tkn_bt_end;
00213                 case tkn_bt_root_bgn: return tkn_bt_end;
00214 
00218                 case tkn_dec_not_bgn: return tkn_dec_not_end;
00219                 case tkn_dec_success_bgn: return tkn_dec_success_end;
00220                 case tkn_dec_fail_bgn: return tkn_dec_fail_end;
00221 
00222                 default: return tkn_null;
00223                 }
00224         }
00225 
00226         bool bt_node_body(tstream& stream, Token& tkn){
00227                 tknStack.push_back(tkn);
00228                 TokenType endTkn = endOfTask(tkn.type);
00229                 size_t end = TKN_SEARCH_CLOSE_PARENT(end, stream, tkn.type, endTkn, "task def");
00230                 size_t cend = stream.getEnd();
00231                 stream.setEnd(end-1);
00232                 TKN_SEARCH( bt_node(stream) );
00233                 stream.setEnd(cend);
00234                 return true;
00235         }
00236 
00237         string node_type_str(TokenType t){
00238                 switch(t){
00239                 case tkn_par_bgn: return "par";
00240                 case tkn_sel_bgn: return "sel";
00241                 case tkn_seq_bgn: return "seq";
00242                 case tkn_task_bgn: return "task";
00243 
00244                 case tkn_dec_not_bgn: return "dec";
00245                 case tkn_dec_success_bgn: return "dec";
00246                 case tkn_dec_fail_bgn: return "dec";
00247 
00248                 default: return "?";
00249                 }
00250         }
00251 
00252         bool bt_node(tstream& stream){
00253                 Token tkn;
00254                 while(not stream.eof()){
00255                         stream >> tkn;
00256 
00260                         if(
00261                                 tkn.type == tkn_par_bgn or
00262                                 tkn.type == tkn_seq_bgn or
00263                                 tkn.type == tkn_sel_bgn or
00264                                 tkn.type == tkn_task_bgn or
00265                                 tkn.type == tkn_dec_fail_bgn
00266                         ){
00267                                 constructor.tree().create_node();
00268                                 constructor.tree().node().type = node_type_str(tkn.type);
00269                                 TKN_SEARCH( name(stream, "node "+tkn.type+" start", constructor.tree().node().name) )
00270 
00271                                 if (tkn.type == tkn_dec_fail_bgn) {
00272                                     constructor.tree().node().name = "Fail";
00273                                     constructor.tree().node().decorator_name = "Fail [" + constructor.tree().node().name + "]";
00274                                 }
00275 
00276                                 if( bt_node_body(stream, tkn) ){
00277                                         constructor.tree().add_node();
00278                                 }else{
00279                                         constructor.tree().drop_node();
00280                                         return false;
00281                                 }
00282                         }
00283 
00284                         if(
00285                 tkn.type == tkn_dec_not_bgn or
00286                 tkn.type == tkn_dec_success_bgn
00287             ){
00288 
00289                             constructor.tree().create_node();
00290                 constructor.tree().node().type = node_type_str(tkn.type);
00291                 constructor.tree().node().name = tkn.type == tkn_dec_not_bgn ? "Not" : "Success";
00292 
00293                 if( bt_node_body(stream, tkn) ){
00294                     constructor.tree().add_node();
00295                 }else{
00296                     constructor.tree().drop_node();
00297                     return false;
00298                 }
00299             }
00300 
00301                         if(
00302                                 tkn.type == tkn_par_end or
00303                                 tkn.type == tkn_seq_end or
00304                                 tkn.type == tkn_sel_end or
00305                                 tkn.type == tkn_task_end
00306                         ){
00307                                 string node_name;
00308 
00309                                 TKN_SEARCH( name(stream, "node "+tkn+" end", node_name) )
00310                                 tknStack.pop_back();
00311                         }
00312 
00316             if(
00317                 tkn.type == tkn_dec_not_end or
00318                 tkn.type == tkn_dec_success_end or
00319                 tkn.type == tkn_dec_fail_end
00320             ){
00321                 tknStack.pop_back();
00322             }
00323 
00324                         if( tkn.type == tkn_call_fsm ){
00325                                 string node_name; int line, pos;
00326                                 TKN_SEARCH( name(stream, "node "+tkn+"", node_name, line, pos) )
00327                                 constructor.tree().node().create_call();
00328                                 constructor.tree().node().call().type = "fsm";
00329                                 constructor.tree().node().call().name = node_name;
00330                                 constructor.tree().node().call().file = filename;
00331                                 constructor.tree().node().call().line = line;
00332                                 constructor.tree().node().call().pos = pos;
00333                                 constructor.tree().node().add_call();
00334                         }
00335                         if( tkn.type == tkn_call_bt ){
00336                                 string node_name; int line, pos;
00337                                 TKN_SEARCH( name(stream, "node "+tkn+"", node_name, line, pos) )
00338                                 constructor.tree().node().create_call();
00339                                 constructor.tree().node().call().type = "bt";
00340                                 constructor.tree().node().call().name = node_name;
00341                                 constructor.tree().node().call().file = filename;
00342                                 constructor.tree().node().call().line = line;
00343                                 constructor.tree().node().call().pos = pos;
00344                                 constructor.tree().node().add_call();
00345                         }
00346                         if( tkn.type == tkn_call_task ){
00347                                 string node_name; int line, pos;
00348                                 TKN_SEARCH( name(stream, "node "+tkn+"", node_name, line, pos) )
00349                                 constructor.tree().node().create_call();
00350                                 constructor.tree().node().call().type = "rtask";
00351                                 constructor.tree().node().call().name = node_name;
00352                                 constructor.tree().node().call().file = filename;
00353                                 constructor.tree().node().call().line = line;
00354                                 constructor.tree().node().call().pos = pos;
00355                                 constructor.tree().node().add_call();
00356                         }
00357 
00358                         if( tkn.type == tkn_set_task_result ){
00359                 string node_name; int line, pos;
00360                 TKN_SEARCH( parse_bracket_content(stream, node_name) )
00361                 constructor.tree().node().create_call();
00362                 constructor.tree().node().call().type = "task_result";
00363                 constructor.tree().node().call().name = "TaskResult";
00364                 constructor.tree().node().call().task_result = node_name;
00365                 constructor.tree().node().call().file = filename;
00366                 constructor.tree().node().call().line = line;
00367                 constructor.tree().node().call().pos = pos;
00368                 constructor.tree().node().add_call();
00369             }
00370                         if( tkn.type == tkn_set_task_result_after ){
00371                 string node_name; int line, pos;
00372                 TKN_SEARCH( parse_bracket_content(stream, node_name) )
00373                 constructor.tree().node().create_call();
00374                 constructor.tree().node().call().type = "task_result_after";
00375                 constructor.tree().node().call().name = "TaskResultAfter";
00376                 constructor.tree().node().call().task_result = node_name;
00377                 constructor.tree().node().call().file = filename;
00378                 constructor.tree().node().call().line = line;
00379                 constructor.tree().node().call().pos = pos;
00380                 constructor.tree().node().add_call();
00381             }
00382 
00383         }
00384 
00385                 return true;
00386         }
00387 
00388 
00389         bool bt_body(tstream& stream, Token& tkn){
00390                 TKN_SEARCH( root_name(stream, "BT "+tkn+" start", constructor.tree().name) )
00391                 TokenType endTkn = endOfTask(tkn.type);
00392                 size_t end = TKN_SEARCH_CLOSE_PARENT(end, stream, tkn.type, endTkn, "task def");
00393                 size_t cend = stream.getEnd();
00394                 stream.setEnd(end-1);
00395                 TKN_SEARCH( bt_node(stream) );
00396                 stream.setEnd(cend);
00397                 return true;
00398         }
00399         bool bt(tstream& stream){
00400                 Token tkn;
00401                 PRINT("start search from "<<stream.first());
00402                 while(not stream.eof()){
00403                         stream >> tkn;
00404                         if( tkn.type == tkn_bt_bgn or tkn.type == tkn_bt_root_bgn ){
00405                                 constructor.create_tree();
00406                                 if( bt_body(stream, tkn) ){
00407                                         constructor.add_tree();
00408                                 }else{
00409                                         constructor.drop_tree();
00410                                 }
00411                         }
00412                         if(
00413                                 tkn.type == tkn_bt_end
00414                         ){
00415                                 string bt_name;
00416                                 TKN_SEARCH( name(stream, "BT "+tkn+" end", bt_name) )
00417                         }
00418                 }
00419                 return false;
00420         }
00421 
00422         struct TokenizerContext{
00423                 Parser::Tokenizer<TokenType, TokenizerInit> tokenizer;
00424                 std::stringstream ss_fullText;
00425                 stringstream buffer;
00426                 size_t start_index, index;
00427                 ifstream& file;
00428                 char c;
00429                 TokenizerContext(ifstream& file):
00430                 start_index(0),index(0),
00431                 file(file), c(0)
00432                 {}
00433         };
00434 
00435         void searchLineInfo(int i, int& line, int& pos){
00436                 line=0;
00437                 for(size_t n=0;n<lines.size();n++){
00438                         if(i<lines[n]){
00439                                 pos = i-lines[line-2];
00440                                 return;
00441                         }
00442                         line = n+2;
00443                 }
00444         }
00445 
00446         void saveReadedChar(TokenizerContext& ctx , char c){
00447                 ctx.ss_fullText<<c;
00448                 if(c=='\n') lines.push_back(ctx.index);
00449         }
00450 
00451         bool skipComments( TokenizerContext& ctx )
00452         {
00453                 if(ctx.c=='/' and ctx.file.eof()==false){
00454                         char cc;
00455                         ctx.file.read(&cc, 1); saveReadedChar(ctx, cc);
00456                         if(cc=='/'){
00457                                 ctx.index++;
00458                                 while(cc!='\n' and ctx.file.eof()==false){
00459                                         ctx.file.read(&cc, 1); saveReadedChar(ctx, cc); ctx.index++;
00460                                 }
00461                                 ctx.index++;
00462                                 return true;
00463                         }
00464                         else{
00465                                 ctx.tokenizer.searchToken(ctx.index++, ctx.buffer, ctx.start_index, ctx.c, tokens);
00466                                 ctx.c=cc;
00467                         }
00468                 }
00469                 return false;
00470         }
00471 
00472         BTParser(string file):filename(file), constructor(errors, file){}
00473 
00474         string filename;
00475         std::string fullText;
00476         tstream tokens;
00477         BTConstructor constructor;
00478         std::stringstream errors;
00479         std::vector<int> lines;
00480 
00481         BTConstructor& main()
00482         {
00483                 PRINT(__TIME__);
00484                 if(true){
00485                         PRINT("Read input file");
00486                         ifstream file(filename.c_str());
00487                         TokenizerContext ctx(file);
00488                         if(ctx.file.is_open()){
00489                                 PRINT("File ("<<filename<<") is open");
00490                                 while(ctx.file.eof()==false){
00491                                         ctx.file.read(&ctx.c, 1); saveReadedChar(ctx, ctx.c);
00492                                         if(skipComments(ctx)) continue;
00493                                         ctx.tokenizer.searchToken(ctx.index++, ctx.buffer, ctx.start_index, ctx.c, tokens);
00494                                 }
00495                                 PRINT("End of file");
00496                                 fullText = ctx.ss_fullText.str();
00497                                 file.close();
00498                         }else{
00499                                 throw PEFileNotFound(filename);
00500                         }
00501                 }
00502 
00503                 if(false){
00504                         //cout<<"Result: ";
00505                         while(not tokens.eof()){
00506                                 Token t; tokens>>t;
00507                                 PRINT(t);
00508                         }
00509                 }
00510                 if(true){
00511                         while( bt(tokens) );
00512                         //PRINT( constructor );
00513                 }
00514 
00515                 return constructor;
00516         }
00517 
00518 };
00519 
00520 ostream& operator<<(ostream& out, BTParser::TokenType t){
00521         #define PRINTTKN(x) case BTParser::tkn_##x: return out<<#x;
00522         switch(t){
00523                 PRINTTKN(null)
00524                 PRINTTKN(text)
00525 
00526                 PRINTTKN(bopen)
00527                 PRINTTKN(bclose)
00528                 PRINTTKN(fopen)
00529                 PRINTTKN(fclose)
00530                 PRINTTKN(semicol)
00531                 PRINTTKN(col)
00532 
00533                 PRINTTKN(bt_bgn)
00534                 PRINTTKN(bt_root_bgn)
00535                 PRINTTKN(par_bgn)
00536                 PRINTTKN(seq_bgn)
00537                 PRINTTKN(sel_bgn)
00538                 PRINTTKN(task_bgn)
00539 
00540                 PRINTTKN(bt_end)
00541                 PRINTTKN(par_end)
00542                 PRINTTKN(seq_end)
00543                 PRINTTKN(sel_end)
00544                 PRINTTKN(task_end)
00545 
00546                 PRINTTKN(call_bt)
00547                 PRINTTKN(call_task)
00548                 PRINTTKN(call_fsm)
00549         }
00550         return out<<"???";
00551         #undef PRINTTKN
00552 }
00553 
00554 
00555 BTConstructor& parseBT(BTParser* p){
00556         return p->main();
00557 }
00558 
00559 BTParser* createBT(std::string filename){
00560         return new BTParser(filename);
00561 }
00562 
00563 void del(BTParser* p){ delete p; }
00564 
00565 
00566 #undef PRINT


decision_making_parser
Author(s):
autogenerated on Wed Aug 26 2015 11:16:57