/// <summary> /// Initializes a new instance of the AppResult class. /// </summary> /// <param name="cncFun">Concrete Function</param> /// <param name="cncType">Concrete Type</param> /// <param name="cncTypes">List of Concrete types</param> public AppResult(ConcreteFunction cncFun, ConcreteType cncType, List<ConcreteType> cncTypes) { this.CncFun = cncFun; this.CncType = cncType; this.CncTypes = cncTypes; }
/// <summary> /// Initializes a new instance of the LinTriple class. /// </summary> /// <param name="fId">Function id</param> /// <param name="cncType">Concrete type</param> /// <param name="linTable">Linearization table</param> public LinTriple(int fId, ConcreteType cncType, List<List<BracketedToken>> linTable) { this.FId = fId; this.CncType = cncType; this.LinTable = linTable; }
/// <summary> /// :D :D :D ? /// </summary> /// <param name="cty">Concrete type</param> /// <param name="p">Production to use</param> /// <param name="f">Function to use</param> /// <param name="prods">Productions to use</param> /// <returns>List of AppResults</returns> private List<AppResult> ToApp(ConcreteType cty, Production p, string f, Dictionary<int, HashSet<Production>> prods) { List<AppResult> rez = new List<AppResult>(); if (p is ProductionApply) { ProductionApply ap = (ProductionApply)p; int[] args = ap.Domain(); ConcreteFunction cncFun = ap.Function; List<ConcreteType> vtype = new List<ConcreteType>(); if (f.Equals("_V")) { foreach (int j in args) { vtype.Add(new ConcreteType("__gfVar", j)); } rez.Add(new AppResult(cncFun, cty, vtype)); return rez; } else if (f.Equals("_B")) { vtype.Add(new ConcreteType(cty.CId, args[0])); for (int i = 1; i < args.Length; i++) { vtype.Add(new ConcreteType("__gfVar", args[i])); } rez.Add(new AppResult(cncFun, cty, vtype)); return rez; } else { Grammar.Type t = null; foreach (AbstractFunction abs in this.pgf.GetAbstract().AbsFuns) { if (f.Equals(abs.Name)) { t = abs.Type; break; } } if (t == null) { throw new LinearizerException("Abstract function: " + f + " not found in the abstract syntax"); } List<string> catSkel = this.CatSkeleton(t); string res = catSkel.ElementAt(0); for (int i = 0; i < args.Length; i++) { vtype.Add(new ConcreteType(catSkel.ElementAt(i + 1), args[i])); } rez.Add(new AppResult(cncFun, new ConcreteType(res, cty.FId), vtype)); return rez; } } else { HashSet<Production> setProds; if (prods.TryGetValue(((ProductionCoerce)p).InitId, out setProds)) { foreach (Production prod in setProds) { rez.AddRange(this.ToApp(cty, prod, f, prods)); } return rez; } throw new LinearizerException("Couldn't find the production with InitId: " + ((ProductionCoerce)p).InitId); } }
/// <summary> /// Main Linearization function /// </summary> /// <param name="xs">list of bound variables (from lambdas)</param> /// <param name="ys">list of strings?</param> /// <param name="mbcty">Concrete type</param> /// <param name="mbfid">Function id</param> /// <param name="tree">Tree to linearize</param> /// <returns>List of all possible linearized tuples</returns> private List<LinTriple> Lin0(List<string> xs, List<string> ys, ConcreteType mbcty, int mbfid, Tree tree) { // if tree is a lambda, we add the variable to the list of bound // variables and we linearize the subtree. if (tree is Lambda) { xs.Add(((Lambda)tree).Ident_); List<LinTriple> tmp = this.Lin0(xs, ys, mbcty, mbfid, ((Lambda)tree).Tree_); return tmp; } else if (xs.Count == 0) { List<Tree> es = new List<Tree>(); if (tree is Application) { do { es.Add(((Application)tree).Tree_2); tree = ((Application)tree).Tree_1; } while (tree is Application); } if (tree is Function) { return this.Apply(xs, mbcty, mbfid, ((Function)tree).Ident_, es); } else if (tree is Trees.Absyn.Literal) { // TODO check if correct? var lit = (Trees.Absyn.Literal)tree; string token = "?"; if (lit.Lit_ is FloatLiteral) { token = ((FloatLiteral)lit.Lit_).Double_.ToString(CultureInfo.InvariantCulture); } else if (lit.Lit_ is IntLiteral) { token = ((IntLiteral)lit.Lit_).Integer_.ToString(CultureInfo.InvariantCulture); } else if (lit.Lit_ is StringLiteral) { token = ((StringLiteral)lit.Lit_).String_; } string[] tokens = { token }; List<BracketedToken> bt = new List<BracketedToken>() { new LeafKS(tokens) }; List<List<BracketedToken>> btt = new List<List<BracketedToken>>() { bt }; LinTriple lt = new LinTriple(mbfid, mbcty, btt); List<LinTriple> llt = new List<LinTriple>() { lt }; return llt; } else { throw new LinearizerException("Undefined construction for expressions !!!"); } } else { xs.AddRange(ys); List<Tree> exprs = new List<Tree> { tree }; foreach (string str in xs) { exprs.Add(new Trees.Absyn.Literal(new StringLiteral(str))); } return this.Apply(xs, mbcty, mbfid, "_B", exprs); } }
/// <summary> /// Find AppResults /// </summary> /// <param name="prods">Productions to use</param> /// <param name="mbcty">Concrete type</param> /// <param name="f">Name of the function</param> /// <returns>List of AppResults</returns> private List<AppResult> GetApps(Dictionary<int, HashSet<Production>> prods, ConcreteType mbcty, string f) { if (mbcty == null) { if (f.Equals("_V") || f.Equals("_B")) { return new List<AppResult>(); } else { List<AppResult> rez = new List<AppResult>(); foreach (KeyValuePair<int, HashSet<Production>> it in prods) { int fid = it.Key; foreach (Production prod in it.Value) { rez.AddRange(this.ToApp(new ConcreteType("_", fid), prod, f, prods)); } } return rez; } } else { HashSet<Production> setProd; List<AppResult> rez = new List<AppResult>(); if (!prods.TryGetValue(mbcty.FId, out setProd)) { return rez; } else { foreach (Production prod in setProd) { rez.AddRange(this.ToApp(mbcty, prod, f, prods)); } return rez; } } }
/// <summary> /// Intermediate linearization for complex expressions. /// </summary> /// To linearize the application of the function "f" to the arguments (trees) a, b and c use : apply(???,???,??? "f", [a,b,c]). /// 'apply' will linearize the argument and then use the concrete function for "f" to glue them together. /// <param name="xs">List of bound variables</param> /// <param name="mbcty">Concrete type</param> /// <param name="nextfid">Insert comment</param> /// <param name="f">Name of the function to be applied</param> /// <param name="es">The argument of the function to linearize</param> /// <returns>All possible linearizations for the application of f to es</returns> private List<LinTriple> Apply(List<string> xs, ConcreteType mbcty, int nextfid, string f, List<Tree> es) { Dictionary<int, HashSet<Production>> prods; if (!this.linProd.TryGetValue(f, out prods)) { List<Tree> newes = new List<Tree> { new Trees.Absyn.Literal(new StringLiteral(f)) }; Console.WriteLine("Function " + f + " does not have a linearization !"); return this.Apply(xs, mbcty, nextfid, "_V", newes); } else { List<AppResult> listApp = this.GetApps(prods, mbcty, f); List<LinTriple> rez = new List<LinTriple>(); foreach (AppResult appr in listApp) { List<ConcreteType> ctys = new List<ConcreteType>(); for (int ind = appr.CncTypes.Count - 1; ind >= 0; ind--) { ctys.Add(appr.CncTypes.ElementAt(ind)); } if (es.Count != ctys.Count) { throw new LinearizerException("Lengths of es and ctys don't match" + es + " -- " + ctys); } Symbol[][] lins = appr.CncFun.Sequences; string cat = appr.CncType.CId; List<Tree> copyExpr = new List<Tree>(es); List<RezDesc> rezDesc = this.Descend(nextfid, ctys, copyExpr, xs); foreach (RezDesc rez2 in rezDesc) { List<List<BracketedToken>> linTab = new List<List<BracketedToken>>(); foreach (Symbol[] seq in lins) { linTab.Add(this.ComputeSeq(seq, rez2.CncTypes, rez2.Bracketedtokn)); } rez.Add(new LinTriple(nextfid + 1, new ConcreteType(cat, nextfid), linTab)); } } return rez; } }