/// <summary> /// Initializes a new instance of the ProductionConst class. /// </summary> /// <param name="function">The corresponding concrete function.</param> /// <param name="tokens">List of tokens.</param> /// <param name="type">The type of the literal, same as FId for literals.</param> public ProductionConst(ConcreteFunction function, List<string> tokens, int type) : base(0, -5) { this.Type = type; this.Tokens = tokens; this.Fun = function; }
/// <summary> /// Initializes a new instance of the ActiveItem class. /// </summary> /// <param name="offset">The offset</param> /// <param name="dot">The position</param> /// <param name="fun">The concrete function used</param> /// <param name="seq">A list of symbols</param> /// <param name="args">A list of arguments</param> /// <param name="fid">The current FId</param> /// <param name="lbl">A label</param> public ActiveItem(int offset, int dot, ConcreteFunction fun, List<Symbol> seq, List<int> args, int fid, int lbl) { this.Offset = offset; this.Dot = dot; this.Fun = fun; this.Seq = seq; this.Args = args; this.FId = fid; this.Lbl = lbl; }
/// <summary> /// Reads a ProductionSet /// </summary> /// <param name="cncFuns">List of Concrete Functions</param> /// <returns>Returns the ProductionSet</returns> private ProductionSet GetProductionSet(ConcreteFunction[] cncFuns) { int id = this.GetInt(); return new ProductionSet(id, this.GetListProduction(id, cncFuns)); }
/// <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; }
/// <summary> /// Read a list of ProductionSets /// </summary> /// <param name="cncFuns">List of Concrete Functions</param> /// <returns>List of ProductionSets</returns> private ProductionSet[] GetListProductionSet(ConcreteFunction[] cncFuns) { int npoz = this.GetInt(); ProductionSet[] tmp = new ProductionSet[npoz]; for (int i = 0; i < npoz; i++) { tmp[i] = this.GetProductionSet(cncFuns); } return tmp; }
/// <summary> /// Read a list of Concrete Functions /// </summary> /// <param name="sequences">List of Sequences</param> /// <returns>List of Concrete Functions</returns> private ConcreteFunction[] GetListCncFun(Symbol[][] sequences) { int npoz = this.GetInt(); ConcreteFunction[] cncfuns = new ConcreteFunction[npoz]; for (int i = 0; i < npoz; i++) { cncfuns[i] = this.GetCncFun(sequences); } return cncfuns; }
/// <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); } } } } }
/// <summary> /// Initializes a new instance of the ProductionApply class. /// </summary> /// <param name="function">The concrete function</param> /// <param name="domain">The domain</param> public ProductionApply(ConcreteFunction function, int[] domain) : base(0, -5) { this.Function = function; this.dom = domain; }