void parseTuple( POETCode* elemType) { POETList* elemTypeList = dynamic_cast<POETList*>(elemType); if (elemTypeList==0) { std::cerr << "expecting a list but get : " << elemType->toString() << "\n"; assert(0); } POETCode* start = eval_AST(elemTypeList->get_first()); if (start != EMPTY) apply(start,EMPTY); POETCode* result = 0; POETList *p = dynamic_cast<POETList*>(elemTypeList->get_rest()); while (p != 0 && p->get_rest() != 0) { POETCode* cur = p->get_first(); p = dynamic_cast<POETList*>(p->get_rest()); assert(p != 0); POETCode* sep = eval_AST(p->get_first()); apply(cur, sep); result = fac->append_tuple(result, res); p = dynamic_cast<POETList*>(p->get_rest()); } if (p != 0) { apply(p->get_first(), fullmatch); if (fullmatch != 0) fullmatch = EMPTY; } res = result; }
extern "C" void* strip_listSingle(POETCode* item) { if (item->get_enum() == SRC_LIST) { POETList* l = static_cast<POETList*>(item); if (l->get_rest() == 0) return l->get_first(); } return item; }
POETCode* EraseTrace(POETCode* vars, POETCode* res) { std::vector<LocalVar*> vec; switch (vars->get_enum()) { case SRC_LVAR: { vars = eval_AST(vars); if (vars->get_enum() != SRC_LVAR) break; LocalVar* lvar = static_cast<LocalVar*>(vars); if (lvar->get_entry().get_entry_type() == LVAR_TRACE) vec.push_back(lvar); break; } case SRC_LIST: { POETList* l = static_cast<POETList*>(vars); while (l != 0) { POETCode* cur = l->get_first(); if (cur->get_enum() == SRC_LVAR) { cur = eval_AST(cur); if (cur->get_enum() == SRC_LVAR) { LocalVar* cur_lvar = static_cast<LocalVar*>(cur); if (cur_lvar->get_entry().get_entry_type() == LVAR_TRACE) vec.push_back(cur_lvar); } } l = dynamic_cast<POETList*>(l->get_rest()); } } break; default: return res; } int size = vec.size(); if (size == 0) return res; for (int i = size-1; i >= 0; --i) { LvarSymbolTable::Entry e = vec[i]->get_entry(); assert (e.get_entry_type() == LVAR_TRACE); e.set_entry_type(LVAR_TRACE_OUTDATE); } res = ReplInfoVisitor().apply(res); for (int i = size-1; i >= 0; --i) { LvarSymbolTable::Entry e = vec[i]->get_entry(); e.set_entry_type(LVAR_TRACE); } return res; }
POETCode* RemoveSpaceFromList(POETCode* r) { POETList* l = dynamic_cast<POETList*>(r); if (l != 0) { POETCode* lFirst = l->get_first(), *lRest = l->get_rest(); POETCode* r1 = RemoveSpaceFromList(lFirst); if (lRest == 0) return r1; if (r1 == EMPTY) return RemoveSpaceFromList(lRest); POETCode* r2 = RemoveSpaceFromList(lRest); if (r2 == EMPTY) return r1; return ASTFactory::inst()->new_list(r1,r2); } else if (r->get_enum() == SRC_STRING) { std::string c = static_cast<POETString*>(r)->get_content(); if (IS_SPACE(c)) return EMPTY; return r; } return r; }
void apply (POETCode* output) { while (output != 0) { POETList* outputList = dynamic_cast<POETList*>(output); if (outputList != 0) { apply(outputList->get_first()); output = outputList->get_rest(); } else { if (output->get_enum() == SRC_STRING) { out << output->toString(OUTPUT_NO_DEBUG); } else { POETCode* res = eval_AST(output); res->visit(this); } output = 0; } } }
POETCode* TraceEval(POETCode* vars, POETCode* res) { std::vector<LocalVar*> vec; switch (vars->get_enum()) { case SRC_LVAR: { LocalVar* lvar = static_cast<LocalVar*>(vars); vec.push_back(lvar); break; } case SRC_LIST: { POETList* l = static_cast<POETList*>(vars); while (l != 0) { POETCode* cur = l->get_first(); if (cur->get_enum() != SRC_LVAR) INCORRECT_TRACE_HANDLE(cur->toString()); vec.push_back(static_cast<LocalVar*>(cur)); l = dynamic_cast<POETList*>(l->get_rest()); } } break; default: INCORRECT_TRACE_HANDLE(vars->toString()); } for (int i = vec.size()-1; i >= 0; --i) { LocalVar* lvar = vec[i]; LvarSymbolTable::Entry entry = lvar->get_entry(); entry.push(true); entry.set_entry_type(LVAR_TRACE); } res = eval_AST(res); for (int i = vec.size()-1; i >= 0; --i) { LocalVar* lvar = dynamic_cast<LocalVar*>(vec[i]); assert(lvar != 0); LvarSymbolTable::Entry entry = lvar->get_entry(); POETCode* val = entry.get_code(); entry.pop(); entry.set_code(val); } return res; }
void ReadFiles(POETCode* _files, LexState _lexStateStart, std::list<POETProgram*>& resultFiles) { POETCode* files = eval_AST(_files); POETCode* p_files=files; while (p_files != 0) { POETList* fileList = dynamic_cast<POETList*>(p_files); POETCode* fileCur = p_files; if (fileList != 0) { fileCur = fileList->get_first(); p_files=fileList->get_rest(); } else p_files = 0; std::string fname= fileCur->toString(OUTPUT_NO_DEBUG); if (fname == "") { std::cerr << "Empty file name: " << fileCur->toString() << " from list " << files->toString() << "\n"; } lexState = _lexStateStart; POETProgram* programFile = process_file(fname.c_str()); resultFiles.push_back(programFile); lexState=LEX_DEFAULT; } }
virtual void visitList(POETList* v2) { POETCode* v2Tail = v2->get_rest(); if (v2Tail == 0) { apply(v2->get_first(), fullmatch); if (fullmatch != 0) fullmatch=EMPTY; res = fac->new_list(res, 0); return; } //if (r1->get_enum() != SRC_LIST) PARSE_MISMATCH(r1,v2,lineno); assert (v2Tail->get_enum() == SRC_LIST); POETCode* v2Head=v2->get_first(); POETCode* v2Second = static_cast<POETList*>(v2Tail)->get_first(); POETCode* v2SecondTail = static_cast<POETList*>(v2Tail)->get_rest(); POETCode *sep = EMPTY, *after_first = v2Tail; if ( v2Head->get_enum() != SRC_STRING && get_matchEnum(v2Second) == SRC_STRING) { sep = v2Second; after_first = v2SecondTail; } POETCode* _r1 = r1; POETCode* res1 = apply(v2->get_first(), sep); if (after_first == 0) { if ( r1 == 0 || r1 == EMPTY || fullmatch != 0) { res = fac->new_list(res1, 0); return; } r1 = _r1; PARSE_MISMATCH(_r1, v2,lineno); } try { POETList* l = dynamic_cast<POETList*>(after_first); if (l != 0 && l->get_rest() == 0) after_first = l->get_first(); apply(after_first, fullmatch); if (fullmatch != 0) fullmatch=EMPTY; } catch (ParseError err) { r1 = _r1; throw err; } res = fac->new_list(res1, 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; } }