Beispiel #1
0
        internal override void CheckTransformation(HashSet<string> subs, AlphabetDef domAlph, AlphabetDef rangeAlph, FastPgm pgm)
        {
            foreach (var expr in args)
                expr.CheckTransformation(subs, domAlph, rangeAlph, pgm);

            var constsAndFuns = new Dictionary<string, FastSort>();
            foreach (var def in pgm.defs)
            {
                if (def.kind == DefKind.Function)
                    constsAndFuns.Add(((FunctionDef)def).name.text, ((FunctionDef)def).sort);
                if (def.kind == DefKind.Const)
                    constsAndFuns.Add(((ConstDef)def).name.text, ((ConstDef)def).sort);
            }
            bool ok = CheckStandardOps(constsAndFuns);

            if (!ok)
            {
                string f = func.name.text;
                if (this is RecordExp)                                 // --- record constrctor ---
                {
                    if (rangeAlph.attrSort.fields.Count != args.Count)
                        throw new FastParseException(func.name.Location, string.Format("unxecpected nr of attribute fields {0}, expecting {1}", args.Count, rangeAlph.attrSort.fields.Count));
                    for (int i = 0; i < args.Count; i++)
                    {
                        if (args[i].sort.name.text != rangeAlph.attrSort.fields[i].Value.name.text)
                            throw new FastParseException(args[i].sort.name.Location, string.Format("invalid argument sort '{0}' of field '{1}', expecting sort '{2}'", args[i].sort.name.text, rangeAlph.attrSort.fields[i].Key.text, rangeAlph.attrSort.fields[i].Value.name.text));
                    }
                    _sort = rangeAlph.attrSort;
                }
                else if (rangeAlph.symbols.Exists(_f => func.name.text == _f.name.text)) // --- tree constructor ---
                {
                    if (!rangeAlph.IsValidSymbol(func.name, func.arity))
                    {
                        throw new FastParseException(func.name.Location, string.Format("wrong number of arguments of constructor '{0}'", func.name));
                    }

                    for (int i = 1; i < args.Count; i++)
                    {
                        if (args[i].sort.name.text != rangeAlph.id.text)
                            throw new FastParseException(func.name.Location, string.Format("unexected argument of function '{0}'", func.name));
                    }
                    _sort = rangeAlph.sort;
                }
                else
                {
                    var def = pgm.FindDef(func.name);

                    if (def.kind == DefKind.Trans)
                    {
                        if (args.Count != 1)
                            throw new FastParseException(func.name.Location, string.Format("transduction '{0}' is unary", func.name));

                        var tdef = def as TransDef;
                        if (tdef.domain.name.text != args[0].sort.name.text)
                            throw new FastParseException(args[0].sort.name.Location, string.Format("transduction '{0}' has unexpected argument of sort '{1}', expecting sort '{2}'", func.name, args[0].sort.name.text, tdef.domain.name.text));

                        _sort = tdef.range;
                        isTranDef = true;
                        if (args[0].kind == FExpKind.App)
                            throw new FastParseException(func.name.Location, string.Format("Transduction '{0}' cannot be nested inside another Transduction", func.name));
                    }
                    else
                    {
                        throw new FastParseException(func.name.Location, string.Format("ID '{0}' is not a Transduction", func.name));
                    }
                }
            }
        }
Beispiel #2
0
 internal override void CheckTransformation(HashSet<string> subs, AlphabetDef domAlph, AlphabetDef rangeAlph, FastPgm pgm)
 {
 }
Beispiel #3
0
        internal override void CheckSubtreeGuard(Dictionary<string, FastSort> subs, AlphabetDef alph, FastPgm pgm)
        {
            Predicate<FExp> IsNotBool = (x => { return x.sort == null || x.sort.kind != FastSortKind.Bool; });
            foreach (var expr in args)
                expr.CheckSubtreeGuard(subs, alph, pgm);

            if (func.name.text != "and" && func.name.text != "or" && !pgm.defs.Exists(d => d.id.text == func.name.text && d.kind == DefKind.Lang && ((LangDef)d).domain.name.text == alph.sort.name.text))
                throw new FastParseException(func.name.Location, string.Format("illeagal identifier '{0}'", func.name.text));

            if ((func.name.text == "and" || func.name.text == "or") && args.Exists(IsNotBool))
                throw new FastParseException(func.name.Location, string.Format("arguments of '{0}' must be Boolean", func.name.text));

            if (pgm.defs.Exists(d => d.id.text == func.name.text && d.kind == DefKind.Lang && ((LangDef)d).domain.name.text == alph.sort.name.text))
                isLangDef = true;

            _sort = FastSort.Bool;
        }
