Ejemplo n.º 1
0
        protected override void MakeGotoTable()
        {
            List <LookaheadRule> g = new List <LookaheadRule>();
            int state = 0;

            for (int j = 0; j < cPrime.Count; j++)
            {
                var Ii = cPrime[j];
                for (int k = 0; k < Ii.Count; k++)
                {
                    var rule = Ii[k];
                    for (int z = 0; z < rule.Count; z++)
                    {
                        var prod = rule[z];
                        var curr = prod.Current;
                        if (curr == null)
                        {
                            continue;
                        }
                        if (TargetGrammar.Exists(curr))
                        {
                            g.AddRange(ComputeGoto(Ii, curr));
                            AddToGotoTable((int)GetIndex(g), curr, state);
                            g.Clear();
                        }
                    }
                }
                state++;
            }
        }
Ejemplo n.º 2
0
        public override IEnumerable <string> First(LookaheadRule rule, int lookahead)
        {
            HashSet <string> s  = new HashSet <string>();
            LookaheadRule    lr = null;

            //LookaheadRule lr = new LookaheadRule();
            for (int i = 0; i < rule.Count; i++)
            {
                var v = rule[i];
                if (v.Count == 0) //empty rule
                {
                    s.Add("<empty>");
                    continue;
                }
                for (int j = lookahead; j < v.Count; j++)
                {
                    var q = v[j];
                    //this is some ugly f*****g code.
                    //my better idea is to store a dictionary that
                    //ties a ruleIndex to a list of valid productions
                    //-------
                    //More succintly it lists the values that do not
                    //start with the current rule symbol. It is a far smaller
                    //list and doesn't chew through tons of space. In fact it
                    //doesn't have to be a int but a string to make things more
                    //convienient since we are referring to a rule
                    //------
                    //Plus it is also precomputed at Parser creation time because it is not
                    //going to change.
                    if (TargetGrammar.Exists(q))
                    {
                        if (firstCache.ContainsKey(q))
                        {
                            s.UnionWith(firstCache[q]);
                            break;
                        }
                        else
                        {
                            if (lr == null)
                            {
                                lr = new LookaheadRule();
                            }
                            if (q.Equals(rule.Name)) //prevent an infinite loop
                            {
                                lr.Repurpose(rule.LookaheadSymbol, skipList[rule.Name]);
                            }
                            else
                            {
                                lr.Repurpose(rule.LookaheadSymbol, TargetGrammar[q]);
                            }
                            IEnumerable <string> result = First(lr, 0);
                            s.UnionWith(result);
                            if (!firstCache.ContainsKey(q))
                            {
                                firstCache.Add(q, result);
                            }
                            if (result.Contains("<empty>"))
                            {
                                continue;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    else //assume non-terminal
                    {
                        s.Add(q);
                        break;
                    }
                }
            }
            return(s);
        }
Ejemplo n.º 3
0
        public override IEnumerable <LookaheadRule> Closure(
            IEnumerable <LookaheadRule> rules,
            string terminateSymbol)
        {
            //Closure is more refined.
            //If [A → α • B β, a] belongs to the set of items,
            //and B → γ is a production of the grammar,
            //then we add the item [B → • γ, b] for all b in FIRST(β a).
            HashSet <LookaheadRule> rr = new HashSet <LookaheadRule>(rules);
            int size = currentRules.Count;

            do
            {
                size = rr.Count;
                //get rid of the
                foreach (var rule in rr)
                {
                    var a         = rule.LookaheadSymbol;
                    var container = singles[rule.Name][rule.LookaheadSymbol];
                    for (int j = 0; j < rule.Count; j++)
                    {
                        var    p      = rule[j];
                        string symbol = p.Current;
                        if (!p.HasNext)
                        {
                            nullTerminators.Add(terminates[p]);
                        }
                        else
                        {
                            if (TargetGrammar.Exists(symbol))
                            {
                                AdvanceableProduction betaProd = advancementDict[p];      //create beta
                                var target       = initialListing[TargetGrammar[symbol]]; //grab the B-Production
                                var actualTarget = memo[target];
                                if (!betaProd.HasNext && a.Equals(terminateSymbol))
                                {
                                    currentRules.Add(actualTarget[terminateSymbol]);
                                }
                                else
                                {
                                    if (betaProd.HasNext)
                                    {
                                        var next = container[p];

                                        var ff = First(next, betaProd.Position);
                                        foreach (var v in ff)
                                        {
                                            currentRules.Add(actualTarget[v]);
                                        }
                                    }
                                    currentRules.Add(actualTarget[a]);
                                }
                            }
                        }
                    }
                }
                rr.UnionWith(currentRules);
                currentRules.Clear();
            }while(rr.Count != size);
            for (int n = 0; n < nullTerminators.Count; n++)
            {
                var    v    = nullTerminators[n];
                string name = v.Name;
                foreach (var s in rr)
                {
                    if (s.Name.Equals(name))
                    {
                        foreach (var qq in v)
                        {
                            if (!s.Contains(qq))
                            {
                                s.Add(qq);
                            }
                        }
                    }
                }
            }
            if (nullTerminators.Count > 0)
            {
                nullTerminators.Clear();
            }
            if (currentRules.Count > 0)
            {
                currentRules.Clear();
            }
            return(rr);
        }