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);
        }
Beispiel #2
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);
        }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
 public GItem(int produce, ExpressInt express)
 {
     this.produce = produce | ExpressInt.nonterminal_flag;
     this.express = express;
 }