Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2007 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #if !defined(MARSYAS_EX_PARSER_H) 00020 #define MARSYAS_EX_PARSER_H 00021 00022 #include <marsyas/expr/ExNode.h> 00023 #include <marsyas/expr/ExSymTbl.h> 00024 #include <marsyas/expr/ExScanner.h> 00025 #include <marsyas/sched/Scheduler.h> 00026 #include <marsyas/system/MarSystem.h> 00027 #include <marsyas/common_header.h> 00028 00029 #include <string> 00030 #include <iostream> 00031 #include <map> 00032 00033 namespace Marsyas { 00034 00035 class ExParser { 00036 private: 00037 int _EOF; 00038 int _tnatural; 00039 int _treal; 00040 int _tstr; 00041 int _tbool; 00042 int _tname; 00043 int _cname; 00044 int _rasgn; 00045 int _lasgn; 00046 int _addrasgn; 00047 int _subrasgn; 00048 int _mulrasgn; 00049 int _divrasgn; 00050 int _modrasgn; 00051 int _addlasgn; 00052 int _sublasgn; 00053 int _mullasgn; 00054 int _divlasgn; 00055 int _modlasgn; 00056 int _andrasgn; 00057 int _orrasgn; 00058 int _andlasgn; 00059 int _orlasgn; 00060 int _addop; 00061 int _subop; 00062 int _mulop; 00063 int _divop; 00064 int _modop; 00065 int _power; 00066 int _lbrkt; 00067 int _rbrkt; 00068 int _rlink; 00069 int _llink; 00070 int _notop; 00071 int _eqop; 00072 int _neop; 00073 int _gtop; 00074 int _geop; 00075 int _ltop; 00076 int _leop; 00077 int _andop; 00078 int _orop; 00079 int _exprbrk; 00080 int _blkstart; 00081 int _blkend; 00082 int _ifblk; 00083 int _atsym; 00084 int _propsep; 00085 int _lsbrkt; 00086 int _rsbrkt; 00087 int _colon; 00088 int _streamlib; 00089 int maxT; 00090 00091 Token *dummyToken; 00092 int errDist; 00093 int minErrDist; 00094 bool fail; 00095 00096 void SynErr(int n); 00097 void Get(); 00098 void Expect(int n); 00099 bool StartOf(int s); 00100 void ExpectWeak(int n, int follow); 00101 bool WeakSeparator(int n, int syFol, int repFol); 00102 00103 public: 00104 ExScanner *scanner; 00105 00106 Token *t; // last recognized token 00107 Token *la; // lookahead token 00108 00109 ExNode* tree; 00110 ExNode* getTree() { return tree; } 00111 00112 std::map<std::string,std::string> aliases_; 00113 ExSymTbl symbol_table; 00114 00115 MarSystem* marsystem_; 00116 Scheduler* scheduler_; 00117 TmTimer** timer_; 00118 00119 bool IsLAsgn()//{{{ 00120 { 00121 bool x=false; 00122 if (la->kind==_tname||la->kind==_cname) { 00123 Token* p = scanner->Peek(); 00124 x= (p->kind== _lasgn) 00125 || (p->kind==_addlasgn) 00126 || (p->kind==_sublasgn) 00127 || (p->kind==_mullasgn) 00128 || (p->kind==_divlasgn) 00129 || (p->kind==_modlasgn); 00130 scanner->ResetPeek(); 00131 } else if (la->kind==_streamlib) { // Stream 00132 if (scanner->Peek()->kind==_propsep) { // . 00133 if (scanner->Peek()->kind==_tname) { // name 00134 if (scanner->Peek()->kind==_lasgn) { // << 00135 x=true; 00136 } 00137 } 00138 } 00139 scanner->ResetPeek(); 00140 } else if (la->kind==_atsym) { 00141 x= scanner->Peek()->kind==_tname 00142 && scanner->Peek()->kind==_lasgn; 00143 scanner->ResetPeek(); 00144 } 00145 return x; 00146 }//}}} 00147 bool IsCNameRAsgnAlias() {//{{{ 00148 bool x=(la->kind==_cname) 00149 && (scanner->Peek()->kind==_rasgn) 00150 && (scanner->Peek()->kind==_atsym); 00151 scanner->ResetPeek(); 00152 return x; 00153 }//}}} 00154 bool IsLink()//{{{ 00155 { 00156 if (la->kind!=_cname) { return false; } 00157 Token* p = scanner->Peek(); 00158 bool x = (p->kind==_rlink) || (p->kind==_llink); 00159 scanner->ResetPeek(); 00160 return x; 00161 }//}}} 00162 bool in_colon()//{{{ 00163 { 00164 bool x=false; 00165 if (la->kind==_tname) { 00166 if (la->val[0]=='i'&&la->val[1]=='n'&&la->val[2]=='\0') { 00167 Token* p=scanner->Peek(); 00168 x=p->kind==_colon; 00169 } 00170 } 00171 scanner->ResetPeek(); 00172 return x; 00173 }//}}} 00174 std::string prep_string(std::string s)//{{{ 00175 { 00176 s=s.substr(1,s.length()-2); // remove quotes 00177 int c=0; bool f=false; 00178 for (unsigned int i=0; i<s.length(); ++i,++c) { 00179 if (f) { 00180 if (s[i]=='n') { c--; s[c]='\n'; } 00181 if (s[i]=='t') { c--; s[c]='\t'; } 00182 f=false; 00183 } else s[c]=s[i]; 00184 if (s[i]==92) { f=true; } 00185 } 00186 s=s.substr(0,c); 00187 return s; 00188 }//}}} 00189 00190 void Init()//{{{ 00191 { 00192 ExRecord* library=new ExRecord(); 00193 load_symbols(library); 00194 loadlib_timer(library,timer_); 00195 symbol_table.addTable(library); 00196 symbol_table.block_open(); 00197 }//}}} 00198 00199 ExNode* getFunctionCopy(std::string nm, ExNode* params)//{{{ 00200 { 00201 std::string key=construct_signature(nm, params); 00202 ExFun* f=symbol_table.getFunctionCopy(key); 00203 if (f!=NULL) { 00204 f->setParams(params); 00205 if (f->is_const()) { 00206 ExVal xx = f->eval(); 00207 ExNode* e = new ExNode(xx); 00208 delete(f); 00209 return e; 00210 } 00211 } else { 00212 MRSWARN("ExParser::getFunctionCopy unbound function call: "+key); 00213 } 00214 return f; 00215 }//}}} 00216 int getKind(std::string nm)//{{{ 00217 { 00218 ExRecord* r=symbol_table.getRecord(nm); 00219 return (r==NULL) ? 0 : r->getKind(); 00220 }//}}} 00221 std::string getType(std::string nm)//{{{ 00222 { 00223 ExRecord* r=symbol_table.getRecord(nm); 00224 return (r==NULL) ? "" : r->getType(); 00225 }//}}} 00226 std::string getElemType(std::string nm)//{{{ 00227 { 00228 ExRecord* r=symbol_table.getRecord(nm); 00229 return (r==NULL) ? "" : r->getElemType(); 00230 }//}}} 00231 std::string getDefaultLib(std::string typ)//{{{ 00232 { 00233 if (typ=="mrs_string") return "String"; 00234 if (typ=="mrs_real") return "Real"; 00235 if (typ=="mrs_natural") return "Natural"; 00236 if (typ=="mrs_bool") return "Bool"; 00237 if (typ=="mrs_timer") return "Timer"; 00238 int len=(int)typ.length(); 00239 if ((len>4)&&typ[len-1]=='t'&&typ[len-2]=='s'&&typ[len-3]=='i'&&typ[len-4]=='l'&&typ[len-5]==' ') return "List"; 00240 return ""; 00241 }//}}} 00242 00243 /****************************************************************************/ 00244 ExNode* expr_append(ExNode* u, ExNode* v)//{{{ 00245 { 00246 if (u==NULL) return v; 00247 ExNode* x=u; while (u->next!=NULL) { u=u->next; } u->next=v; 00248 return x; 00249 } //}}} 00250 std::string exprs_type(ExNode* es)//{{{ 00251 { 00252 if (es==NULL) return ""; 00253 while (es->next!=NULL) { es=es->next; } 00254 return es->getType(); 00255 } //}}} 00256 std::string construct_signature(std::string nm, ExNode* params)//{{{ 00257 { 00258 std::string key=nm; 00259 key+="("; 00260 ExNode* ps=params; 00261 while (ps!=NULL) { 00262 std::string tp=ps->getType(); 00263 key+=tp; 00264 if (tp=="mrs_natural") key+="|mrs_real"; 00265 if (ps->is_list()) key+="|mrs_list"; 00266 ps=ps->next; 00267 if (ps!=NULL) key+=","; 00268 } 00269 key+=")"; 00270 return key; 00271 } //}}} 00272 bool is_alias(std::string nm) { return (aliases_.find(nm) != aliases_.end()); } 00273 bool is_num(std::string n)//{{{ 00274 { 00275 for (unsigned int i=0; i<n.length(); ++i) { 00276 if (n[i]<'0'||n[i]>'9') return false; 00277 } 00278 return true; 00279 } //}}} 00280 ExNode* assignment(ExNode* u, ExRecord* r) {//{{{ 00281 std::string rt=r->getType(); std::string ut=u->getType(); 00282 if (rt=="mrs_real"&&ut=="mrs_natural") u=new ExNode_NaturalToReal(u); 00283 else if (rt=="mrs_natural"&&ut=="mrs_real") u=new ExNode_RealToNatural(u); 00284 if (rt==u->getType()) u=new ExNode_AsgnVar(u,r); 00285 else { 00286 MRSWARN("ExParser: Type mismatch in assignment: "+r->getType()+" << "+u->getType()); 00287 fail=true; u->deref(); return NULL; 00288 } 00289 return u; 00290 }//}}} 00291 ExNode* do_asgn(std::string nm, ExNode* u)//{{{ 00292 { 00293 if (is_alias(nm)) { return do_casgn(nm,u); } 00294 std::string t = getType(nm); 00295 // compare name type with u 00296 if (t=="") { // make a new variable in symbol table 00297 ExVal v = ExValTyped(T_VAR,u->getType()); 00298 symbol_table.setValue(v,nm); 00299 t=u->getType(); 00300 } 00301 ExRecord* r=symbol_table.getRecord(nm); 00302 return assignment(u,r); 00303 } //}}} 00304 ExNode* do_masgn(int atype, bool right_assign, std::string nm, ExNode* u)//{{{ 00305 { 00306 if (is_alias(nm)) { return do_cmasgn(atype,right_assign,nm,u); } 00307 // get name type, it must exist because we need read it 00308 std::string rt=getType(nm); 00309 if (rt=="") { 00310 MRSWARN("ExParser: Unbound name '"+nm+"'"); 00311 fail=true; u->deref(); return NULL; 00312 } 00313 ExRecord* r=symbol_table.getRecord(nm); 00314 ExNode* v=new ExNode_ReadVar(r,nm); 00315 if (!right_assign) { ExNode* a=u; u=v; v=a; } 00316 if (atype==OP_ADD||atype==OP_SUB) { u=do_addop(atype,u,v); } 00317 else if (atype==OP_MUL||atype==OP_DIV||atype==OP_MOD) { u=do_mulop(atype,u,v); } 00318 else { u=do_condop(atype,u,v); } 00319 if (u==NULL) return NULL; 00320 return assignment(u,r); 00321 }//}}} 00322 // assignment 00323 ExNode* do_alias(std::string anm, std::string cnm) { aliases_[anm]=cnm; return NULL; } 00324 ExNode* do_casgn(std::string nm, ExNode* u)//{{{ 00325 { 00326 if (is_alias(nm)) nm=aliases_[nm]; 00327 if (marsystem_->hasControl(nm)) { 00328 MarControlPtr p = marsystem_->getctrl(nm); 00329 // does p exist 00330 std::string t = p->getType(); 00331 std::string ut= u->getType(); 00332 // compare name type with u 00333 if (t=="mrs_real") { 00334 if (ut=="mrs_real") u=new ExNode_SetCtrlReal(nm,p,u); 00335 else if (ut=="mrs_natural") u=new ExNode_SetCtrlReal(nm,p,new ExNode_NaturalToReal(u)); 00336 else { 00337 MRSWARN("ExParser: Cannot assign type '"+ut+"' to "+t); 00338 fail=true; u->deref(); return NULL; 00339 } 00340 } 00341 else if (t=="mrs_natural") { 00342 if (ut=="mrs_natural") u=new ExNode_SetCtrlNatural(nm,p,u); 00343 else { 00344 MRSWARN("ExParser: Cannot setctrl type '"+ut+"' to "+t); 00345 fail=true; u->deref(); return NULL; 00346 } 00347 } 00348 else if (t=="mrs_bool"&&ut=="mrs_bool") { 00349 u=new ExNode_SetCtrlBool(nm,p,u); 00350 } 00351 else if (t=="mrs_string"&&ut=="mrs_string") { 00352 u=new ExNode_SetCtrlString(nm,p,u); 00353 } 00354 else { 00355 MRSWARN("ExParser: Unknown types in setctrl"); 00356 fail=true; u->deref(); return NULL; 00357 } 00358 } else { 00359 MRSWARN("ExParser: '"+nm+"' does not exist"); 00360 fail=true; u->deref(); return NULL; 00361 } 00362 return u; 00363 } //}}} 00364 ExNode* do_cmasgn(int atype, bool right_assign, std::string nm, ExNode* u)//{{{ 00365 { 00366 if (is_alias(nm)) nm=aliases_[nm]; 00367 ExNode* v=do_getctrl(nm); 00368 if (v==NULL) return NULL; 00369 if (!right_assign) { ExNode* a=u; u=v; v=a; } 00370 if (atype==OP_ADD||atype==OP_SUB) { u=do_addop(atype,u,v); } 00371 else if (atype==OP_MUL||atype==OP_DIV||atype==OP_MOD) { u=do_mulop(atype,u,v); } 00372 else { u=do_condop(atype,u,v); } 00373 if (u==NULL) return NULL; 00374 return do_casgn(nm,u); 00375 } //}}} 00376 ExNode* do_getctrl(std::string nm)//{{{ 00377 { 00378 if (marsystem_==NULL) { 00379 MRSWARN("ExParser: Control Name defined on NULL MarSystem"); 00380 fail=true; return NULL; 00381 } 00382 if (marsystem_->hasControl(nm)) { 00383 MarControlPtr ptr=marsystem_->getctrl(nm); 00384 std::string t=ptr->getType(); 00385 if (t=="mrs_bool") { return new ExNode_GetCtrlBool(nm,ptr); } 00386 else if (t=="mrs_string") { return new ExNode_GetCtrlString(nm,ptr); } 00387 else if (t=="mrs_natural") { return new ExNode_GetCtrlNatural(nm,ptr); } 00388 else if (t=="mrs_real") { return new ExNode_GetCtrlReal(nm,ptr); } 00389 } 00390 MRSWARN("ExParser: getctrl on '"+nm+"' failed."); 00391 fail=true; 00392 return NULL; 00393 }//}}} 00394 // operators 00395 ExNode* do_mulop(int m, ExNode* u, ExNode* v)//{{{ 00396 { 00397 std::string ut=u->getType(); std::string vt=v->getType(); 00398 std::string t=ut; 00399 if (ut=="mrs_real"&&vt=="mrs_natural") { v=new ExNode_NaturalToReal(v); vt="mrs_real"; } 00400 else if (vt=="mrs_real"&&ut=="mrs_natural") { u=new ExNode_NaturalToReal(u); ut="mrs_real"; t=ut; } 00401 00402 if (ut!="mrs_real"&&ut!="mrs_natural") { 00403 MRSWARN("ExParser::mult Expected mrs_real|mrs_natural types, got "+ut+" & "+vt); 00404 fail=true; u->deref(); v->deref(); return NULL; 00405 } 00406 ExNode* w=NULL; 00407 // check for const and evaluate if possible 00408 bool is_const = (u->is_const()&&v->is_const()); 00409 if (m==OP_MUL) { 00410 if (is_const) { w=new ExNode(u->value*v->value); } 00411 else { u=new ExNode_MUL(t,u,v); } 00412 } 00413 else if (m==OP_DIV) { 00414 if (is_const) { w=new ExNode(u->value/v->value); } 00415 else { u=new ExNode_DIV(t,u,v); } 00416 } 00417 else if (m==OP_MOD) { 00418 if (is_const) { w=new ExNode(u->value%v->value); } 00419 else { u=new ExNode_MOD(t,u,v); } 00420 } 00421 if (w!=NULL) { u->deref(); v->deref(); u=w; } 00422 return u; 00423 } //}}} 00424 ExNode* do_addop(int m, ExNode* u, ExNode* v)//{{{ 00425 { 00426 std::string ut=u->getType(); std::string vt=v->getType(); 00427 // first step conversion, so that u and t are of the same type 00428 if (ut=="mrs_real"&&vt=="mrs_natural") { v=new ExNode_NaturalToReal(v); vt="mrs_real"; } 00429 else if (vt=="mrs_real"&&ut=="mrs_natural") { u=new ExNode_NaturalToReal(u); ut="mrs_real"; } 00430 else if (m==OP_ADD) { 00431 if (ut=="mrs_string") { 00432 if (vt=="mrs_real") { 00433 if (v->is_const()) { v->setValue(dtos(v->getValue().toReal())); } 00434 else { v=new ExNode_RealToString(v); } 00435 } 00436 else if (vt=="mrs_natural") { 00437 if (v->is_const()) { v->setValue(ltos(v->getValue().toNatural())); } 00438 else { v=new ExNode_NaturalToString(v); } 00439 } 00440 else if (vt=="mrs_bool") { 00441 if (v->is_const()) { v->setValue(btos(v->getValue().toBool())); } 00442 else { v=new ExNode_NaturalToString(v); } 00443 } 00444 vt="mrs_string"; 00445 } 00446 else if (vt=="mrs_string") { 00447 if (ut=="mrs_real") { 00448 if (u->is_const()) { u->setValue(dtos(u->getValue().toReal())); } 00449 else { u=new ExNode_RealToString(u); } 00450 } 00451 else if (ut=="mrs_natural") { 00452 if (u->is_const()) { u->setValue(ltos(u->getValue().toNatural())); } 00453 else { u=new ExNode_NaturalToString(u); } 00454 } 00455 else if (ut=="mrs_bool") { 00456 if (u->is_const()) { u->setValue(btos(u->getValue().toBool())); } 00457 else { u=new ExNode_NaturalToString(u); } 00458 } 00459 ut="mrs_string"; 00460 } 00461 } 00462 bool is_const = (u->is_const()&&v->is_const()); 00463 ExNode* w=NULL; 00464 // type check operator 00465 bool list_t=false; 00466 if (u->is_list()&&v->is_list()) { 00467 if (ut==" list"&&vt!=" list") { ut=vt; } 00468 else if (vt==" list"&&ut!=" list") { vt=ut; } 00469 list_t=true; 00470 } 00471 if (ut==vt) { 00472 bool addable= 00473 ( ut=="mrs_real" 00474 || ut=="mrs_natural" 00475 || ut=="mrs_string" 00476 || list_t 00477 ); 00478 if (m==OP_ADD&&addable) { 00479 if (is_const) { w=new ExNode(u->getValue()+v->getValue()); } 00480 else { u=new ExNode_ADD(ut,u,v); } 00481 } 00482 else if (m==OP_SUB&&(ut=="mrs_real"||ut=="mrs_natural")) { 00483 if (is_const) { w=new ExNode(u->getValue()-v->getValue()); } 00484 else { u=new ExNode_SUB(ut,u,v); } 00485 } 00486 else { 00487 MRSWARN("ExParser: Invalid types to addop: "+ut+" and "+vt); 00488 fail=true; delete u; delete v; return NULL; 00489 } 00490 } 00491 else { 00492 MRSWARN("ExParser: Invalid types to addop: "+ut+" and "+vt); 00493 fail=true; delete u; delete v; return NULL; 00494 } 00495 if (w!=NULL) { delete u; delete v; u=w; } 00496 return u; 00497 } //}}} 00498 ExNode* do_num_negate(ExNode* u)//{{{ 00499 { 00500 if (u->getType()=="mrs_real") { 00501 if (u->is_const()) { (u->value).set(-(u->value).toReal()); } 00502 else { u=new ExNode_MathNeg_Real(u); } 00503 } else if (u->getType()=="mrs_natural") { 00504 if (u->is_const()) { (u->value).set(-(u->value).toNatural()); } 00505 else { u=new ExNode_MathNeg_Natural(u); } 00506 } else { 00507 MRSWARN("ExParser: Type mismatch in unary math negation operator"); 00508 fail=true; delete u; return NULL; 00509 } 00510 return u; 00511 } //}}} 00512 ExNode* do_relop(int m, ExNode* u, ExNode* v)//{{{ 00513 { 00514 if (u->getType()!=v->getType()) { 00515 MRSWARN("ExParser: Type mismatch to relational operator."); 00516 fail=true; delete u; delete v; 00517 return NULL; 00518 } 00519 bool is_const = (u->is_const()&&v->is_const()); 00520 if (m==OP_EQ) { 00521 printf("@ eq\n"); 00522 if (is_const) { ExVal a=u->value == v->value; u->deref(); v->deref(); u=new ExNode(a); } 00523 else { u=new ExNode_EQ("mrs_bool",u,v); } 00524 } 00525 else if (m==OP_NE) { 00526 if (is_const) { ExVal a=u->value != v->value; u->deref(); v->deref(); u=new ExNode(a); } 00527 else { u=new ExNode_NE("mrs_bool",u,v); } 00528 } 00529 else if (m==OP_GT) { 00530 if (is_const) { ExVal a=u->value > v->value; u->deref(); v->deref(); u=new ExNode(a); } 00531 else { u=new ExNode_GT("mrs_bool",u,v); } 00532 } 00533 else if (m==OP_GE) { 00534 if (is_const) { ExVal a=u->value >= v->value; u->deref(); v->deref(); u=new ExNode(a); } 00535 else { u=new ExNode_GE("mrs_bool",u,v); } 00536 } 00537 else if (m==OP_LT) { 00538 if (is_const) { ExVal a=u->value < v->value; u->deref(); v->deref(); u=new ExNode(a); } 00539 else { u=new ExNode_LT("mrs_bool",u,v); } 00540 } 00541 else if (m==OP_LE) { 00542 if (is_const) { ExVal a=u->value <= v->value; u->deref(); v->deref(); u=new ExNode(a); } 00543 else { u=new ExNode_LE("mrs_bool",u,v); } 00544 } 00545 return u; 00546 } //}}} 00547 ExNode* do_bool_negate(ExNode* v)//{{{ 00548 { 00549 if (v->is_const()) { (v->value).set(!(v->value).toBool()); } 00550 else v=new ExNode_BoolNeg(v); 00551 return v; 00552 } //}}} 00553 ExNode* do_condop(int o, ExNode* u, ExNode* v)//{{{ 00554 { 00555 if (u->getType()=="mrs_bool"&&v->getType()=="mrs_bool") { 00556 if (u->is_const()&&v->is_const()) { 00557 if (o==OP_AND) { u->value.set(u->value.toBool() && v->value.toBool()); } 00558 else { u->value.set(u->value.toBool() || v->value.toBool()); } 00559 delete v; 00560 } 00561 else if (o==OP_AND) u=new ExNode_AND("mrs_bool",u,v); 00562 else u=new ExNode_OR("mrs_bool",u,v); 00563 } 00564 else { 00565 MRSWARN("ExParser: Types to relational operator must bool."); 00566 fail=true; delete u; delete v; u=NULL; 00567 } 00568 return u; 00569 } //}}} 00570 ExNode* do_conditional(ExNode* cond, ExNode* ts, ExNode* es)//{{{ 00571 { 00572 if (exprs_type(cond)!="mrs_bool") { 00573 MRSWARN("ExParser: Condition in conditional statement must be of type bool"); 00574 fail=true; delete cond; delete ts; delete es; 00575 return NULL; 00576 } 00577 std::string tt=exprs_type(ts); 00578 std::string et=exprs_type(es); 00579 if (et!=tt||tt.length()==0||et.length()==0) { 00580 MRSWARN("ExParser: Type Mismatch in function"); 00581 fail=true; delete cond; delete ts; delete es; 00582 return NULL; 00583 } 00584 return new ExNode_Conditional(tt,cond,ts,es); 00585 } //}}} 00586 ExNode* do_link(std::string f, std::string t)//{{{ 00587 { 00588 if (marsystem_==NULL) { 00589 MRSWARN("ExParser: Control Name defined on NULL MarSystem"); 00590 fail=true; return NULL; 00591 } 00592 if (marsystem_->hasControl(f)&&marsystem_->hasControl(t)) { 00593 MarControlPtr pf = marsystem_->getctrl(f); 00594 MarControlPtr pt = marsystem_->getctrl(t); 00595 if (pf.isInvalid()||pt.isInvalid()) { 00596 MRSWARN("ExParser: Cannot link controls '"+f+"' -> '"+t+"'"); 00597 fail=true; return NULL; 00598 } 00599 if (pf->getType()!=pt->getType()) { 00600 MRSWARN("ExParser: linkctrl type mismatch between '"+f+"' -> '"+t+"'"); 00601 fail=true; return NULL; 00602 } 00603 std::string tp = marsystem_->getctrl(f)->getType(); 00604 return new ExNode_Link(pf,pt,tp); 00605 } 00606 MRSWARN("ExParser: Link controls '"+f+"' -> '"+t+"' failed."); 00607 fail=true; return NULL; 00608 }//}}} 00609 ExNode* do_name(bool is_fun, std::string key, ExNode* params)//{{{ 00610 { 00611 (void) is_fun; // FIXME Unused parameter 00612 if (is_alias(key)) return do_getctrl(aliases_[key]); 00613 int kind=getKind(key); ExNode* u=NULL; 00614 if (kind==T_FUN) { 00615 u=getFunctionCopy(key,params); 00616 } 00617 else if (kind==T_VAR||kind==T_CONST) { 00618 ExRecord* nd=symbol_table.getRecord(key); 00619 u=new ExNode_ReadVar(nd,key); 00620 } 00621 if (u==NULL) { 00622 MRSWARN("ExParser::do_name("+ltos(la->col)+") Unbound name '"+key+"'"); 00623 fail=true; delete params; return NULL; 00624 } 00625 return u; 00626 } //}}} 00627 ExNode* do_property(ExNode* u, std::string key, ExNode* params)//{{{ 00628 { 00629 if (u!=NULL) { 00630 key=getDefaultLib(u->getType())+"."+key; 00631 u->next=params; params=u; u=NULL; 00632 } 00633 int kind=getKind(key); 00634 if (kind==T_CONST) { 00636 if (params!=NULL) { 00637 MRSWARN("ExParser::property parameters supplied to non-function call: "+key); 00638 delete params; delete u; fail=true; return NULL; 00639 } 00640 ExVal v=symbol_table.getValue(key); 00641 u=new ExNode(v); 00642 } else if (kind==T_VAR) { 00644 if (params!=NULL) { 00645 MRSWARN("ExParser::property parameters supplied to non-function call: "+key); 00646 delete params; delete u; fail=true; return NULL; 00647 } 00648 ExRecord* r=symbol_table.getRecord(key); 00649 u=new ExNode_ReadVar(r,key); 00650 } else if (kind==T_FUN) { 00651 u=getFunctionCopy(key,params); 00652 if (u==NULL) { 00653 // MRSWARN("ExParser::property unbound function call: "+key); 00654 params->deref(); fail=true; return NULL; 00655 } 00656 } else { 00657 MRSWARN("ExParser::property unbound name: "+key); 00658 delete u; delete params; fail=true; u=NULL; 00659 } 00660 return u; 00661 }//}}} 00662 ExNode* do_getelem(ExNode* u, ExNode* lidx, ExNode* ridx, bool is_range)//{{{ 00663 { 00664 if (!u->is_seq()) { 00665 MRSWARN("ExParser::getelem not a sequence type"); 00666 fail=true; u->deref(); lidx->deref(); 00667 if (ridx)ridx->deref(); return NULL; 00668 } 00669 // int kind=u->getKind(); 00670 // if (kind==T_VAR||kind==T_CONST) { 00671 if (is_range) u=new ExNode_Range(u,lidx,ridx); 00672 else u=new ExNode_GetElem(u,lidx); 00673 // } 00674 return u; 00675 }//}}} 00676 ExNode* do_setelem(std::string key, ExNode* lidx, ExNode* ridx, bool is_range, ExNode* u)//{{{ 00677 { 00678 if (getKind(key)==T_VAR) { 00679 ExRecord* nd=symbol_table.getRecord(key); 00680 if (nd==NULL) { 00681 MRSWARN("ExParser::setelem unbound name "+key); 00682 u->deref(); lidx->deref(); if(ridx)ridx->deref(); fail=true; u=NULL; 00683 } else if (nd->is_seq()) { 00684 if (nd->getElemType()==u->getType()) { 00685 if (is_range) { 00686 MRSWARN("ExParser::setelem setting element as range not supported"); 00687 u->deref(); u=NULL; lidx->deref(); if(ridx)ridx->deref(); fail=true; 00688 } else { 00689 u=new ExNode_SetElem(nd,lidx,u); 00690 } 00691 } else { 00692 MRSWARN("ExParser::setelem type mismatch in setelem"); 00693 u->deref(); u=NULL; lidx->deref(); if(ridx)ridx->deref(); fail=true; 00694 } 00695 } else { 00696 MRSWARN("ExParser::setelem not a sequence type"); 00697 fail=true; u->deref(); u=NULL; lidx->deref(); if(ridx)ridx->deref(); 00698 } 00699 } 00700 return u; 00701 }//}}} 00702 ExNode* do_msetelem(std::string key, ExNode* lidx, ExNode* ridx, bool is_range, bool right_assign, int atype, ExNode* u)//{{{ 00703 { 00704 // get name type, it must exist because we need read it 00705 std::string rt=getElemType(key); 00706 if (rt=="") { 00707 MRSWARN("ExParser: Unbound name '"+key+"'"); 00708 fail=true; u->deref(); return NULL; 00709 } 00710 ExNode* v=NULL; 00711 ExRecord* nd=symbol_table.getRecord(key); 00712 if (nd==NULL) { 00713 MRSWARN("ExParser::getelem unbound name "+key); fail=true; 00714 } else { 00715 v=do_getelem(new ExNode_ReadVar(nd,key),lidx,ridx,is_range); 00716 } 00717 00718 if (v!=NULL) { 00719 if (!right_assign) { ExNode* a=u; u=v; v=a; } 00720 if (atype==OP_ADD||atype==OP_SUB) { u=do_addop(atype,u,v); } 00721 else if (atype==OP_MUL||atype==OP_DIV||atype==OP_MOD) { u=do_mulop(atype,u,v); } 00722 else { u=do_condop(atype,u,v); } 00723 if (u==NULL) return NULL; 00724 return do_setelem(key,lidx,ridx,is_range,u); 00725 } 00726 return NULL; 00727 }//}}} 00728 ExNode* list_append(ExNode* u, ExNode* v)//{{{ 00729 { 00730 if (u==NULL) return v; 00731 if (u->getType()!=v->getType()) { 00732 MRSWARN("ExParser::list_append type mismatch in list declaration"); 00733 u->deref(); v->deref(); fail=true; return NULL; 00734 } 00735 ExNode* x=u; while (u->next!=NULL) { u=u->next; } u->next=v; 00736 return x; 00737 }//}}} 00738 ExNode* do_list(bool is_empty, ExNode* u)//{{{ 00739 { 00740 if (is_empty) { return new ExNode(ExVal(0,NULL)); } 00741 mrs_natural len=0; ExNode* x=u; while (x!=NULL) { len++; x=x->next; } 00742 ExNode** elems=new ExNode*[len]; 00743 int l=0; x=u; while (x!=NULL) { ExNode* y=x; elems[l]=x; l++; x=x->next; y->next=NULL; } 00744 return new ExNode(ExVal(len,(ExNode**)elems)); 00745 }//}}} 00746 ExNode* do_iter(int iter_type, std::string var_nm, std::string ary_nm, ExNode* list, ExNode* exprs)//{{{ 00747 { 00748 ExRecord* var=symbol_table.getRecord(var_nm); 00749 if (list && !list->is_seq()) { 00750 MRSWARN("ExParser::iterator Expected sequence type to iterator"); 00751 list->deref(); exprs->deref(); 00752 fail=true; 00753 return NULL; 00754 } 00755 ExNode* e=NULL; 00756 if (iter_type==1) { // map 00757 if (list->getType()=="mrs_string") { 00758 e=new ExNode_StringMap(list,var,exprs,"mrs_string"); 00759 } else { 00760 std::string rt=exprs_type(exprs)+" list"; 00761 e=new ExNode_IterMap(list,var,exprs,rt); 00762 } 00763 } 00764 else if (iter_type==2) { // iter 00765 // note that list is null in this case, ary_nm is key to the list 00766 ExRecord* original=symbol_table.getRecord(ary_nm); 00767 if (original->getType()=="mrs_string") { 00768 e=new ExNode_StringIter(original,var,exprs); 00769 } else { 00770 if (original==NULL) { 00771 if (exprs) exprs->deref(); 00772 } 00773 e=new ExNode_IterIter(original,var,exprs); 00774 } 00775 } 00776 else if (iter_type==3) { // for 00777 if (list->getType()=="mrs_string") { 00778 e=new ExNode_StringFor(list,var,exprs); 00779 } else { 00780 e=new ExNode_IterFor(list,var,exprs); 00781 } 00782 } 00783 else if (iter_type==4) { // rfor 00784 if (list->getType()=="mrs_string") { 00785 e=new ExNode_StringRFor(list,var,exprs); 00786 } else { 00787 e=new ExNode_IterRFor(list,var,exprs); 00788 } 00789 } 00790 return e; 00791 }//}}} 00792 00793 /******************************************************************/ 00794 00795 00796 ExParser(TmTimer** t, ExScanner *scanner); 00797 ~ExParser(); 00798 void SemErr(char* msg); 00799 00800 void Alias(std::string& nm); 00801 void Name(std::string& nm); 00802 void CName(std::string& nm); 00803 void AddOp(int& m); 00804 void MulOp(int& m); 00805 void RelOp(int& m); 00806 void LAsgnOp(int& type); 00807 void RAsgnOp(int& type); 00808 void Exprs(ExNode** u); 00809 void Task(ExNode** u); 00810 void LAsgn(ExNode** u); 00811 void Link(ExNode** u); 00812 void RAsgn(ExNode** u); 00813 void Condition(ExNode** u); 00814 void CondTerm(ExNode** u); 00815 void CondFact(ExNode** u); 00816 void Expr(ExNode** u); 00817 void Term(ExNode** u); 00818 void Property(ExNode** u); 00819 void Factor(std::string& l, ExNode** u); 00820 void ListElems(ExNode** u); 00821 void Sequence(std::string& l, ExNode** u); 00822 void ElemAccess(ExNode** u); 00823 void FactorB(std::string& l, ExNode** u); 00824 void Elem(ExNode*& idx); 00825 void Use(); 00826 void Load(); 00827 void UL(); 00828 void Neil(); 00829 00830 void Parse(); 00831 void Parse(Scheduler* v, MarSystem* m, ExRecord* est); 00832 00833 }; // end ExParser 00834 00835 }; // namespace 00836 00837 #endif // !defined(MARSYAS_EX_PARSER_H) 00838