📄 code.cc
字号:
} if (y->depth < x->depth) { x->depth = y->depth; } } } if (x->depth == k) { do { (*--top)->depth = cInfinity; (*top)->link = x; } while (*top != x); }}static bool state_is_in_non_trivial_SCC(const State* s){ // does not link to self if (s->link != s) { return true; } // or exists i: (s->go.spans[i].to->link == s) // // Note: (s->go.spans[i].to == s) is allowed, corresponds to s // looping back to itself. // for (uint i = 0; i < s->go.nSpans; ++i) { const State* t = s->go.span[i].to; if (t && t->link == s) { return true; } } // otherwise no return false;}uint maxDist(State *s){ if (s->depth != cInfinity) { // Already calculated, just return result. return s->depth; } uint mm = 0; for (uint i = 0; i < s->go.nSpans; ++i) { State *t = s->go.span[i].to; if (t) { uint m = 1; if (!t->link) // marked as non-key state { if (t->depth == cInfinity) { t->depth = maxDist(t); } m += t->depth; } if (m > mm) { mm = m; } } } s->depth = mm; return mm;}void calcDepth(State *head){ State* s; // mark non-key states by s->link = NULL ; for (s = head; s; s = s->next) { if (s != head && !state_is_in_non_trivial_SCC(s)) { s->link = NULL; } //else: key state, leave alone } for (s = head; s; s = s->next) { s->depth = cInfinity; } // calculate max number of transitions before guarantied to reach // a key state. for (s = head; s; s = s->next) { maxDist(s); }}void DFA::findSCCs(){ SCC scc(nStates); State *s; for (s = head; s; s = s->next) { s->depth = 0; s->link = NULL; } for (s = head; s; s = s->next) { if (!s->depth) { scc.traverse(s); } } calcDepth(head);}void DFA::split(State *s){ State *move = new State; (void) new Move(move); addState(&s->next, move); move->link = s->link; move->rule = s->rule; move->go = s->go; s->rule = NULL; s->go.nSpans = 1; s->go.span = new Span[1]; s->go.span[0].ub = ubChar; s->go.span[0].to = move;}void DFA::findBaseState(){ Span *span = new Span[ubChar - lbChar]; for (State *s = head; s; s = s->next) { if (!s->link) { for (uint i = 0; i < s->go.nSpans; ++i) { State *to = s->go.span[i].to; if (to && to->isBase) { to = to->go.span[0].to; uint nSpans = merge(span, s, to); if (nSpans < s->go.nSpans) { delete [] s->go.span; s->go.nSpans = nSpans; s->go.span = new Span[nSpans]; memcpy(s->go.span, span, nSpans*sizeof(Span)); } break; } } } } delete [] span;}void DFA::emit(std::ostream &o, uint ind){ State *s; uint i, bitmap_brace = 0; findSCCs(); head->link = head; uint nRules = 0; for (s = head; s; s = s->next) { s->depth = maxDist(s); if (maxFill < s->depth) { maxFill = s->depth; } if (s->rule && s->rule->accept >= nRules) { nRules = s->rule->accept + 1; } } uint nSaves = 0; uint *saves = new uint[nRules]; memset(saves, ~0, (nRules)*sizeof(*saves)); // mark backtracking points bool bSaveOnHead = false; for (s = head; s; s = s->next) { if (s->rule) { for (i = 0; i < s->go.nSpans; ++i) { if (s->go.span[i].to && !s->go.span[i].to->rule) { delete s->action; s->action = NULL; if (saves[s->rule->accept] == ~0u) { saves[s->rule->accept] = nSaves++; } bSaveOnHead |= s == head; (void) new Save(s, saves[s->rule->accept]); // sets s->action } } } } // insert actions State **rules = new State * [nRules]; memset(rules, 0, (nRules)*sizeof(*rules)); State *accept = NULL; Accept *accfixup = NULL; for (s = head; s; s = s->next) { State * ow; if (!s->rule) { ow = accept; } else { if (!rules[s->rule->accept]) { State *n = new State; (void) new Rule(n, s->rule); rules[s->rule->accept] = n; addState(&s->next, n); } ow = rules[s->rule->accept]; } for (i = 0; i < s->go.nSpans; ++i) { if (!s->go.span[i].to) { if (!ow) { ow = accept = new State; accfixup = new Accept(accept, nRules, saves, rules); addState(&s->next, accept); } s->go.span[i].to = ow; } } } if (accfixup) { accfixup->genRuleMap(); } // split ``base'' states into two parts for (s = head; s; s = s->next) { s->isBase = false; if (s->link) { for (i = 0; i < s->go.nSpans; ++i) { if (s->go.span[i].to == s) { s->isBase = true; split(s); if (bFlag) { BitMap::find(&s->next->go, s); } s = s->next; break; } } } } // find ``base'' state, if possible findBaseState(); delete head->action; head->action = NULL; if (bFlag) { o << indent(ind++) << "{\n"; bitmap_brace = 1; BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256); } bUsedYYAccept = false; uint start_label = next_label; (void) new Initial(head, next_label++, bSaveOnHead); if (bUseStartLabel) { if (startLabelName.empty()) { vUsedLabels.insert(start_label); } } for (s = head; s; s = s->next) { s->label = next_label++; } // Save 'next_fill_index' and compute information about code generation // while writing to null device. uint save_fill_index = next_fill_index; null_stream null_dev; for (s = head; s; s = s->next) { bool readCh = false; s->emit(null_dev, ind, readCh); s->go.genGoto(null_dev, ind, s, s->next, readCh); } if (last_fill_index < next_fill_index) { last_fill_index = next_fill_index; } next_fill_index = save_fill_index; // Generate prolog o << "\n" << outputFileInfo; o << indent(ind++) << "{\n"; if (!fFlag) { o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n"; if (bUsedYYAccept) { o << indent(ind) << "unsigned int "<< mapCodeName["yyaccept"] << " = 0;\n"; } } else { o << "\n"; } genGetState(o, ind, start_label); if (vUsedLabels.count(1)) { vUsedLabels.insert(0); o << indent(ind) << "goto " << labelPrefix << "0;\n"; } // Generate code for (s = head; s; s = s->next) { bool readCh = false; s->emit(o, ind, readCh); s->go.genGoto(o, ind, s, s->next, readCh); } // Generate epilog o << indent(--ind) << "}\n"; if (bitmap_brace) { o << indent(--ind) << "}\n"; } // Cleanup if (BitMap::first) { delete BitMap::first; BitMap::first = NULL; } delete [] saves; delete [] rules; bUseStartLabel = false;}void genGetState(std::ostream &o, uint& ind, uint start_label){ if (fFlag && !bWroteGetState) { vUsedLabels.insert(start_label); o << indent(ind) << "switch(" << mapCodeName["YYGETSTATE"] << "()) {\n"; if (bUseStateAbort) { o << indent(ind) << "default: abort();\n"; o << indent(ind) << "case -1: goto " << labelPrefix << start_label << ";\n"; } else { o << indent(ind) << "default: goto " << labelPrefix << start_label << ";\n"; } for (size_t i=0; i<last_fill_index; ++i) { o << indent(ind) << "case " << i << ": goto " << mapCodeName["yyFillLabel"] << i << ";\n"; } o << indent(ind) << "}\n"; if (bUseStateNext) { o << mapCodeName["yyNext"] << ":\n"; } bWroteGetState = true; }}std::ostream& operator << (std::ostream& o, const file_info& li){ if (li.ln && !iFlag) { o << "#line " << li.ln->get_line() << " \"" << li.fname << "\"\n"; } return o;}uint Scanner::get_line() const{ return cline;}void Scanner::config(const Str& cfg, int num){ if (cfg.to_string() == "indent:top") { if (num < 0) { fatal("configuration 'indent:top' must be a positive integer"); } topIndent = num; } else if (cfg.to_string() == "yybm:hex") { yybmHexTable = num != 0; } else if (cfg.to_string() == "startlabel") { bUseStartLabel = num != 0; startLabelName = ""; } else if (cfg.to_string() == "state:abort") { bUseStateAbort = num != 0; } else if (cfg.to_string() == "state:nextlabel") { bUseStateNext = num != 0; } else if (cfg.to_string() == "yyfill:enable") { bUseYYFill = num != 0; } else if (cfg.to_string() == "yyfill:parameter") { bUseYYFillParam = num != 0; } else if (cfg.to_string() == "cgoto:threshold") { cGotoThreshold = num; } else if (cfg.to_string() == "yych:conversion") { if (num) { yychConversion = "("; yychConversion += mapCodeName["YYCTYPE"]; yychConversion += ")"; } else { yychConversion = ""; } } else { fatal("unrecognized configuration name or illegal integer value"); }}static std::set<std::string> mapVariableKeys;static std::set<std::string> mapDefineKeys;static std::set<std::string> mapLabelKeys;void Scanner::config(const Str& cfg, const Str& val){ if (mapDefineKeys.empty()) { mapVariableKeys.insert("variable:yyaccept"); mapVariableKeys.insert("variable:yybm"); mapVariableKeys.insert("variable:yych"); mapVariableKeys.insert("variable:yytarget"); mapDefineKeys.insert("define:YYCTXMARKER"); mapDefineKeys.insert("define:YYCTYPE"); mapDefineKeys.insert("define:YYCURSOR"); mapDefineKeys.insert("define:YYDEBUG"); mapDefineKeys.insert("define:YYFILL"); mapDefineKeys.insert("define:YYGETSTATE"); mapDefineKeys.insert("define:YYLIMIT"); mapDefineKeys.insert("define:YYMARKER"); mapDefineKeys.insert("define:YYSETSTATE"); mapLabelKeys.insert("label:yyFillLabel"); mapLabelKeys.insert("label:yyNext"); } std::string strVal; if (val.len >= 2 && val.str[0] == val.str[val.len-1] && (val.str[0] == '"' || val.str[0] == '\'')) { SubStr tmp(val.str + 1, val.len - 2); unescape(tmp, strVal); } else { strVal = val.to_string(); } if (cfg.to_string() == "indent:string") { indString = strVal; } else if (cfg.to_string() == "startlabel") { startLabelName = strVal; bUseStartLabel = !startLabelName.empty(); } else if (cfg.to_string() == "labelprefix") { labelPrefix = strVal; } else if (mapVariableKeys.find(cfg.to_string()) != mapVariableKeys.end()) { if (bFirstPass && !mapCodeName.insert( std::make_pair(cfg.to_string().substr(sizeof("variable:") - 1), strVal) ).second) { fatal("variable already being used and cannot be changed"); } } else if (mapDefineKeys.find(cfg.to_string()) != mapDefineKeys.end()) { if (bFirstPass && !mapCodeName.insert( std::make_pair(cfg.to_string().substr(sizeof("define:") - 1), strVal) ).second) { fatal("define already being used and cannot be changed"); } } else if (mapLabelKeys.find(cfg.to_string()) != mapLabelKeys.end()) { if (bFirstPass && !mapCodeName.insert( std::make_pair(cfg.to_string().substr(sizeof("label:") - 1), strVal) ).second) { fatal("label already being used and cannot be changed"); } } else { fatal("unrecognized configuration name or illegal string value"); }}} // end namespace re2c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -