private string wrapStartProductions(string startSymbol, Dictionary <string, List <ProductionInfo> > productionsDict)
        {
            string new_start = grammar.RegisterNewSymbol("__start_" + startSymbol, grammar.GetTypeNameOfSymbol(startSymbol));

            var prod = new ProductionInfo(SymbolPosition.None,
                                          new_start,
                                          RecursiveEnum.No,
                                          new[] { new RhsSymbol(SymbolPosition.None, null, startSymbol) },
                                          null);

            var param = FuncParameter.Create(startSymbol, grammar.TreeNodeName, dummy: false);

            // this code is really an identity call
            prod.ActionCode = CodeLambda.CreateProxy(new_start,
                                                     // parameters
                                                     new FuncParameter[] { param },
                                                     grammar.TreeNodeName,
                                                     functionsRegistry.Add(FunctionRegistry.IdentityFunction(new_start)),
                                                     // its arguments
                                                     new [] { param.NameAsCode() });

            productionsDict.Add(new_start, new List <ProductionInfo> {
                prod
            });

            return(new_start);
        }
Esempio n. 2
0
        public IList <FuncParameter> LoadFuncParameter(string catalogs)
        {
            string sql = @"SELECT f.funcname,p.pindex,p.pname,p.displayname,p.datatype,p.droplistId,p.edittype,d.code 
                   FROM rpt_func_param p,rpt_func f,rpt_droplist d WHERE p.funcphid = f.phid 
                    AND d.phid = p.droplistid AND f.catalogid IN ({0}) ORDER BY f.catalogid,f.funcname,p.pindex ";

            sql = string.Format(sql, catalogs);
            var datas = this.QueryForDataTable(sql);

            if (datas == null)
            {
                throw new FuncException("无法从数据库加载公式参数信息");
            }

            IList <FuncParameter> funcParamList = new List <FuncParameter>();

            foreach (DataRow dr in datas.Rows)
            {
                FuncParameter paramInfo = new FuncParameter();

                paramInfo.FuncName        = dr["funcname"].TryGetString();
                paramInfo.Name            = dr["pname"].TryGetString();
                paramInfo.Index           = dr["pindex"].TryGetInt();
                paramInfo.DisplayProperty = dr["displayname"].TryGetString();
                paramInfo.ParamType       = dr["datatype"].TryGetString();
                paramInfo.DroplistCode    = dr["code"].TryGetString();     //下拉名称
                paramInfo.EditType        = dr["edittype"].TryGetString(); //下拉类型

                funcParamList.Add(paramInfo);
            }
            return(funcParamList);
        }
Esempio n. 3
0
        private void FunctionParameter_Load(object sender, EventArgs e)
        {
            cmbTipo.DataSource     = Enum.GetValues(typeof(DataTypes));
            cmbMecanism.DataSource = Enum.GetValues(typeof(MechanismFunctionParameter));
            Parametro              = new FuncParameter();
            cmbMecanism.Enabled    = false;
            numericUpDown1.Enabled = false;

            if (Padre.Funcion.Parametros.Find(x => x.IsReturn) == null)
            {
                chkIsReturn.Enabled = true;
            }
            else
            {
                chkIsReturn.Enabled = false;
            }
        }
Esempio n. 4
0
        public static IList <FuncInfo> GetFuncs(string xml)
        {
            IList <FuncInfo> funcInfos = new List <FuncInfo>();

            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(xml);

            var xmlFuncs = xmlDoc.SelectNodes("/root/Functions/Function");

            foreach (XmlNode node in xmlFuncs)
            {
                XmlElement xmlFunc = node as XmlElement;

                FuncInfo funcInfo = new FuncInfo();
                string   funcName = xmlFunc.GetAttribute("name");//函数名称
                funcInfo.Name = funcName;

                //函数参数
                var xmlFuncParams = xmlFunc.ChildNodes;
                int index         = 0;
                IList <FuncParameter> paramList = new List <FuncParameter>();
                foreach (var p in xmlFuncParams)
                {
                    XmlElement xmlParam = p as XmlElement;

                    FuncParameter funcParam = new FuncParameter();
                    funcParam.Value     = xmlParam.InnerText;
                    funcParam.ParamType = xmlParam.GetAttribute("dataType");
                    funcParam.FuncName  = funcName;
                    funcParam.Index     = index;

                    paramList.Add(funcParam);

                    index++;
                }
                funcInfo.Paras = paramList;

                funcInfos.Add(funcInfo);
            }
            return(funcInfos);
        }
