virtual void visitLocalVar(LocalVar* var) { LvarSymbolTable::Entry e = var->get_entry(); POETCode *restr = e.get_restr(); if (restr == 0) { CollectInfoVisitor::visitLocalVar(var); return; } if (restr->get_enum() == SRC_CVAR) { CodeVar* cvar = static_cast<CodeVar*>(restr); POETCode* code = e.get_code(); if (code!=0 && !match_AST(code, cvar,MATCH_AST_EQ)) { CodeVar* tmp = ASTFactory::inst()->new_codeRef(cvar->get_entry(), code); tmp->visit(this); return; } } else if (restr->get_enum() == SRC_OP) { POETOperator* op = static_cast<POETOperator*>(restr); if (op->get_op() == POET_OP_LIST || op->get_op()==POET_OP_LIST1) { POETCode* _listsep = listsep; CodeVar* _listelem = listelem; int save = align; align = start_pos; listsep = op->get_arg(1); listelem=dynamic_cast<CodeVar*>(op->get_arg(0)); CollectInfoVisitor::visitLocalVar(var); align = save; listsep = _listsep; listelem = _listelem; return; } } CollectInfoVisitor::visitLocalVar(var); }
virtual void visitCodeVar(CodeVar* v) { try { POETCode* _listsep = listsep; CodeVar* _listelem = listelem; POETCode* result = v->invoke_output(v->get_args()); if (result != 0 && result != v) { listsep = 0; listelem=0; result->visit(this); listsep = _listsep; listelem=_listelem; return; } CvarSymbolTable::Entry e = v->get_entry(); LvarSymbolTable *local = 0; POETCode* f = 0; POETCode *parse = e.get_parse(); if (parse != 0 && parse->get_enum()==SRC_OP) { POETOperator* op = static_cast<POETOperator*>(parse); if (op->get_op() == POET_OP_LIST || op->get_op()==POET_OP_LIST1) { listsep = op->get_arg(1); listelem=dynamic_cast<CodeVar*>(op->get_arg(0)); f = v->get_args(); } } if (f == 0) { listsep = 0; listelem=0; f = e.get_code(); if (f == 0) { if (parse==0) { CODE_SYNTAX_UNDEFINED(v->toString()); } else f = v->get_args(); } else { local = e.get_symTable(); if (local != 0) local->push_table(false); POETCode* pars = e.get_param(); if (pars != 0 && !match_parameters(pars, v->get_args(),MATCH_PAR_MOD_CODE)) CVAR_MISMATCH(v,pars, v->get_args()); v->set_attr(); } } if (f == 0) { CODE_SYNTAX_UNDEFINED(v->toString()); } int save = align; align = start_pos; f->visit(this); align = save; if (local != 0) local->pop_table(); listsep = _listsep; listelem=_listelem; } catch (Error err) { std::cerr << " From unparsing code template " << SHORT(v->toString(),500) << "\n"; throw err; } }
POETCode* eval_cvar_access(CodeVar* cv, POETCode* access) { POETCode* res = 0; CvarSymbolTable::Entry cv_e = cv->get_entry(); LvarSymbolTable* symTable = cv_e.get_symTable(); symTable->push_table(true); /* push symbol table for evaluation of access*/ if (access->get_enum() != SRC_LVAR) access= apply(access); switch (access->get_enum()) { case SRC_LVAR: { cv->get_entry().get_symTable()->pop_table(); LocalVar* lv = static_cast<LocalVar*>(access); res = eval_cvar_attr(cv, lv); if (res == 0) { CVAR_ACC_MISMATCH( cv,access); } break; } case SRC_OP: { POETOperator* op = static_cast<POETOperator*>(access); if (op->get_op() == TYPE_TOR) { cv->get_entry().get_symTable()->pop_table(); for (int i = 0; i < op->numOfArgs(); ++i) { POETCode* cur = apply(op->get_arg(i)); LocalVar* lv = dynamic_cast<LocalVar*>(cur); if (lv == 0) { CVAR_ACC_MISMATCH( cv,access); } res = eval_cvar_attr(cv, lv); if (res != 0) return res; } CVAR_ACC_MISMATCH( cv,access); } } default: if (cv->get_args() != 0) CVAR_ACC_MISMATCH( cv, access); /*QY: access is used to set optional attribute values of code template; return a new code template object with the given attribute*/ res = ASTFactory::inst()->build_codeRef(cv->get_entry(),0); cv->get_entry().get_symTable()->pop_table(); break; } return res; }
/*QY: return the min length of tokens placed in the filter res*/ unsigned EvaluatePOET:: compute_lookaheadInfo(POETCode* cur, std::vector<POETCode*>& res, unsigned need) { try { assert(cur != 0); switch (cur->get_enum()) { case SRC_TYPE: if (cur != ANY) { res.push_back(cur); return 1; } return 0; case SRC_STRING: if (cur != EMPTY) { res.push_back(cur); return 1; } return 0; case SRC_ICONST: res.push_back(cur); res.push_back(AST2String(cur)); return 1; case SRC_CVAR: { CodeVar* cvar = static_cast<CodeVar*>(cur); POETCode* parse=cvar->get_parseInfo(); unsigned lookahead = cvar->get_entry().get_lookahead(); if (need < lookahead) need = lookahead; if (parse != EMPTY) { unsigned len = compute_lookaheadInfo(parse, res, need); if (lookahead > 1 && len < lookahead) { LOOKAHEAD_AMBIGUOUS(cvar); return 0; } return len; } res.push_back(cvar); /*QY: the code var is a token */ return 1; } case SRC_LVAR: { LocalVar* lvar = static_cast<LocalVar*>(cur); POETCode* restr = 0; switch (lvar->get_entry().get_entry_type()) { case LVAR_CODEPAR: case LVAR_ATTR: restr = lvar->get_entry().get_restr(); break; default: restr = lvar->get_entry().get_code(); break; } if (restr == 0) { LOOKAHEAD_AMBIGUOUS(cur); return 0; } else return compute_lookaheadInfo(restr,res,need); } case SRC_LIST: { POETList* curlist = static_cast<POETList*>(cur); int curstart = res.size(); unsigned len = compute_lookaheadInfo(curlist->get_first(),res,need); cur = curlist->get_rest(); if (cur == 0) return len; int cursize = res.size(); if (need == 1) { if (len == 0) return compute_lookaheadInfo(cur, res, need); return len; } if (len < need ) { std::vector<POETCode*> tailres; unsigned len2 = compute_lookaheadInfo(cur, tailres, need-len); ASTFactory* fac = ASTFactory::inst(); for (int i = curstart; i < cursize; ++i) { POETCode* first = res[i]; res[i] = fac->append_tuple(first,tailres[0]); for (unsigned j = 1; j < tailres.size(); ++j) res.push_back(fac->append_tuple(first,tailres[j])); } return len+len2; } return len; } case SRC_OP : { POETOperator* op = static_cast<POETOperator*>(cur); switch(op->get_op()) { case TYPE_TOR: { POETTypeTor* tor = static_cast<POETTypeTor*>(cur); return tor->compute_lookaheadInfo(this, res, need); } case POET_OP_LIST1: case TYPE_LIST1: return compute_lookaheadInfo(op->get_arg(0),res,need); case POET_OP_LIST: case TYPE_LIST: compute_lookaheadInfo(op->get_arg(0),res); return 0; case POET_OP_EXP: return compute_exp_lookahead(res); default: LOOKAHEAD_AMBIGUOUS(cur); return 0; } } default: LOOKAHEAD_AMBIGUOUS(cur); return 0; } } catch (Error err) { std::cerr << " From computing filter information for " << cur->toString() << "\n"; throw err; } }