/// <summary> /// Change a C# parse tree to a F# AST /// </summary> public static FSharpTransform.Formula CreateFSharpTree(this ParseTreeNode input) { if (input.IsParentheses()) { return(FSharpTransform.Formula.NewFunction("", ListModule.OfSeq(new [] { CreateFSharpTree(input.ChildNodes[0]) }))); } input = input.SkipToRelevant(); switch (input.Type()) { case GrammarNames.FunctionCall: case GrammarNames.ReferenceFunctionCall: case GrammarNames.UDFunctionCall: var fname = input.GetFunction() + (input.IsNamedFunction()?"(":""); var args = ListModule.OfSeq(input.GetFunctionArguments().Select(CreateFSharpTree)); // Check for range if (fname == ":") { return(makeFSharpRange(input)); } return(FSharpTransform.makeFormula(fname, args)); case GrammarNames.Reference: // ignore prefix return(CreateFSharpTree(input.ChildNodes.Count == 1 ? input.ChildNodes[0] : input.ChildNodes[1])); case GrammarNames.Cell: var L = new Location(input.Print()); return(FSharpTransform.makeSuperCell(FSharpTransform.makeCell(L.Column, L.Row))); case GrammarNames.NamedRange: return(FSharpTransform.makeNamedRange(input.Print())); case TransformationRuleGrammar.Names.DynamicCell: //get variables from dynamic cell return(FSharpTransform.makeSuperCell(GetDynamicCell(input))); case TransformationRuleGrammar.Names.DynamicRange: var letter = input // DynamicRange .ChildNodes[0] // LowLetter .Token.ValueString[0]; return(FSharpTransform.makeDRange(letter)); case GrammarNames.Constant: case GrammarNames.Number: case GrammarNames.Text: case GrammarNames.Bool: case GrammarNames.Error: case GrammarNames.RefError: return(FSharpTransform.makeConstant(input.Print())); case TransformationRuleGrammar.Names.DynamicConstant: return(FSharpTransform.makeDArgument(input.ChildNodes[0].Token.ValueString[1])); default: throw new ArgumentException($"Can't convert node type {input.Type()}", nameof(input)); } }
protected override IEnumerable <Index> VisitReferenceFunctionCall(ParseTreeNode node) { var function = node.GetFunction(); switch (function) { case ":": return(ReferenceRange(node.ChildNodes[0], node.ChildNodes[2])); default: throw new InvalidOperationException(); } }
private static bool IsTargetFunction(ParseTreeNode node) { return // Not interested in not-functions (node.IsNamedFunction() // Or functions without arguments && node.ChildNodes[1].ChildNodes.Any() && (varargsFunctions.Contains(node.GetFunction()) // Functions have an arrayasargument parameter || node.GetFunctionArguments().Any(n => n.SkipToRelevant().IsUnion()) ) ); }
private int OperatorDepth(ParseTreeNode node, ISet <string> operators = null) { // Get the maximum depth of the childnodes int depth = node.ChildNodes.Count == 0 ? 0 : node.ChildNodes.Max(n => OperatorDepth(n, operators)); // If this is one of the target functions, increase depth by 1 if (node.IsFunction() && (operators == null || operators.Contains(node.GetFunction()))) { depth++; } return(depth); }
protected override IEnumerable <Index> VisitFunctionCall(ParseTreeNode node) { var function = node.GetFunction().ToUpper(); switch (function) { case "+": return(VisitNodes(node.GetFunctionArguments())); case "-": return(VisitNodes(node.GetFunctionArguments())); case "*": return(VisitNodes(node.GetFunctionArguments())); case "/": return(VisitNodes(node.GetFunctionArguments())); case "SUM": return(VisitNodes(node.GetFunctionArguments())); default: throw new ArgumentException("node"); } }
private int OperatorDepth(ParseTreeNode node, ISet<string> operators = null) { // Get the maximum depth of the childnodes int depth = node.ChildNodes.Count == 0 ? 0 : node.ChildNodes.Max(n => OperatorDepth(n, operators)); // If this is one of the target functions, increase depth by 1 if(node.IsFunction() && (operators == null || operators.Contains(node.GetFunction()))) { depth++; } return depth; }
internal static string GetBinOp(ParseTreeNode node) { node = node.SkipToRelevant(); return(!node.IsBinaryNonReferenceOperation() ? "" : node.GetFunction()); }