Beispiel #4
0
 internal virtual void SetConstructorSort(AlphabetDef alph)
 {
 }
Beispiel #5
0
 internal override void CheckSubtreeGuard(Dictionary<string, FastSort> subs, AlphabetDef alph, FastPgm pgm)
 {
 }
Beispiel #6
0
        internal override void CheckTransformation(HashSet<string> subs, AlphabetDef domAlph, AlphabetDef rangeAlph, FastPgm pgm)
        {
            if (subs.Contains(this.token.text))
            {
                _sort = domAlph.sort;
            }
            else
            {
                //Check if the current variable is a constant
                FastSort s;
                foreach (var def in pgm.defs)
                {
                    if (def.kind == DefKind.Const && ((ConstDef)def).id.text == this.token.text)
                    {
                        s = ((ConstDef)def).sort;
                        if (s == null || (_sort != null && s.name.text != _sort.name.text))
                            throw new FastParseException(token.Location, string.Format("unexpected identifier '{0}'", token.text));
                        _sort = s;
                        return;
                    }
                }

                //Oterwise look for attr symbol

                if (Array.Exists(rangeAlph.symbols.ToArray(), x => x.name.text == this.token.text))
                    throw new FastParseException(this.token.Location, string.Format("the constructor '{0}' is not applied to a tuple", this.token.text));

                if (domAlph == null)
                    throw new FastParseException(this.token.Location, string.Format("the variable '{0}' is not defined", this.token.text));

                s = domAlph.attrSort.getSort(this.token);

                if (s == null || (_sort != null && s.name.text != _sort.name.text))
                    throw new FastParseException(token.Location, string.Format("unexpected identifier '{0}'", token.text));
                _sort = s;
            }
        }
        //Generate the C# corresponding to the constructor of a Tree class, the MakeTree method and an accessor for the children
        private static bool GenerateConstructor(StringBuilder sb, AlphabetDef aDef)
        {
            sb.Append("private Tree" + aDef.id.text + "(" + aDef.id.text + " symbol");
            foreach (var s in aDef.attrSort.fieldSorts)
            {
                if (s.Value.kind == FastSortKind.Real)
                {
                    sb.Append(", double " + s.Key);
                }
                else
                {
                    sb.Append(", " + s.Value.name + " " + s.Key);
                }
            }
            sb.AppendLine(", Tree" + aDef.id.text + "[] children){");
            sb.AppendLine("this.symbol=symbol;");
            foreach (var s in aDef.attrSort.fieldSorts)
            {
                sb.AppendLine("this." + s.Key + "=" + s.Key + ";");
            }
            sb.AppendLine("this.children=children;");
            sb.AppendLine("this.langsLabel = new HashSet<string>();");
            sb.AppendLine("ComputeLabel();");
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("public Tree" + aDef.id.text + " this [int _i]{get { return children[_i]; }}");
            sb.AppendLine();

            sb.Append("public static Tree" + aDef.id.text + " MakeTree(" + aDef.id.text + " symbol");
            foreach (var s in aDef.attrSort.fieldSorts)
            {
                if (s.Value.kind == FastSortKind.Real)
                {
                    sb.Append(", double " + s.Key);
                }
                else
                {
                    sb.Append(", " + s.Value.name + " " + s.Key);
                }
            }
            sb.AppendLine(", Tree" + aDef.id.text + "[] children){");
            sb.AppendLine("if(children.Length==" + aDef.id.text + "Util.getRank(symbol)){");
            sb.Append("Tree" + aDef.id.text + " t = new Tree" + aDef.id.text + "(symbol");
            foreach (var s in aDef.attrSort.fieldSorts)
            {
                sb.Append(", " + s.Key);
            }
            sb.AppendLine(", children);");
            sb.AppendLine("return t;");
            sb.AppendLine("}");
            sb.AppendLine("return null;");
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine();

            return true;
        }
        //Generate the C# corresponding to a particular tree class (inferred from the alphabets)
        private static bool GenerateTreeClass(List<Def> defs, StringBuilder sb, AlphabetDef aDef)
        {
            sb.AppendLine("partial class Tree" + aDef.id.text + "{");
            foreach (var s in aDef.attrSort.fieldSorts)
                if (s.Value.kind == FastSortKind.Real)
                    sb.AppendLine("double " + s.Key + ";");
                else
                    sb.AppendLine(s.Value.name + " " + s.Key + ";");
            sb.AppendLine();
            sb.AppendLine(aDef.id.text + " symbol;");
            sb.AppendLine();
            sb.AppendLine("HashSet<string> langsLabel;");
            sb.AppendLine("Tree" + aDef.id.text + "[] children;");
            sb.AppendLine();

            GenerateConsts(defs, sb);
            GenerateFuns(defs, sb);
            GenerateTrees(defs, sb, aDef);
            GenerateConstructor(sb, aDef);
            GenerateLookahead(defs, sb, aDef);
            GenerateLanguagesAndTransductions(defs, sb, aDef);

            sb.AppendLine("}");
            sb.AppendLine();

            return true;
        }
        //Generate C# for all the consts in the program
        private static bool GenerateTrees(List<Def> defs, StringBuilder sb, AlphabetDef aDef)
        {
            foreach (var def in defs)
                switch (def.kind)
                {
                    case (DefKind.Def):
                        {
                            if(((DefDef)def).ddkind == DefDefKind.Tree)
                                if (((TreeDef)def).domain.name.text.Equals(aDef.id.text))
                                    if (!GenerateTree((TreeDef)def, sb))
                                        return false;
                            break;
                        }
                }

            return true;
        }
        //Generates the code for a particular Transduction (def) in a particular class (aDef)
        private static bool GenerateTransduction(TransDef def, StringBuilder sb, AlphabetDef aDef)
        {
            sb.AppendLine((def.isPublic ? "public" : "private") + " IEnumerable<Tree" + def.range.name + "> " + def.func.name + "(){");
            List<FastToken> children;
            foreach (var ruleCase in def.cases)
            {
                children = ruleCase.pat.children;
                //Check that the constructor is the one of the rule
                sb.AppendLine("if(this.symbol==" + aDef.id + "." + ruleCase.pat.symbol + "){");

                //Check the where condition
                sb.Append("if(");
                PrintExpr(children, ruleCase.where, sb);
                sb.AppendLine("){");

                //Compute the given subsets
                int childPos = 0;
                string childName, langName;
                HashSet<string>[] givenElelements = new HashSet<string>[children.Count];
                for (int i = 0; i < givenElelements.Length; i++)
                    givenElelements[i] = new HashSet<string>();
                //Populate given elements
                foreach (var giv in ruleCase.given)
                {
                    if (giv.kind == FExpKind.App)
                    {
                        langName = ((AppExp)giv).func.name.text;
                        childName = ((AppExp)giv).args[0].token.text;
                        childPos = 0;
                        foreach (var child in children)
                        {
                            if (child.text == childName)
                                break;
                            childPos++;
                        }
                        //Array of sets of langauges
                        if (!givenElelements[childPos].Contains(langName))
                            givenElelements[childPos].Add(langName);
                    }
                }
                //Check given subsets are included in labeling
                bool needsComma;
                int givenUsed = 0;
                for (int i = 0; i < givenElelements.Length; i++)
                {
                    if (givenElelements[i].Count != 0)
                    {
                        sb.Append("if(this.children[" + i + "].langsLabel.IsSupersetOf(new string[] {");
                        needsComma = false;
                        foreach (var lang in givenElelements[i])
                        {
                            if (needsComma)
                                sb.Append(", ");
                            sb.Append("\"" + lang + "\"");
                            needsComma = true;
                        }
                        sb.Append("})){");
                        sb.AppendLine();
                        givenUsed++;
                    }
                }

                iterCases = new List<List<string>>();

                ComputeIterators((AppExp)ruleCase.to, def.range.name.text, sb, false);
                RemoveDuplicates();

                PrintIterators(children, def.range.name.text, sb);
                sb.Append("yield return ");
                PrintOutputTree(children, (AppExp)ruleCase.to, def.range.name.text, sb, false);
                sb.Append(";");

                //Close all parenthesis
                for (int j = 0; j < iterCases.Count; j++)
                    sb.AppendLine("}");
                for (int i = 0; i < givenUsed; i++)
                    sb.AppendLine("}");
                sb.AppendLine("}");
                sb.AppendLine("}");
            }

            //FOR EMPTY RULES CASES
            sb.AppendLine("if(false) yield return null;");
            sb.AppendLine("}");
            sb.AppendLine();
            return true;
        }
 //Generate CSharp for a definition of type TransDefDef
 private static bool GenerateTransductionDefinition(TransDefDef def, StringBuilder sb, AlphabetDef aDef)
 {
     int x;
     sb.AppendLine("public IEnumerable<Tree" + def.range.name + "> " + def.func.name + "(){");
     GenerateDefExpr(def.expr, sb, "this", 0, out x);
     sb.AppendLine("}");
     return true;
 }
        //Generate the Lookahed computation for a particular language definition
        private static bool GenerateLookaheadExpr(LangDef def, StringBuilder sb, AlphabetDef aDef)
        {
            List<FastToken> children;
            foreach (var ruleCase in def.cases)
            {
                children = ruleCase.pat.children;
                sb.AppendLine("if(this.symbol==" + aDef.id.text + "." + ruleCase.pat.symbol + "){");
                sb.Append("if(");
                PrintExpr(children, ruleCase.where, sb);
                sb.AppendLine("){");

                #region Compute the given subsets
                int childPos = 0;
                string childName, langName;
                HashSet<string>[] givenElelements = new HashSet<string>[children.Count];
                for (int i = 0; i < givenElelements.Length; i++)
                    givenElelements[i] = new HashSet<string>();
                #endregion

                #region Populate given elements
                foreach (var giv in ruleCase.given)
                {
                    if (giv.kind == FExpKind.App)
                    {
                        langName = ((AppExp)giv).func.name.text;
                        childName = ((AppExp)giv).args[0].token.text;
                        childPos = 0;
                        foreach (var child in children)
                        {
                            if (child.text == childName)
                                break;
                            childPos++;
                        }
                        //Array of sets of langauges
                        if (!givenElelements[childPos].Contains(langName))
                            givenElelements[childPos].Add(langName);
                    }
                }
                #endregion

                #region Compute lookahead
                bool needsComma;
                int givenUsed = 0;
                for (int i = 0; i < givenElelements.Length; i++)
                {
                    if (givenElelements[i].Count != 0)
                    {
                        sb.Append("if(this.children[" + i + "].langsLabel.IsSupersetOf(new string[] {");
                        needsComma = false;
                        foreach (var lang in givenElelements[i])
                        {
                            if (needsComma)
                                sb.Append(", ");
                            sb.Append("\"" + lang + "\"");
                            needsComma = true;
                        }
                        sb.Append("})){");
                        sb.AppendLine();
                        givenUsed++;
                    }
                }
                sb.AppendLine("this.langsLabel.Add(\"" + def.func.name.text + "\");");
                #endregion

                for (int i = 0; i < givenUsed; i++)
                    sb.AppendLine("}");
                sb.AppendLine("}");
                sb.AppendLine("}");
            }
            sb.AppendLine();
            return true;
        }
 //Generate the Lookahed computation for the tree
 private static bool GenerateLookahead(List<Def> defs, StringBuilder sb, AlphabetDef aDef)
 {
     sb.AppendLine("private void ComputeLabel(){");
     foreach (var def in defs)
     {
         switch (def.kind)
         {
             case (DefKind.Lang):
                 {
                     if ((((LangDef)def).domain.name.text).Equals(aDef.id.text))
                         if (!GenerateLookaheadExpr((LangDef)def, sb, aDef))
                             return false;
                     break;
                 }
         }
     }
     sb.AppendLine("}");
     return true;
 }
        //Generates all the languages and transductions of a particular tree class (correposnding to aDef)
        private static bool GenerateLanguagesAndTransductions(List<Def> defs, StringBuilder sb, AlphabetDef aDef)
        {
            foreach (var def in defs)
            {
                switch (def.kind)
                {
                    case (DefKind.Lang):
                        {
                            if (((LangDef)def).isPublic)
                                if (((LangDef)def).domain.name.text.Equals(aDef.id.text))
                                    if (!GenerateLanguage((LangDef)def, sb))
                                        return false;
                            break;
                        }
                    case (DefKind.Trans):
                        {
                            if (((TransDef)def).domain.name.text.Equals(aDef.id.text))
                                if (!GenerateTransduction((TransDef)def, sb, aDef))
                                    return false;
                            break;
                        }
                    case (DefKind.Def):
                        {
                            if (((DefDef)def).ddkind == DefDefKind.Trans)
                            {
                                if (((TransDefDef)def).domain.name.text.Equals(aDef.id.text))
                                    if (!GenerateTransductionDefinition((TransDefDef)def, sb, aDef))
                                        return false;
                            }
                            else
                            {
                                if (((DefDef)def).ddkind == DefDefKind.Lang)
                                    if (((LangDefDef)def).domain.name.text.Equals(aDef.id.text))
                                        if (!GenerateLanguageDefinition((LangDefDef)def, sb))
                                            return false;
                            }
                            break;
                        }
                }
            }

            return true;
        }
