public void MeltWith(State s) { // copy actions of s to state for (Action action = s.firstAction; action != null; action = action.next) { Action a = new Action(action.typ, action.sym, action.tc); a.AddTargets(action); AddAction(a); } }
public ScannerOutput(StreamWriter gen, Tab tab, bool ignoreCase, bool hasCtxMoves, State firstState, Comment firstComment) { this.gen=gen; this.tab=tab; this.ignoreCase=ignoreCase; this.hasCtxMoves=hasCtxMoves; this.firstState=firstState; this.firstComment=firstComment; keywords.Add("-->namespace",GenNamespace()); keywords.Add("-->declarations",GenDeclarations()); keywords.Add("-->initialization",GenInitialization()); keywords.Add("-->casing1",GenCasing1()); keywords.Add("-->casing2",GenCasing2()); keywords.Add("-->comments",GenComments()); keywords.Add("-->literals",GenLiterals()); keywords.Add("-->scan3", GenScan3()); keywords.Add("-->scan1",GenScan1()); keywords.Add("-->scan2",GenScan2()); keywords.Add("$$$",GenDollarDollarDollar()); }
public DFA(Parser parser) { this.parser = parser; tab = parser.tab; errors = parser.errors; trace = parser.trace; firstState = null; lastState = null; lastStateNr = -1; firstState = NewState(); firstMelted = null; firstComment = null; ignoreCase = false; dirtyDFA = false; hasCtxMoves = false; }
void Step(State from, Node p, BitArray stepped) { if (p == null) return; stepped[p.n] = true; switch (p.typ) { case Node.clas: case Node.chr: { NewTransition(from, TheState(p.next), p.typ, p.val, p.code); break; } case Node.alt: { Step(from, p.sub, stepped); Step(from, p.down, stepped); break; } case Node.iter: { if (Tab.DelSubGraph(p.sub)) { parser.SemErr("contents of {...} must not be deletable"); return; } if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped); Step(from, p.sub, stepped); if (p.state != from) { Step(p.state, p, new BitArray(tab.nodes.Count)); } break; } case Node.opt: { if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped); Step(from, p.sub, stepped); break; } } }
// Assigns a state n.state to every node n. There will be a transition from // n.state to n.next.state triggered by n.val. All nodes in an alternative // chain are represented by the same state. // Numbering scheme: // - any node after a chr, clas, opt, or alt, must get a new number // - if a nested structure starts with an iteration the iter node must get a new number // - if an iteration follows an iteration, it must get a new number void NumberNodes(Node p, State state, bool renumIter) { if (p == null) return; if (p.state != null) return; // already visited; if (state == null || (p.typ == Node.iter && renumIter)) state = NewState(); p.state = state; if (Tab.DelGraph(p)) state.endOf = curSy; switch (p.typ) { case Node.clas: case Node.chr: { NumberNodes(p.next, null, false); break; } case Node.opt: { NumberNodes(p.next, null, false); NumberNodes(p.sub, state, true); break; } case Node.iter: { NumberNodes(p.next, state, true); NumberNodes(p.sub, state, true); break; } case Node.alt: { NumberNodes(p.next, null, false); NumberNodes(p.sub, state, true); NumberNodes(p.down, state, renumIter); break; } } }
//---------- State handling State NewState() { State s = new State(); s.nr = ++lastStateNr; if (firstState == null) firstState = s; else lastState.next = s; lastState = s; return s; }
void MeltStates(State state) { bool ctx; BitArray targets; Symbol endOf; for (Action action = state.firstAction; action != null; action = action.next) { if (action.target.next != null) { GetTargetStates(action, out targets, out endOf, out ctx); Melted melt = StateWithSet(targets); if (melt == null) { State s = NewState(); s.endOf = endOf; s.ctx = ctx; for (Target targ = action.target; targ != null; targ = targ.next) s.MeltWith(targ.state); MakeUnique(s); melt = NewMelted(targets, s); } action.target.next = null; action.target.state = melt.state; } } }
void FindUsedStates(State state, BitArray used) { if (used[state.nr]) return; used[state.nr] = true; for (Action a = state.firstAction; a != null; a = a.next) FindUsedStates(a.target.state, used); }
void NewTransition(State from, State to, int typ, int sym, int tc) { if (to == firstState) parser.SemErr("token must not start with an iteration"); Target t = new Target(to); Action a = new Action(typ, sym, tc); a.target = t; from.AddAction(a); if (typ == Node.clas) curSy.tokenKind = Symbol.classToken; }
public static void Init (string dir) { srcDir = dir; firstState = null; lastState = null; State.lastNr = -1; firstState = NewState(); Melted.first = null; Comment.first = null; dirtyDFA = false; hasCtxMoves = false; }
static void WriteState(State state) { Symbol endOf = state.endOf; gen.WriteLine("\t\t\tcase {0}:", state.nr); bool ctxEnd = state.ctx; for (Action action = state.firstAction; action != null; action = action.next) { if (action == state.firstAction) gen.Write("\t\t\t\tif ("); else gen.Write("\t\t\t\telse if ("); if (action.typ == Node.chr) gen.Write(ChCond((char)action.sym)); else PutRange(CharClass.Set(action.sym)); gen.Write(") {"); if (action.tc == Node.contextTrans) { gen.Write("apx++; "); ctxEnd = false; } else if (state.ctx) gen.Write("apx = 0; "); gen.Write("buf.Append(ch); NextCh(); goto case {0};", action.target.state.nr); gen.WriteLine("}"); } if (state.firstAction == null) gen.Write("\t\t\t\t{"); else gen.Write("\t\t\t\telse {"); if (ctxEnd) { // final context state: cut appendix gen.WriteLine(); gen.WriteLine("\t\t\t\t\tbuf.Length = buf.Length - apx;"); gen.WriteLine("\t\t\t\t\tpos = pos - apx - 1; line = t.line;"); gen.WriteLine("\t\t\t\t\tBuffer.Pos = pos+1; NextCh();"); gen.Write( "\t\t\t\t\t"); } if (endOf == null) { gen.WriteLine("t.kind = noSym; goto done;}"); } else { gen.Write("t.kind = {0}; ", endOf.n); if (endOf.tokenKind == Symbol.classLitToken) { gen.WriteLine("t.val = buf.ToString(); CheckLiteral(); return t;}"); } else { gen.WriteLine("goto done;}"); } } }
static void NewTransition(State from, State to, int typ, int sym, int tc) { if (to == firstState) Parser.SemErr("token must not start with an iteration"); Target t = new Target(to); Action a = new Action(typ, sym, tc); a.target = t; from.AddAction(a); }
//---------- State handling static State NewState() { State s = new State(); if (firstState == null) firstState = s; else lastState.next = s; lastState = s; return s; }
public Melted(BitArray set, State state) { this.set = set; this.state = state; this.next = first; first = this; }
//---------------------------- actions -------------------------------- public Action FindAction(State state, char ch) { for (Action a = state.firstAction; a != null; a = a.next) if (a.typ == Node.chr && ch == a.sym) return a; else if (a.typ == Node.clas) { CharSet s = tab.CharClassSet(a.sym); if (s[ch]) return a; } return null; }
void DeleteRedundantStates() { State[] newState = new State[lastStateNr + 1]; BitArray used = new BitArray(lastStateNr + 1); FindUsedStates(firstState, used); // combine equal final states for (State s1 = firstState.next; s1 != null; s1 = s1.next) // firstState cannot be final if (used[s1.nr] && s1.endOf != null && s1.firstAction == null && !s1.ctx) for (State s2 = s1.next; s2 != null; s2 = s2.next) if (used[s2.nr] && s1.endOf == s2.endOf && s2.firstAction == null & !s2.ctx) { used[s2.nr] = false; newState[s2.nr] = s1; } for (State state = firstState; state != null; state = state.next) if (used[state.nr]) for (Action a = state.firstAction; a != null; a = a.next) if (!used[a.target.state.nr]) a.target.state = newState[a.target.state.nr]; // delete unused states lastState = firstState; lastStateNr = 0; // firstState has number 0 for (State state = firstState.next; state != null; state = state.next) if (used[state.nr]) {state.nr = ++lastStateNr; lastState = state;} else lastState.next = state.next; }
void NumberNodes(Node p, State state) { /* Assigns a state n.state to every node n. There will be a transition from n.state to n.next.state triggered by n.val. All nodes in an alternative chain are represented by the same state. */ if (p == null) return; if (p.state != null) return; // already visited; if (state == null) state = NewState(); p.state = state; if (tab.DelGraph(p)) state.endOf = curSy; switch (p.typ) { case Node.clas: case Node.chr: { NumberNodes(p.next, null); break; } case Node.opt: { NumberNodes(p.next, null); NumberNodes(p.sub, state); break; } case Node.iter: { NumberNodes(p.next, state); NumberNodes(p.sub, state); break; } case Node.alt: { NumberNodes(p.sub, state); NumberNodes(p.down, state); break; } } }
void MakeUnique(State state) { bool changed; do { changed = false; for (Action a = state.firstAction; a != null; a = a.next) for (Action b = a.next; b != null; b = b.next) if (Overlap(a, b)) { SplitActions(state, a, b); changed = true; } } while (changed); }
bool MakeUnique(State state) { // return true if actions were split bool changed = false; for (Action a = state.firstAction; a != null; a = a.next) for (Action b = a.next; b != null; b = b.next) if (Overlap(a, b)) {SplitActions(state, a, b); changed = true;} return changed; }
Melted NewMelted(BitArray set, State state) { Melted m = new Melted(set, state); m.next = firstMelted; firstMelted = m; return m; }
void Step(State from, Node p, BitArray stepped) { if (p == null) return; stepped[p.n] = true; switch (p.typ) { case Node.clas: case Node.chr: { NewTransition(from, TheState(p.next), p.typ, p.val, p.code); break; } case Node.alt: { Step(from, p.sub, stepped); Step(from, p.down, stepped); break; } case Node.iter: case Node.opt: { if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped); Step(from, p.sub, stepped); if (p.typ == Node.iter && p.state != from) { Step(p.state, p, new BitArray(tab.nodes.Count)); } break; } } }
void NewTransition(State from, State to, int typ, int sym, int tc) { Target t = new Target(to); Action a = new Action(typ, sym, tc); a.target = t; from.AddAction(a); if (typ == Node.clas) curSy.tokenKind = Symbol.classToken; }
public State state; // new state #endregion Fields #region Constructors public Melted(BitArray set, State state) { this.set = set; this.state = state; }
void SplitActions(State state, Action a, Action b) { Action c; CharSet seta, setb, setc; seta = a.Symbols(tab); setb = b.Symbols(tab); if (seta.Equals(setb)) { a.AddTargets(b); state.DetachAction(b); } else if (seta.Includes(setb)) { setc = seta.Clone(); setc.Subtract(setb); b.AddTargets(a); a.ShiftWith(setc, tab); } else if (setb.Includes(seta)) { setc = setb.Clone(); setc.Subtract(seta); a.AddTargets(b); b.ShiftWith(setc, tab); } else { setc = seta.Clone(); setc.And(setb); seta.Subtract(setc); setb.Subtract(setc); a.ShiftWith(seta, tab); b.ShiftWith(setb, tab); c = new Action(0, 0, Node.normalTrans); // typ and sym are set in ShiftWith c.AddTargets(a); c.AddTargets(b); c.ShiftWith(setc, tab); state.AddAction(c); } }
public State state; // target state #endregion Fields #region Constructors public Target(State s) { state = s; }
void WriteState(State state) { Symbol endOf = state.endOf; gen.WriteLine("\t\t\tcase {0}:", state.nr); if (endOf != null && state.firstAction != null) { gen.WriteLine("\t\t\t\trecEnd = pos; recKind = {0};", endOf.n); } bool ctxEnd = state.ctx; for (Action action = state.firstAction; action != null; action = action.next) { if (action == state.firstAction) gen.Write("\t\t\t\tif ("); else gen.Write("\t\t\t\telse if ("); if (action.typ == Node.chr) gen.Write(ChCond((char)action.sym)); else PutRange(tab.CharClassSet(action.sym)); gen.Write(") {"); if (action.tc == Node.contextTrans) { gen.Write("apx++; "); ctxEnd = false; } else if (state.ctx) gen.Write("apx = 0; "); gen.Write("AddCh(); goto case {0};", action.target.state.nr); gen.WriteLine("}"); } if (state.firstAction == null) gen.Write("\t\t\t\t{"); else gen.Write("\t\t\t\telse {"); if (ctxEnd) { // final context state: cut appendix gen.WriteLine(); gen.WriteLine("\t\t\t\t\ttlen -= apx;"); gen.WriteLine("\t\t\t\t\tSetScannerBehindT();"); gen.Write("\t\t\t\t\t"); } if (endOf == null) { gen.WriteLine("goto case 0;}"); } else { gen.Write("t.kind = {0}; ", endOf.n); if (endOf.tokenKind == Symbol.classLitToken) { gen.WriteLine("t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}"); } else { gen.WriteLine("break;}"); } } }
void WriteState(State state) { Symbol endOf = state.endOf; gen.WriteLine("\t\t| {0} -> ", state.nr); bool ctxEnd = state.ctx; for (Action action = state.firstAction; action != null; action = action.next) { if (action == state.firstAction) gen.Write("\t\t\t\tif ("); else gen.Write("\t\t\t\telse if ("); if (action.typ == Node.chr) { gen.Write(ChCond((char)action.sym)); } else { //Convert Charset to BitArray CharSet teste2 = tab.CharClassSet(action.sym); bool[] cg = new bool[256]; for (int i = 0; i < 256; i++) cg[i] = teste2[i]; BitArray cc = new BitArray(cg); PutRange(cc); } gen.Write(") then ("); if (action.tc == Node.contextTrans) { gen.Write("apx:=apx+1; "); ctxEnd = false; } else if (state.ctx) gen.Write("apx := 0; "); gen.Write("x.AddCh(); x.resolveKind {0};", action.target.state.nr); gen.WriteLine(")"); } if (state.firstAction == null) gen.Write("\t\t\t\t("); else gen.Write("\t\t\t\telse ("); if (ctxEnd) { // final context state: cut appendix gen.WriteLine(); gen.WriteLine("\t\t\t\t\ttlen := tlen- apx;"); gen.WriteLine("\t\t\t\t\tpos := pos - apx - 1; line = t.line;"); gen.WriteLine("\t\t\t\t\tbuffer.Pos := pos + 1; x.NextCh();"); gen.Write("\t\t\t\t\t"); } if (endOf == null) { gen.WriteLine(" noSym )"); } else { if (endOf.tokenKind == Symbol.classLitToken) { gen.Write("x.checkLiteral (tval.ToString()) "); gen.WriteLine(" {0} )", endOf.n); } else { gen.Write(" {0} ", endOf.n); gen.WriteLine(")"); } } }