public static Lexer GetLexer(Frame fromf, STable kl, LAD[] lads, string title) { LexerCache lc = kl.GetLexerCache(); Lexer ret; if (lc.nfas.TryGetValue(lads, out ret)) return ret; if (lc.parent != null && lc.parent.mo.name != "Cursor" && lc.parent.mo.name != "Any") { ret = GetLexer(fromf, lc.parent.mo, lads, title); foreach (string u in ret.pad.used_methods) { if (lc.repl_methods.Contains(u)) goto anew; } if (LtmTrace) Console.WriteLine("Reused {0} alternation lexer for {1} in {2}", title, lc.parent.mo.name, kl.name); return lc.nfas[lads] = ret; } anew: if (LtmTrace) { Console.WriteLine("Need new alternation lexer for {0} in {1}", title, kl.name); } NFA pad = new NFA(); pad.cursor_class = kl; LAD[] lads_p = new LAD[lads.Length]; pad.outer_stack.Add(fromf); pad.info_stack.Add(fromf.info); for (int i = 0; i < lads_p.Length; i++) lads_p[i] = lads[i].Reify(pad); ret = new Lexer(pad, title, lads_p); lc.nfas[lads] = ret; return ret; }
public static Lexer GetDispatchLexer(STable kl, SubInfo disp) { LexerCache lc = kl.GetLexerCache(); Lexer ret; if (lc.dispatch_nfas.TryGetValue(disp, out ret)) return ret; if (lc.parent != null && lc.parent.mo.name != "Cursor" && lc.parent.mo.name != "Any") { ret = GetDispatchLexer(lc.parent.mo, disp); foreach (string u in ret.pad.used_methods) { if (lc.repl_methods.Contains(u)) goto anew; } if (LtmTrace) Console.WriteLine("Reused {0} dispatch lexer for {1} in {2}", disp.name, lc.parent.mo.name, kl.name); return lc.dispatch_nfas[disp] = ret; } anew: if (LtmTrace) { Console.WriteLine("Need new dispatch lexer for {0} in {1}", disp.name, kl.name); } NFA pad = new NFA(); pad.cursor_class = kl; P6any[] cands = (P6any[])disp.param[0]; LAD[] lads_p = new LAD[cands.Length]; for (int i = 0; i < lads_p.Length; i++) { pad.outer_stack.Add(Kernel.GetOuter(cands[i])); pad.info_stack.Add(Kernel.GetInfo(cands[i])); lads_p[i] = pad.info_stack[0].ltm.Reify(pad); pad.outer_stack.RemoveAt(pad.outer_stack.Count - 1); pad.info_stack.RemoveAt(pad.info_stack.Count - 1); } ret = new Lexer(pad, disp.name, lads_p); lc.dispatch_nfas[disp] = ret; return ret; }