Esempio n. 5
0
        private string registerLambda(string lhsSymbol,
                                      IEnumerable <string> inputTypeNames,
                                      string outputTypeName,
                                      // each pair holds real name (like "expr") and (as backup) dummy name, like "_2"
                                      IEnumerable <Tuple <string, string> > arguments,
                                      CodeBody body)
        {
            if (inputTypeNames.Count() != arguments.Count())
            {
                throw new ArgumentException("Creating a function -- types count vs. arguments count mismatch.");
            }

            CodeLambda lambda = null;

            // identity function, i.e. f(x) = x, we check only real name, if it was a dummy name, it would be
            if (arguments.Count() == 1)
            {
                if (arguments.Single().Item1 == body.Make().Trim())
                {
                    lambda = FunctionRegistry.IdentityFunction(lhsSymbol);
                }
                else if (arguments.Single().Item2 == body.Make().Trim())
                {
                    throw new InvalidOperationException("Somehow dummy name which should not exist was referenced.");
                }
            }

            if (lambda == null)
            {
                lambda = new CodeLambda(lhsSymbol, arguments.SyncZip(inputTypeNames)
                                        .Select(it => FuncParameter.Create(it.Item1.Item1, it.Item1.Item2, it.Item2)),
                                        outputTypeName,
                                        body);
            }

            return(functionsRegistry.Add(lambda));
        }
        /// <summary>
        /// Extracts data for a binary expression
        /// </summary>
        /// <param name="myComplexValue">The complex part of the binary expression.</param>
        /// <param name="mySimpleValue">The simple/atomic part of the expression.</param>
        /// <param name="errors">The list of errors.</param>
        /// <param name="typeOfBinExpr">The kind of the binary expression</param>
        /// <returns>A data tuple.</returns>
        private static DataContainer ExtractData(AExpressionDefinition myComplexValue,
                                                 AExpressionDefinition mySimpleValue,
                                                 ref TypesOfBinaryExpression typeOfBinExpr,
                                                 GQLPluginManager myPluginManager,
                                                 IGraphDB myGraphDB,
                                                 SecurityToken mySecurityToken,
                                                 Int64 myTransactionToken,
                                                 Boolean aggregateAllowed)
        {
            #region data

            //the complex IDNode (sth. like U.Age or Count(U.Friends))
            IDChainDefinition complexIDNode = null;

            //the value that is on the opposite of the complex IDNode
            AExpressionDefinition simpleValue = null;

            //a complex IDNode may result in a complexValue (i.e. Count(U.Friends) --> 3)
            AExpressionDefinition complexValue = null;

            //reference to former myComplexValue
            AExpressionDefinition extraordinaryValue = null;

            #endregion

            #region extraction

            if (myComplexValue is IDChainDefinition)
            {
                #region IDNode

                #region Data

                complexIDNode = (IDChainDefinition)myComplexValue;
                complexIDNode.Validate(myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, false);
                if (complexIDNode.Any(id => id is ChainPartFuncDefinition))
                {
                    if (complexIDNode.Edges == null || complexIDNode.Edges.Count == 0)
                    {
                        #region parameterless function

                        var fcn = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition);

                        // somes functions (aggregates) like SUM are not valid for where expressions, though they are not resolved
                        if (fcn.Function == null)
                        {
                            throw new FunctionDoesNotExistException(fcn.FuncName);
                        }

                        FuncParameter pResult = fcn.Function.ExecFunc(null, null, null, myGraphDB, mySecurityToken, myTransactionToken);

                        //simpleValue = new AtomValue(fcn.Function.TypeOfResult, ((FuncParameter)pResult.Value).Value); //the new simple value extraced from the function
                        simpleValue   = new ValueDefinition(((FuncParameter)pResult).Value);
                        typeOfBinExpr = TypesOfBinaryExpression.Unknown; //we do not know if we are left or right associated
                        complexIDNode = null;                            //we resolved it... so it's null

                        #endregion
                    }
                    else
                    {
                        //extraordinaryValue = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition);
                        extraordinaryValue = complexIDNode;

                        if (mySimpleValue is ValueDefinition)
                        {
                            simpleValue = mySimpleValue;
                        }
                    }
                }
                else
                {
                    if (mySimpleValue is ValueDefinition)
                    {
                        try
                        {
                            if (complexIDNode.IsUndefinedAttribute)
                            {
                                throw new VertexAttributeIsNotDefinedException(complexIDNode.UndefinedAttribute);
                            }

                            simpleValue = GetCorrectValueDefinition(complexIDNode.LastAttribute, complexIDNode.LastType, ((ValueDefinition)mySimpleValue));
                        }
                        catch (FormatException)
                        {
                            throw new DataTypeDoesNotMatchException(((IPropertyDefinition)complexIDNode.LastAttribute).BaseType.Name, ((ValueDefinition)mySimpleValue).Value.GetType().Name);
                        }
                    }
                    else
                    {
                        if (mySimpleValue is TupleDefinition)
                        {
                            ((TupleDefinition)mySimpleValue).ConvertToAttributeType(myPluginManager, complexIDNode.LastAttribute, myGraphDB, mySecurityToken, myTransactionToken);

                            simpleValue = mySimpleValue;
                        }
                    }
                }

                #endregion


                #endregion
            }
            else if (myComplexValue is TupleDefinition)
            {
                #region TupleSetNode

                complexValue  = ((TupleDefinition)myComplexValue);
                simpleValue   = mySimpleValue;
                typeOfBinExpr = TypesOfBinaryExpression.Atom;

                #endregion
            }
            else if (myComplexValue is AggregateDefinition)
            {
                #region AggregateNode

                if (aggregateAllowed)
                {
                    if (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters.Count != 1)
                    {
                        throw new GQLAggregateArgumentException("An aggregate must have exactly one expression.");
                    }

                    if (!(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] is IDChainDefinition))
                    {
                        throw new GQLAggregateArgumentException("An aggregate must have exactly one IDNode.");
                    }

                    #region Data

                    complexIDNode = (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] as IDChainDefinition);

                    if (complexIDNode == null)
                    {
                        throw new InvalidIDNodeException("Only single IDNodes are currently allowed in aggregates!");
                    }

                    #endregion

                    #region values

                    simpleValue        = mySimpleValue;
                    extraordinaryValue = myComplexValue;

                    #endregion
                }
                else
                {
                    throw new AggregateNotAllowedException(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Aggregate.PluginShortName);
                }
                #endregion
            }
            else
            {
                throw new NotImplementedQLException("");
            }

            #endregion

            return(new DataContainer(new Tuple <IDChainDefinition, IDChainDefinition>(complexIDNode, null),
                                     new Tuple <AExpressionDefinition, AExpressionDefinition>(simpleValue, complexValue),
                                     new Tuple <AExpressionDefinition, AExpressionDefinition>(extraordinaryValue, null)));
        }
