Exemple #1
0
        /// <summary>
        /// Inserts a new tree for each token in keys.
        /// </summary>
        /// <param name="keys">The list of keys.</param>
        /// <param name="obj">The tree.</param>
        /// <returns>The new tree.</returns>
        public Trie InsertChain(List<string> keys, Trie obj)
        {
            var node = this;        // TODO check if correct
            foreach (string key in keys)
            {
                Trie nnode;
                if (this.Items.ContainsKey(key))
                {
                    nnode = node.Items[key];
                }
                else
                {
                    nnode = new Trie();
                    node.Items[key] = nnode;
                }

                node = nnode;
            }

            node.Value = obj.Value;
            return node;
        }
Exemple #2
0
        /// <summary>
        /// Inserts a chain of trees.
        /// </summary>
        /// <param name="keys">The list of tokens.</param>
        /// <param name="obj">The tree used.</param>
        /// <returns>The new tree.</returns>
        public Trie InsertChain1(List<string> keys, Trie obj)
        {
            var node = this;    // TODO this is wrong? copy?
            foreach (string key in keys)
            {
                Trie nnode;
                if (this.Items.ContainsKey(key))
                {
                    nnode = node.Items[key];
                }
                else
                {
                    nnode = new Trie();
                    node.Items[key] = nnode;
                }

                node = nnode;
            }

            if (node.Value.Count == 0)
            {
                node.Value = new List<ActiveItem>();
                node.Value.AddRange(obj.Value);
            }
            else
            {
                node.Value.AddRange(obj.Value);
            }

            return node;
        }
Exemple #3
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);
                        }
                    }
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Initializes a new instance of the ParseState class.
        /// </summary>
        /// <param name="concrete">The concrete used to parse.</param>
        public ParseState(Concrete concrete)
        {
            this.concrete = concrete;
            this.startCat = concrete.GetStartCat();

            this.items = new Trie();
            this.chart = new Chart(concrete);

            ConcreteCategory tempcat = concrete.GetStartCat();
            for (int fid = tempcat.FirstFID; fid <= tempcat.LastFID; fid++)
            {
                var prods = this.chart.ExpandForest(fid);
                foreach (ProductionApply k in prods)
                {
                    k.Function.FixSymbols();
                    int lbl = 0;
                    foreach (Symbol[] sym in k.Function.Sequences)
                    {
                        var activeItem = new ActiveItem(0, 0, k.Function, sym.ToList<Symbol>(), k.Domain().ToList<int>(), fid, lbl);
                        this.items.Value.Add(activeItem);
                        lbl++;
                    }
                }
            }

            this.items.InsertChain(new List<string>(), this.items);
        }
Exemple #5
0
        /// <summary>
        /// Parse the next token.
        /// </summary>
        /// <param name="token">The token we want to parse.</param>
        /// <returns>Returns true if parsed correctly.</returns>
        public bool Next(string token)
        {
            // Temporary store token instead of callback
            this.currentToken = token;
            this.currentAcc = this.items.Lookup(token);

            this.Process(this.items.Value);

            this.items = this.currentAcc;
            this.chart.Shift();

            return !this.items.IsEmpty();
        }