unsigned EvaluatePOET:: compute_exp_lookahead(std::vector<POETCode*>& res) { res.push_back(fac->new_string("(")); if (exp_item->get_entry().get_code() == 0) SYM_UNDEFINED("EXP_BASE"); compute_lookaheadInfo(exp_item->get_entry().get_code(), res); POETCode* uop = exp_uop->get_entry().get_code(); while (uop != 0) { res.push_back(get_head(uop)); uop = get_tail(uop); } return 1; }
unsigned POETTypeTor:: compute_lookaheadInfo(EvaluatePOET* op, std::vector<POETCode*>& res, unsigned need) { int size = args.size(); unsigned len = -1; for (int i = 0; i < size; ++i) { unsigned curlen = compute_lookaheadInfo(op, i,need); if (len > curlen) len = curlen; ParseInfo& cur = parseInfo[i]; for (unsigned i = 0; i < cur.filter.size(); ++i) { res.push_back(cur.filter[i]); } } return len; }
POETCode* POETTypeTor::get_parseInfo(EvaluatePOET* op, POETCode* r1) { /*QY: compute and set parsing information*/ int size = args.size(); for (int i = 0; i < size-1; ++i) { compute_lookaheadInfo(op, i, 1); ParseInfo& cur = parseInfo[i]; if (cur.lookahead == 0) LOOKAHEAD_EMPTY(args[i]); assert(cur.filter.size() > 0); for (int j = 0; j < cur.filter.size(); ++j) { POETCode* cur_filter = cur.filter[j]; if (op->match_lookahead(r1, cur_filter)) return args[i]; } } return args[size-1]; }
/*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; } }