public bool IsVaild(ISymbolMap symbol, out string message) { DebugSymbolMap debug = symbol as DebugSymbolMap; GItem[] vs = m_items; Range[] map = m_nonterminals; int x = vs.Length; string result = string.Empty; int errorcnt = 1; while (--x >= 0) { GItem current = vs[x]; ExpressInt expression = current.express; int len = expression.Length; while (--len >= 0) { int now = expression[len]; if (!now.IsTerminal() && map[now.ToIndex()] == default) { result += $"[{errorcnt++}] Invalid Non-Terminal: " + (debug?.Get(now) ?? $"<{now}>") + Environment.NewLine; } } } message = result; return(result.Length == 0); }
private static int IndexOf(Grammar g, LRxItem item) { ExpressInt express = item.express; #if DEBUG int debug = item.produce.ToIndex(); string debug_str = Grammar.bag[item.produce]; #endif Range rng = g.m_nonterminals[item.produce.ToIndex()]; int st = rng.start; int ed = rng.end; do { if (g.m_items[st].express.Equals(express)) { return(st); } } while (++st < ed); return(-1); }
private static void First2(Grammar grammar, HashSet <int> result, HashSet <int> done, Range rng) { Stack <Range> stack = new Stack <Range>(); loop1: int st = rng.start; loop2: ExpressInt express = grammar.m_items[st].express; int now = express[0]; if (now.IsTerminal()) { result.Add(now); } else if (done.Add(now)) { stack.Push(new Range(st + 1, rng.end)); rng = grammar.m_nonterminals[now.ToIndex()]; goto loop1; } if (++st < rng.end) { goto loop2; } while (stack.Count > 0) { rng = stack.Pop(); if (rng.start >= rng.end) { continue; } goto loop1; } }
private static void Follow2(Grammar grammar, HashSet <int> result, HashSet <int> done, Item item) { Stack <Item> its = new Stack <Item>(); HashSet <int> firstdone = new HashSet <int>(); loop1: int idx = item.index; int st = item.start; loop2: ExpressInt express = grammar.m_items[st].express; int len = express.Length; int mlen = len - 1; if (idx >= len) { its.Clear(); return; } loop3: Range rng; int now = express[idx]; if (!now.IsTerminal()) { if (idx < mlen) { now = express[++idx]; if (now.IsTerminal()) { result.Add(now); } else if (done.Add(now)) { First2(grammar, result, firstdone, grammar.m_nonterminals[now.ToIndex()]); firstdone.Clear(); } } else if (len == 1 && done.Add(now)) { its.Push(new Item(st, item.end, idx)); rng = grammar.m_nonterminals[now.ToIndex()]; item = new Item(rng.start, rng.end, 0); goto loop1; } } if (++idx < len) { goto loop3; } else if (++st < item.end) { idx = 0; goto loop2; } else if (its.Count > 0) { item = its.Pop(); goto loop1; } }
public GItem(int produce, ExpressInt express) { this.produce = produce | ExpressInt.nonterminal_flag; this.express = express; }