00001
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
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
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
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
00138
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
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
00505 while(not tokens.eof()){
00506 Token t; tokens>>t;
00507 PRINT(t);
00508 }
00509 }
00510 if(true){
00511 while( bt(tokens) );
00512
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