Esempio n. 7
0
 public FuncParameter(FuncParameter old, string value)
 {
     this.Name  = old.Name;
     this.Value = value;
 }
Esempio n. 8
0
 public static CodeLambda IdentityFunction(string lhs)
 {
     // we are creating effectivelly singleton identity function, not 100% though, because
     // in case of struct instances it would lead to boxing/unboxing, BUT... TREE_NODE in NLT has to be "class"
     return(new CodeLambda(lhs, new[] { FuncParameter.Create("x", "object", dummy: false) }, "object", new CodeBody().AddIdentifier("x")));
 }
        private void substituteProductions(Dictionary <string, List <ProductionInfo> > productionsDict,
                                           ProductionInfo[] substitutes, // same LHS
                                           bool mixWithSource)
        {
            // this function is part of optimization of given production rules

            // we could have case, that sub production is marked and the one where there is replacement as well
            // in such case which marking to choose? so we don't allow substitutes to have markings
            if (substitutes.Any(it => it.IsMarked))
            {
                throw new ArgumentException();
            }

            string sub_lhs = substitutes.Select(it => it.LhsSymbol).Distinct().Single(); // making sure LHS symbol is the same

            Console.WriteLine("Substituting " + sub_lhs);

            foreach (string lhs in productionsDict.Keys.ToArray())
            {
                var replacements = new List <ProductionInfo>();

                foreach (ProductionInfo prod in productionsDict[lhs])
                {
                    // nothing to replace
                    if (!prod.RhsSymbols.Any(it => it.SymbolName.Equals(sub_lhs)))
                    {
                        replacements.Add(prod);
                    }
                    else
                    {
                        // -1 -- use original symbol, >=0 -- substitute (the value is the index of substitution)
                        IEnumerable <CycleCounter> counters = prod.RhsSymbols.ZipWithIndex()
                                                              .Select(it =>
                        {
                            bool hit = it.Item1.SymbolName.Equals(sub_lhs);
                            return(new CycleCounter(((!hit || mixWithSource) ? -1 : 0), (hit ? substitutes.Length : 0), it.Item2));
                        }).ToArray();

                        // we have initial run only in case if we mix substitutions with original production, otherwise it pure substitution
                        bool pass_first_as_source = mixWithSource;

                        do
                        {
                            if (pass_first_as_source)
                            {
                                pass_first_as_source = false;
                                if (!counters.All(it => it.Value == -1))
                                {
                                    throw new Exception("Oops, something wrong.");
                                }

                                // it is simply better to add original production instead of re-creating it from symbols
                                // after all, for every rhs symbol we would have -1 value, meaning "use original"
                                replacements.Add(prod);
                                continue;
                            }

                            var p = new ProductionInfo(prod.Position,
                                                       prod.LhsSymbol,
                                                       prod.Recursive,
                                                       counters.SyncZip(prod.RhsSymbols)
                                                       .Select(it => it.Item1.Value == -1 ? new[] { it.Item2 } : substitutes[it.Item1.Value].RhsSymbols).Flatten(),
                                                       prod.PassedMarkedWith);

                            // if there was no action code, no point of building proxy for it
                            if (prod.ActionCode != null)
                            {
                                FuncCallCode func_call = (FuncCallCode)(prod.ActionCode.Body);

                                // do not rename those parameters which have counter == -1
                                IEnumerable <Tuple <FuncParameter, int>[]> parameters = null;

                                parameters = counters.SyncZip(prod.ActionCode.Parameters)
                                             .Select(cit => cit.Item1.Value == -1 ? new[] { Tuple.Create(cit.Item2, cit.Item1.Index) }
                                          : substitutes[cit.Item1.Value].ActionCode.Parameters.Select(x => Tuple.Create(x, cit.Item1.Index)).ToArray())
                                             .ToArray();

                                // only subsituted parameters are renamed
                                Dictionary <Tuple <FuncParameter, int>, FuncParameter> param_map
                                    = FuncParameter.BuildParamMapping(parameters.Flatten());

                                p.ActionCode = CodeLambda.CreateProxy(lhs + "_sub__",
                                                                      // parameters
                                                                      parameters.Flatten().Select(it => param_map[it]),

                                                                      prod.ActionCode.ResultTypeName,
                                                                      functionsRegistry.Add(prod.ActionCode),

                                                                      // arguments
                                                                      counters.SyncZip(parameters)
                                                                      .Select(cit => cit.Item1.Value == -1 ? param_map[cit.Item2.Single()].NameAsCode()
                                                : new FuncCallCode(functionsRegistry.Add(substitutes[cit.Item1.Value].ActionCode),
                                                                   cit.Item2.Select(x => param_map[x].NameAsCode())))
                                                                      );
                            }
                            replacements.Add(p);
                        }while (counters.Iterate());
                    }
                }
                productionsDict[lhs] = replacements;
            }
        }
        private ProductionInfo makeBuilderCall(string lhsSymbol,
                                               RecursiveEnum recursive,
                                               AltRule alt,
                                               IEnumerable <SymbolMarked> symbolsMarked,
                                               string treeNodeName)
        {
            // add production with no code
            var prod_info = new ProductionInfo(alt.Position, lhsSymbol, recursive, symbolsMarked.Where(it => it.IsEnabled).Select(it => it.Symbol),
                                               alt.MarkWith);

            CodeBody code_body = null;

            if (alt.Code != null)
            {
                code_body = (alt.Code as CodeMix).BuildBody(symbolsMarked.Where(sym => sym.Symbol.ObjName != null)
                                                            .Select(sym => sym.Symbol.GetCodeArgumentNames().Select(it => Tuple.Create(it, sym.IsEnabled))).Flatten())
                            .Trim();

                string identity_function_on = null;
                // are we just passing one of the parameters?
                if (code_body.IsIdentity)
                {
                    identity_function_on = code_body.IdentityIdentifier;
                }

                foreach (string var_name in code_body.GetVariables())
                {
                    SymbolMarked sym = symbolsMarked
                                       .Where(sm => sm.Symbol.GetCodeArgumentNames().Contains(var_name))
                                       // there could be duplicates so we "prefer" enabled element
                                       .OrderBy(it => it.IsEnabled ? 0 : 1)
                                       .FirstOrDefault();

                    if (sym != null)
                    {
                        sym.IsParamUsed = true;
                    }
                }

                var anon_args = new Dictionary <SymbolMarked, string>();
                foreach (Tuple <SymbolMarked, int> sym_pair in symbolsMarked.ZipWithIndex())
                {
                    if (sym_pair.Item1.Symbol.ObjName == null)
                    {
                        anon_args.Add(sym_pair.Item1, code_body.RegisterNewIdentifier("_" + sym_pair.Item2));
                    }
                }

                IEnumerable <SymbolMarked> arg_symbols = symbolsMarked.Where(it => it.IsEnabled || it.IsParamUsed).ToList();

                // build external function to run the user code
                string func_ref = registerLambda(lhsSymbol,
                                                 arg_symbols.Select(sym => sym.Symbol.GetCodeArgumentTypes(grammar)).Flatten(),
                                                 grammar.TreeNodeName,
                                                 arg_symbols.Select(sym => sym.Symbol.GetCodeArgumentNames()
                                                                    .Select(it => Tuple.Create(it, anon_args.GetOrNull(sym)))).Flatten(),
                                                 code_body);

                // build a lambda with call to a just built function
                // note that our lambda can have fewer arguments than the actual fuction
                // in such case we pass "nulls" for disabled arguments

                // we add nulls to params in order to keep track which arguments comes from which parameters
                IEnumerable <FuncParameter> lambda_params = arg_symbols.Where(it => it.IsEnabled)
                                                            .Select(it => FuncParameter.Create(it.Symbol.ObjName, anon_args.GetOrNull(it), grammar.GetTypeNameOfSymbol(it.Symbol))).ToArray();

                // if the code indicates that this is identity function, then just find out which parameter is passed along
                if (identity_function_on != null)
                {
                    // we can fail for two reasons here:
                    // (1) ok -- single variable we found in the code body is not a parameter, but global variable
                    // (2) BAD -- we have case of unpacking the data, and that case so far we cannot handle
                    // ad.2) consider such rule as
                    // x -> (a b)+ { b };
                    // "a" and "b" will be handled as tuple of lists
                    // so in entry function we will get a tuple, and then we will call actuall user action code
                    // some "__function_13__(a,b)" which returns the "b"
                    // so we could compute index for inner parameter (for "b" it is 1)
                    // but we cannot compute index for outer function, because there is no index for "b" at all
                    // there is only one parameter -- tuple -- holding "a" (in Item1) and "b" (in Item2) at the same time
                    // so if anything we would have to introduce some combo index:
                    // outer index --> optional unpacking index --> inner index
                    // too much trouble for now
                    Option <int> index = lambda_params.Select(it => it.Name)
                                         .ZipWithIndex().Where(it => it.Item1 == identity_function_on).Select(it => it.Item2).OptSingle();
                    if (index.HasValue)
                    {
                        prod_info.IdentityOuterFunctionParamIndex = index.Value;
                    }
                }

                prod_info.ActionCode = CodeLambda.CreateProxy(
                    lhsSymbol,
                    // lambda arguments
                    lambda_params,
                    treeNodeName,
                    func_ref,

                    arg_symbols.Select(arg => arg.Symbol.CombinedSymbols == null
                                       // regular symbols
                        ? new[] { new CodeBody().AddIdentifier(arg.IsEnabled ? (arg.Symbol.ObjName ?? anon_args[arg]) : CodeWords.Null) }
                                       // compound symbols, we have to use embedded atomic symbols instead now
                        : arg.Symbol.UnpackTuple(arg.IsEnabled)
                                       )
                    .Flatten());

                prod_info.CodeComment = alt.Code.Comment;
            }

            return(prod_info);
        }
Esempio n. 11
0
 public void RefrescarParametros(FuncParameter parametro)
 {
     _parametrosBindingList.Add(parametro);
 }