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