/// <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> /// Reads a list of Symbols /// </summary> /// <returns>List of Symbols</returns> private Symbol[] GetListSymbol() { int npoz = this.GetInt(); Symbol[] tmp = new Symbol[npoz]; for (int i = 0; i < npoz; i++) { tmp[i] = this.GetSymbol(); } return tmp; }
/// <summary> /// Reads a Concrete Function /// </summary> /// <param name="sequences">List of sequences</param> /// <returns>Returns the Concrete Function</returns> private ConcreteFunction GetCncFun(Symbol[][] sequences) { string name = this.GetIdent(); int[] seqIndices = this.GetListInt(); Symbol[][] seqs = new Symbol[seqIndices.Length][]; for (int i = 0; i < seqIndices.Length; i++) { seqs[i] = sequences[seqIndices[i]]; } return new ConcreteFunction(name, seqs); }
/// <summary> /// Only for testing /// </summary> public void FixSymbols() { List<List<Symbol>> syms = new List<List<Symbol>>(); foreach (Symbol[] st in this.Sequences) { var temp = new List<Symbol>(); foreach (Symbol sym in st) { if (sym is SymbolKS) { foreach (string token in ((SymbolKS)sym).Tokens) { string[] tmp2 = { token }; temp.Add(new SymbolKS(tmp2)); } } else { temp.Add(sym); } } syms.Add(temp); } Symbol[][] seqs = new Symbol[syms.Count][]; int i = 0; foreach (List<Symbol> t in syms) { seqs[i] = t.ToArray(); i++; } this.Sequences = seqs; }
/// <summary> /// Initializes a new instance of the ConcreteFunction class. /// </summary> /// <param name="name">Name of function</param> /// <param name="sequences">List of list of symbols</param> public ConcreteFunction(string name, Symbol[][] sequences) { this.Name = name; this.Sequences = sequences; }
/// <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 Alternative class. /// </summary> /// <param name="alt1">Normal tokens</param> /// <param name="alt2">List of prefixes</param> public Alternative(Symbol[] alt1, string[] alt2) { this.Alt1 = alt1; this.Alt2 = alt2; }