Beispiel #15
0
        internal override void SetConstructorSort(AlphabetDef alph)
        {
            for (int i=0; i < args.Count; i++)
                args[i].SetConstructorSort(alph);

            if (func.name.Kind == Tokens.ID && alph.IsValidSymbol(func.name, func.arity))
            {
                func.alph = alph;
                func.isConstructor = true;
            }
        }
Beispiel #16
0
 internal abstract void CheckSubtreeGuard(Dictionary<string, FastSort> subs, AlphabetDef alph, FastPgm pgm);
Beispiel #17
0
 internal override void CheckSubtreeGuard(Dictionary<string, FastSort> subs, AlphabetDef alph, FastPgm pgm)
 {
     //Double check
     if (!subs.ContainsKey(token.text))
         throw new FastParseException(token.Location, string.Format("unexpected identifier '{0}', expecting a subtree parameter", token.text));
     else
         _sort = subs[token.text];
 }
Beispiel #18
0
 internal abstract void CheckTransformation(HashSet<string> subs, AlphabetDef domAlph, AlphabetDef rangeAlph, FastPgm pgm);
        public RankedAlphabetSort(AlphabetDef def, Z3Provider z3p, FastTransducerInstance fti)
        {
            this.z3p = z3p;

            List<string> alphSymbols = new List<string>();
            List<int> alphArities = new List<int>();

            // Create list of symbols with corresponding arities
            foreach (var sym in def.symbols)
            {
                alphSymbols.Add(sym.name.text);
                alphArities.Add(sym.arity - 1);
            }

            alphFieldsSorts = new List<Sort>();
            tupleKeys = new List<String>();

            foreach (var field in def.attrSort.fieldSorts)
            {
                tupleKeys.Add(field.Key);
                switch (field.Value.kind)
                {
                    case (FastSortKind.Char):
                        {
                            alphFieldsSorts.Add(z3p.CharSort);
                            break;
                        }
                    case (FastSortKind.Real):
                        {
                            alphFieldsSorts.Add(z3p.RealSort);
                            break;
                        }
                    case (FastSortKind.Bool):
                        {
                            alphFieldsSorts.Add(z3p.BoolSort);
                            break;
                        }
                    case (FastSortKind.Int):
                        {
                            alphFieldsSorts.Add(z3p.IntSort);
                            break;
                        }
                    case (FastSortKind.String):
                        {
                            alphFieldsSorts.Add(z3p.MkListSort(z3p.CharSort));
                            break;
                        }
                    case (FastSortKind.Tree):
                        {
                            foreach (var enumSort in fti.enums)
                            {
                                if (enumSort.name == field.Value.name.text)
                                {
                                    alphFieldsSorts.Add(enumSort.sort);
                                    break;
                                }
                            }
                            break;
                        }
                }
            }

            this.tupleName = "$" + def.id.text;
            this.tupleTests = new FuncDecl[alphFieldsSorts.Count];
            var tupsymbs = new Symbol[tupleKeys.Count];
            int j = 0;
            foreach(var v in tupleKeys){
                tupsymbs[j]= z3p.Z3.MkSymbol(v);
                j++;
            }
            var tup = z3p.Z3.MkTupleSort(z3p.Z3.MkSymbol(tupleName), tupsymbs, alphFieldsSorts.ToArray());
            this.tupleSort = tup;
            this.tupleFuncDec = tup.MkDecl;
            this.tupleTests = tup.FieldDecls;

            this.alph = z3p.TT.MkRankedAlphabet(def.id.text, this.tupleSort, alphSymbols.ToArray(), alphArities.ToArray());
            this.alphName = def.id.text;
            this.alphSort = this.alph.AlphabetSort;
        }
        //Generate the C# corresponding to a particular alphabet (using enum)
        private static bool GenerateAlphabet(AlphabetDef def, StringBuilder sb)
        {
            //Generate enum for alphabet
            sb.Append("public enum " + def.id.text + " {");
            foreach (var sym in def.symbols)
            {
                if (def.symbols.First().Equals(sym))
                {
                    sb.Append(sym.name);
                }
                else
                {
                    sb.Append(", " + sym.name);
                }
            }
            sb.AppendLine("}");
            sb.AppendLine();

            sb.AppendLine("class " + def.id.text + "Util {");
            sb.AppendLine("public static int getRank(" + def.id.text + " el){");
            sb.AppendLine("switch(el){");
            foreach (var sym in def.symbols)
            {
                sb.AppendLine("case(" + def.id.text + "." + sym.name + "):{");
                sb.AppendLine("return " + (sym.arity - 1) + ";");
                sb.AppendLine("}");
            }
            sb.AppendLine("}");
            sb.AppendLine("return -1;");
            sb.AppendLine("}");
            sb.AppendLine("}");
            sb.AppendLine();

            return true;
        }