actions.cc
来自「a little DFA compiler.」· CC 代码 · 共 1,063 行 · 第 1/2 页
CC
1,063 行
/* $Id: actions.cc 608 2006-11-05 00:48:30Z helly $ */#include <time.h>#include <string.h>#include <iostream>#include <iomanip>#include <cctype>#include "globals.h"#include "parser.h"#include "dfa.h"namespace re2c{void Symbol::ClearTable(){ for (SymbolTable::iterator it = symbol_table.begin(); it != symbol_table.end(); ++it) { delete it->second; } symbol_table.clear();}Symbol::SymbolTable Symbol::symbol_table;Symbol *Symbol::find(const SubStr &str){ const std::string ss(str.to_string()); SymbolTable::const_iterator it = symbol_table.find(ss); if (it == symbol_table.end()) { return (*symbol_table.insert(SymbolTable::value_type(ss, new Symbol(str))).first).second; } return (*it).second;}void showIns(std::ostream &o, const Ins &i, const Ins &base){ o.width(3); o << &i - &base << ": "; switch (i.i.tag) { case CHAR: { o << "match "; for (const Ins *j = &(&i)[1]; j < (Ins*) i.i.link; ++j) prtCh(o, j->c.value); break; } case GOTO: o << "goto " << ((Ins*) i.i.link - &base); break; case FORK: o << "fork " << ((Ins*) i.i.link - &base); break; case CTXT: o << "ctxt"; break; case TERM: o << "term " << ((RuleOp*) i.i.link)->accept; break; } o << "\n";}uint RegExp::fixedLength(){ return ~0;}const char *NullOp::type = "NullOp";void NullOp::calcSize(Char*){ size = 0;}uint NullOp::fixedLength(){ return 0;}void NullOp::compile(Char*, Ins*){ ;}void NullOp::split(CharSet&){ ;}std::ostream& operator<<(std::ostream &o, const Range &r){ if ((r.ub - r.lb) == 1) { prtCh(o, r.lb); } else { prtCh(o, r.lb); o << "-"; prtCh(o, r.ub - 1); } return o << r.next;}Range *doUnion(Range *r1, Range *r2){ Range *r, **rP = &r; for (;;) { Range *s; if (r1->lb <= r2->lb) { s = new Range(*r1); } else { s = new Range(*r2); } *rP = s; rP = &s->next; for (;;) { if (r1->lb <= r2->lb) { if (r1->lb > s->ub) break; if (r1->ub > s->ub) s->ub = r1->ub; if (!(r1 = r1->next)) { uint ub = 0; for (; r2 && r2->lb <= s->ub; r2 = r2->next) ub = r2->ub; if (ub > s->ub) s->ub = ub; *rP = r2; return r; } } else { if (r2->lb > s->ub) break; if (r2->ub > s->ub) s->ub = r2->ub; if (!(r2 = r2->next)) { uint ub = 0; for (; r1 && r1->lb <= s->ub; r1 = r1->next) ub = r1->ub; if (ub > s->ub) s->ub = ub; *rP = r1; return r; } } } } *rP = NULL; return r;}Range *doDiff(Range *r1, Range *r2){ Range *r, *s, **rP = &r; for (; r1; r1 = r1->next) { uint lb = r1->lb; for (; r2 && r2->ub <= r1->lb; r2 = r2->next) ; for (; r2 && r2->lb < r1->ub; r2 = r2->next) { if (lb < r2->lb) { *rP = s = new Range(lb, r2->lb); rP = &s->next; } if ((lb = r2->ub) >= r1->ub) goto noMore; } *rP = s = new Range(lb, r1->ub); rP = &s->next;noMore: ; } *rP = NULL; return r;}MatchOp *merge(MatchOp *m1, MatchOp *m2){ if (!m1) return m2; if (!m2) return m1; return new MatchOp(doUnion(m1->match, m2->match));}const char *MatchOp::type = "MatchOp";void MatchOp::display(std::ostream &o) const{ o << match;}void MatchOp::calcSize(Char *rep){ size = 1; for (Range *r = match; r; r = r->next) for (uint c = r->lb; c < r->ub; ++c) if (rep[c] == c) ++size;}uint MatchOp::fixedLength(){ return 1;}void MatchOp::compile(Char *rep, Ins *i){ i->i.tag = CHAR; i->i.link = &i[size]; Ins *j = &i[1]; uint bump = size; for (Range *r = match; r; r = r->next) { for (uint c = r->lb; c < r->ub; ++c) { if (rep[c] == c) { j->c.value = c; j->c.bump = --bump; j++; } } }}void MatchOp::split(CharSet &s){ for (Range *r = match; r; r = r->next) { for (uint c = r->lb; c < r->ub; ++c) { CharPtn *x = s.rep[c], *a = x->nxt; if (!a) { if (x->card == 1) continue; x->nxt = a = s.freeHead; if (!(s.freeHead = s.freeHead->nxt)) s.freeTail = &s.freeHead; a->nxt = NULL; x->fix = s.fix; s.fix = x; } if (--(x->card) == 0) { *s.freeTail = x; *(s.freeTail = &x->nxt) = NULL; } s.rep[c] = a; ++(a->card); } } for (; s.fix; s.fix = s.fix->fix) if (s.fix->card) s.fix->nxt = NULL;}RegExp * mkDiff(RegExp *e1, RegExp *e2){ MatchOp *m1, *m2; if (!(m1 = (MatchOp*) e1->isA(MatchOp::type))) return NULL; if (!(m2 = (MatchOp*) e2->isA(MatchOp::type))) return NULL; Range *r = doDiff(m1->match, m2->match); return r ? (RegExp*) new MatchOp(r) : (RegExp*) new NullOp;}RegExp *doAlt(RegExp *e1, RegExp *e2){ if (!e1) return e2; if (!e2) return e1; return new AltOp(e1, e2);}RegExp *mkAlt(RegExp *e1, RegExp *e2){ AltOp *a; MatchOp *m1, *m2; if ((a = (AltOp*) e1->isA(AltOp::type))) { if ((m1 = (MatchOp*) a->exp1->isA(MatchOp::type))) e1 = a->exp2; } else if ((m1 = (MatchOp*) e1->isA(MatchOp::type))) { e1 = NULL; } if ((a = (AltOp*) e2->isA(AltOp::type))) { if ((m2 = (MatchOp*) a->exp1->isA(MatchOp::type))) e2 = a->exp2; } else if ((m2 = (MatchOp*) e2->isA(MatchOp::type))) { e2 = NULL; } return doAlt(merge(m1, m2), doAlt(e1, e2));}const char *AltOp::type = "AltOp";void AltOp::calcSize(Char *rep){ exp1->calcSize(rep); exp2->calcSize(rep); size = exp1->size + exp2->size + 2;}uint AltOp::fixedLength(){ uint l1 = exp1->fixedLength(); uint l2 = exp1->fixedLength(); if (l1 != l2 || l1 == ~0u) return ~0; return l1;}void AltOp::compile(Char *rep, Ins *i){ i->i.tag = FORK; Ins *j = &i[exp1->size + 1]; i->i.link = &j[1]; exp1->compile(rep, &i[1]); j->i.tag = GOTO; j->i.link = &j[exp2->size + 1]; exp2->compile(rep, &j[1]);}void AltOp::split(CharSet &s){ exp1->split(s); exp2->split(s);}const char *CatOp::type = "CatOp";void CatOp::calcSize(Char *rep){ exp1->calcSize(rep); exp2->calcSize(rep); size = exp1->size + exp2->size;}uint CatOp::fixedLength(){ uint l1, l2; if ((l1 = exp1->fixedLength()) != ~0u ) if ((l2 = exp2->fixedLength()) != ~0u) return l1 + l2; return ~0u;}void CatOp::compile(Char *rep, Ins *i){ exp1->compile(rep, &i[0]); exp2->compile(rep, &i[exp1->size]);}void CatOp::split(CharSet &s){ exp1->split(s); exp2->split(s);}const char *CloseOp::type = "CloseOp";void CloseOp::calcSize(Char *rep){ exp->calcSize(rep); size = exp->size + 1;}void CloseOp::compile(Char *rep, Ins *i){ exp->compile(rep, &i[0]); i += exp->size; i->i.tag = FORK; i->i.link = i - exp->size;}void CloseOp::split(CharSet &s){ exp->split(s);}const char *CloseVOp::type = "CloseVOp";void CloseVOp::calcSize(Char *rep){ exp->calcSize(rep); if (max >= 0) { size = (exp->size * min) + ((1 + exp->size) * (max - min)); } else { size = (exp->size * min) + 1; }}void CloseVOp::compile(Char *rep, Ins *i){ Ins *jumppoint; int st; jumppoint = i + ((1 + exp->size) * (max - min)); for (st = min; st < max; st++) { i->i.tag = FORK; i->i.link = jumppoint; i++; exp->compile(rep, &i[0]); i += exp->size; } for (st = 0; st < min; st++) { exp->compile(rep, &i[0]); i += exp->size; if (max < 0 && st == 0) { i->i.tag = FORK; i->i.link = i - exp->size; i++; } }}void CloseVOp::split(CharSet &s){ exp->split(s);}RegExp *expr(Scanner &);uint Scanner::unescape(SubStr &s) const{ static const char * hex = "0123456789abcdef"; static const char * oct = "01234567"; s.len--; uint c, ucb = 0; if ((c = *s.str++) != '\\' || s.len == 0) { return xlat(c); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?