Ejemplo n.º 1
0
Archivo: PGF.cs Proyecto: hundben/CSPGF
        /// <summary>
        /// Read a Production
        /// </summary>
        /// <param name="leftCat">Left hand side category</param>
        /// <param name="cncFuns">List of Concrete Functions</param>
        /// <returns>Returns the Production</returns>
        private Production GetProduction(int leftCat, ConcreteFunction[] cncFuns)
        {
            int sel = this.inputstream.ReadByte();
            Production prod;
            switch (sel)
            {
                case 0: // application
                    prod = new ProductionApply(leftCat, cncFuns[this.GetInt()], this.GetDomainFromPArgs());
                    break;
                case 1: // coercion
                    prod = new ProductionCoerce(leftCat, this.GetInt());
                    break;
                default:
                    throw new PGFException("Invalid tag for productions : " + sel);
            }

            return prod;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Processes the current agenda.
        /// </summary>
        /// <param name="agenda">The agenda we want to go through.</param>
        public void Process(List<ActiveItem> agenda)
        {
            while (agenda.Count > 0)
            {
                var item = agenda[agenda.Count - 1];
                agenda.RemoveAt(agenda.Count - 1);
                var lin = item.Seq;

                if (item.Dot < lin.Count)
                {
                    var sym = lin[item.Dot];
                    if (sym is SymbolCat)
                    {
                        var newSym = (SymbolCat)sym;
                        var fid = item.Args[newSym.Arg];
                        var label = newSym.Label;
                        var items = this.chart.LookupAC(fid, label);

                        if (items == null)
                        {
                            var rules = this.chart.ExpandForest(fid);

                            foreach (ProductionApply rule in rules)
                            {
                                var newAI = new ActiveItem(this.chart.Offset, 0, rule.Function, rule.Function.Sequences[label].ToList<Symbol>(), rule.Domain().ToList<int>(), fid, label);
                                agenda.Add(newAI);
                            }

                            List<ActiveItem> temp = new List<ActiveItem>();
                            temp.Add(item);
                            this.chart.InsertAC(fid, label, temp);
                        }
                        else
                        {
                            bool isMember = false;
                            foreach (ActiveItem ai in items)
                            {
                                if (ai.Equals(item))
                                {
                                    isMember = true;
                                    break;
                                }
                            }

                            if (!isMember)
                            {
                                items.Add(item);

                                var fid2 = this.chart.LookupPC(fid, label, this.chart.Offset);
                                if (fid2.HasValue)
                                {
                                    agenda.Add(item.ShiftOverArg(newSym.Arg, fid2.Value));
                                }
                            }
                        }
                    }
                    else if (sym is SymbolLit)
                    {
                        var newSym = (SymbolLit)sym;
                        var fid = item.Args[newSym.Arg];

                        List<Production> rules;
                        if (this.chart.Forest.ContainsKey(fid))
                        {
                            rules = this.chart.Forest[fid];
                        }
                        else
                        {
                            rules = new List<Production>();
                        }

                        if (rules.Count > 0)
                        {
                            if (rules[0] is ProductionConst)
                            {
                                ProductionConst pc = (ProductionConst)rules[0];
                                List<string> tokens = new List<string>(pc.Tokens);
                                ActiveItem ai2 = item.ShiftOverTokn();
                                if (pc.Tokens.Count > 0 && (this.currentToken == string.Empty || tokens[0] == this.currentToken))
                                {
                                    tokens.RemoveAt(0);
                                    Trie tt = new Trie();
                                    tt.Value = new List<ActiveItem>() { ai2 };
                                    this.currentAcc = this.currentAcc.InsertChain1(tokens, tt);
                                }
                            }
                        }
                        else
                        {
                            List<Production> newProd = new List<Production>();

                            Symbol[][] syms = new Symbol[0][];
                            if (fid == -1)
                            {
                                // If string
                                string token = "\"" + this.currentToken + "\"";
                                ConcreteFunction newFun = new ConcreteFunction(token, syms);
                                newProd.Add(new ProductionConst(newFun, new List<string>() { token }, -1));    // nextId´+??
                            }
                            else if (fid == -2)
                            {
                                // If int
                                int i = 0;
                                if (int.TryParse(this.currentToken, out i))
                                {
                                    ConcreteFunction newFun = new ConcreteFunction(this.currentToken, syms);
                                    newProd.Add(new ProductionConst(newFun, new List<string>() { this.currentToken }, -2));
                                }
                            }
                            else if (fid == -3)
                            {
                                // If float
                                double f = 0;
                                if (double.TryParse(this.currentToken, NumberStyles.Number, NumberFormatInfo.InvariantInfo, out f))
                                {
                                    ConcreteFunction newFun = new ConcreteFunction(this.currentToken, syms);
                                    newProd.Add(new ProductionConst(newFun, new List<string>() { this.currentToken }, -3));
                                }
                            }

                            if (newProd.Count > 0)
                            {
                                var currentProd = (ProductionConst)newProd[0];
                                fid = this.chart.NextId++;
                                this.chart.Forest[fid] = newProd;

                                var tokens2 = new List<string>(currentProd.Tokens);
                                var item2 = item.ShiftOverArg(newSym.Arg, fid);

                                if (tokens2.Count > 0 && (this.currentToken == string.Empty || tokens2[0] == this.currentToken))
                                {
                                    tokens2.RemoveAt(0);
                                    Trie tt = new Trie();
                                    tt.Value = new List<ActiveItem>() { item2 };
                                    this.currentAcc = this.currentAcc.InsertChain1(tokens2, tt);
                                }
                            }
                        }
                    }
                    else if (sym is SymbolKP)
                    {
                        var newSym = (SymbolKP)sym;
                        var pitem = item.ShiftOverTokn();
                        var tokens = new List<string>();
                        foreach (Symbol newSymbol in newSym.Tokens)
                        {
                            if (newSymbol is SymbolKS)
                            {
                                // TODO is this correct?
                                tokens.AddRange(((SymbolKS)newSymbol).Tokens);
                            }
                            else if (newSymbol is SymbolBind)
                            {
                                tokens.Add("&+");
                            }
                            else if (newSymbol is SymbolSoftBind)
                            {
                                // Ignore
                            }
                            else if (newSymbol is SymbolSoftSpace)
                            {
                                // Ignore
                            }
                            else if (newSymbol is SymbolCapit)
                            {
                                tokens.Add("&|");
                            }
                            else if (newSymbol is SymbolAllCapit)
                            {
                                tokens.Add("&|");
                            }
                            else
                            {
                                // If new token just ignore
                            }
                        }

                        if (tokens.Count > 0 && (this.currentToken == string.Empty || tokens[0] == this.currentToken))
                        {
                            tokens.RemoveAt(0);
                            Trie tt = new Trie();
                            tt.Value = new List<ActiveItem>() { pitem };
                            this.currentAcc = this.currentAcc.InsertChain1(tokens, tt);
                        }

                        foreach (Alternative alt in newSym.Alts)
                        {
                            // TODO check if needed
                            Symbol[] currentSym = alt.Alt1;

                            tokens = new List<string>(alt.Alt2.ToList<string>());
                            if (tokens.Count > 0 && (this.currentToken == string.Empty || tokens[0] == this.currentToken))
                            {
                                tokens.RemoveAt(0);
                                Trie tt = new Trie();
                                tt.Value = new List<ActiveItem>() { pitem };
                                this.currentAcc = this.currentAcc.InsertChain1(tokens, tt);
                            }
                        }
                    }
                    else if (sym is SymbolKS)
                    {
                        var newSym = (SymbolKS)sym;
                        var tokens = new List<string>(newSym.Tokens.ToList<string>());
                        var ai = item.ShiftOverTokn();
                        if (tokens.Count > 0 && (this.currentToken == string.Empty || tokens[0] == this.currentToken))
                        {
                            tokens.RemoveAt(0);
                            Trie tt = new Trie();
                            tt.Value = new List<ActiveItem>() { ai };
                            this.currentAcc = this.currentAcc.InsertChain1(tokens, tt);
                        }
                    }
                    else if (sym is SymbolVar)
                    {
                        var newSym = (SymbolVar)sym;

                        // TODO Not implemented
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    int? tempfid = this.chart.LookupPC(item.FId, item.Lbl, item.Offset);
                    if (!tempfid.HasValue)
                    {
                        int fid = this.chart.NextId++;

                        var items = this.chart.LookupACo(item.Offset, item.FId, item.Lbl);
                        if (items != null)
                        {
                            foreach (ActiveItem pitem in items)
                            {
                                var temp = pitem.Seq[pitem.Dot];
                                if (temp is SymbolCat)
                                {
                                    var arg = ((SymbolCat)temp).Arg;
                                    agenda.Add(pitem.ShiftOverArg(arg, fid));
                                }
                                else if (temp is SymbolLit)
                                {
                                    var arg = ((SymbolLit)temp).Arg;
                                    agenda.Add(pitem.ShiftOverArg(arg, fid));
                                }
                            }
                        }

                        this.chart.InsertPC(item.FId, item.Lbl, item.Offset, fid);
                        var newProd = new ProductionApply(item.Fun, item.Args.ToArray<int>());
                        if (this.chart.Forest.ContainsKey(fid))
                        {
                            this.chart.Forest[fid].Add(newProd);
                        }
                        else
                        {
                            this.chart.Forest[fid] = new List<Production>() { newProd };
                        }
                    }
                    else
                    {
                        int fid = tempfid.Value;
                        var labels = this.chart.LabelsAC(fid);
                        foreach (int k in labels.Keys)
                        {
                            var newAI = new ActiveItem(this.chart.Offset, 0, item.Fun, item.Fun.Sequences[k].ToList<Symbol>(), item.Args, fid, k);
                            agenda.Add(newAI);
                        }

                        var rules = this.chart.Forest[fid];
                        var rule = new ProductionApply(item.Fun, item.Args.ToArray<int>());
                        bool isMember = false;
                        foreach (Production p in rules)
                        {
                            if (p is ProductionApply)
                            {
                                if (rule.Equals((ProductionApply)p))
                                {
                                    isMember = true;
                                }
                            }
                        }

                        if (!isMember)
                        {
                            rules.Add(rule);
                        }
                    }
                }
            }
        }