Exemplo n.º 1
0
 public static bool IsOperation(this ParseTreeNode input)
 {
     return(input.IsBinaryOperation() || input.IsUnaryOperation());
 }
Exemplo n.º 2
0
        /// <summary>
        /// Pretty-print a parse tree to a string
        /// </summary>
        public static string Print(this ParseTreeNode input)
        {
            // For terminals, just print the token text
            if (input.Term is Terminal)
            {
                return(input.Token.Text);
            }

            // (Lazy) enumerable for printed children
            var children = input.ChildNodes.Select(Print);
            // Concrete list when needed
            List <string> childrenList;

            // Switch on non-terminals
            switch (input.Term.Name)
            {
            case GrammarNames.Formula:
                // Check if these are brackets, otherwise print first child
                return(IsParentheses(input) ? $"({children.First()})" : children.First());

            case GrammarNames.FunctionCall:
            case GrammarNames.ReferenceFunctionCall:
            case GrammarNames.UDFunctionCall:
                childrenList = children.ToList();

                if (input.IsNamedFunction())
                {
                    return(string.Join("", childrenList) + ")");
                }

                if (input.IsBinaryOperation())
                {
                    // format string for "normal" binary operation
                    string format = "{0} {1} {2}";
                    if (input.IsIntersection())
                    {
                        format = "{0} {2}";
                    }
                    else if (input.IsBinaryReferenceOperation())
                    {
                        format = "{0}{1}{2}";
                    }

                    return(string.Format(format, childrenList[0], childrenList[1], childrenList[2]));
                }

                if (input.IsUnion())
                {
                    return($"({string.Join(",", childrenList)})");
                }

                if (input.IsUnaryOperation())
                {
                    return(string.Join("", childrenList));
                }

                throw new ArgumentException("Unknown function type.");

            case GrammarNames.Reference:
                return(IsParentheses(input) ? $"({children.First()})" : string.Concat(children));

            case GrammarNames.Prefix:
                var ret = string.Join("", children);
                // The exclamation mark token is not included in the parse tree, so we have to add that if it's a single file
                if (input.ChildNodes.Count == 1 && input.ChildNodes[0].Is(GrammarNames.File))
                {
                    ret += "!";
                }
                return(ret);

            case GrammarNames.ArrayFormula:
                return("{=" + children.ElementAt(1) + "}");

            case GrammarNames.StructuredReference:
                var sb           = new StringBuilder();
                var hashtable    = input.ChildNodes.Count >= 1 && input.ChildNodes[0].Is(GrammarNames.StructuredReferenceTable);
                var contentsNode = hashtable ? 1 : 0;
                childrenList = children.ToList();
                if (hashtable)
                {
                    sb.Append(childrenList[0]);
                }

                if (hashtable && input.ChildNodes.Count == 1)
                {
                    // Full table reference
                    sb.Append("[]");
                }
                else if (input.ChildNodes[contentsNode].Is(GrammarNames.StructuredReferenceElement))
                {
                    sb.Append(childrenList[contentsNode]);
                }
                else
                {
                    sb.Append($"[{childrenList[contentsNode]}]");
                }

                return(sb.ToString());

            // Terms for which to print all child nodes concatenated
            case GrammarNames.ArrayConstant:
            case GrammarNames.DynamicDataExchange:
            case GrammarNames.FormulaWithEq:
            case GrammarNames.File:
            case GrammarNames.StructuredReferenceExpression:
                return(string.Join("", children));

            // Terms for which we print the children comma-separated
            case GrammarNames.Arguments:
            case GrammarNames.ArrayRows:
            case GrammarNames.Union:
                return(string.Join(",", children));

            case GrammarNames.ArrayColumns:
                return(string.Join(";", children));

            case GrammarNames.ConstantArray:
                return($"{{{children.First()}}}");

            default:
                // If it is not defined above and the number of children is exactly one, we want to just print the first child
                if (input.ChildNodes.Count == 1)
                {
                    return(children.First());
                }

                throw new ArgumentException($"Could not print node of type '{input.Term.Name}'." + Environment.NewLine +
                                            "This probably means the Excel grammar was modified without the print function being modified");
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Pretty-print a parse tree to a string
        /// </summary>
        public static string Print(this ParseTreeNode input)
        {
            // For terminals, just print the token text
            if (input.Term is Terminal)
            {
                return(input.Token.Text);
            }

            // (Lazy) enumerable for printed childs
            var childs = input.ChildNodes.Select(Print);
            // Concrete list when needed
            List <String> childsL;

            // Switch on nonterminals
            switch (input.Term.Name)
            {
            case GrammarNames.Formula:
                // Check if these are brackets, otherwise print first child
                return(IsParentheses(input) ? String.Format("({0})", childs.First()) : childs.First());

            case GrammarNames.FunctionCall:
            case GrammarNames.ReferenceFunctionCall:
            case GrammarNames.UDFunctionCall:
                childsL = childs.ToList();

                if (input.IsNamedFunction())
                {
                    return(String.Join("", childsL) + ")");
                }

                if (input.IsBinaryOperation())
                {
                    // format string for "normal" binary operation
                    string format = "{0} {1} {2}";
                    if (input.IsIntersection())
                    {
                        format = "{0} {2}";
                    }
                    else if (input.IsBinaryReferenceOperation())
                    {
                        format = "{0}{1}{2}";
                    }

                    return(String.Format(format, childsL[0], childsL[1], childsL[2]));
                }

                if (input.IsUnion())
                {
                    return(String.Format("({0})", String.Join(",", childsL)));
                }

                if (input.IsUnaryOperation())
                {
                    return(String.Join("", childsL));
                }

                throw new ArgumentException("Unknown function type.");

            case GrammarNames.Reference:
                /*if (IsParentheses(input) || IsUnion(input))
                 * {
                 *  return String.Format("({0})", childs.First());
                 * }
                 *
                 * childsL = childs.ToList();
                 * if (IsIntersection(input))
                 * {
                 *  return String.Format("{0} {1}", childsL[0], childsL[2]);
                 * }
                 *
                 * if (IsBinaryOperation(input))
                 * {
                 *  return String.Format("{0}{1}{2}", childsL[0], childsL[1], childsL[2]);
                 * }*/
                if (IsParentheses(input))
                {
                    return(String.Format("({0})", childs.First()));
                }

                return(String.Join("", childs));

            case GrammarNames.File:
                return(String.Format("[{0}]", childs.First()));

            case GrammarNames.Prefix:
                var ret = String.Join("", childs);
                // The exclamation mark token is not included in the parse tree, so we have to add that if it's a single file
                if (input.ChildNodes.Count == 1 && input.ChildNodes[0].Is(GrammarNames.File))
                {
                    ret += "!";
                }
                return(ret);

            case GrammarNames.ArrayFormula:
                return("{=" + childs.ElementAt(1) + "}");

            case GrammarNames.DynamicDataExchange:
                childsL = childs.ToList();
                return(String.Format("{0}!{1}", childsL[0], childsL[1]));

            // Terms for which to print all child nodes concatenated
            case GrammarNames.ArrayConstant:
            case GrammarNames.FormulaWithEq:
                return(String.Join("", childs));

            // Terms for which we print the childs comma-separated
            case GrammarNames.Arguments:
            case GrammarNames.ArrayRows:
            case GrammarNames.Union:
                return(String.Join(",", childs));

            case GrammarNames.ArrayColumns:
                return(String.Join(";", childs));

            case GrammarNames.ConstantArray:
                return(String.Format("{{{0}}}", childs.First()));


            default:
                // If it is not defined above and the number of childs is exactly one, we want to just print the first child
                if (input.ChildNodes.Count == 1)
                {
                    return(childs.First());
                }
                throw new ArgumentException(String.Format("Could not print node of type '{0}'.\nThis probably means the excel grammar was modified without the print function being modified", input.Term.Name));
            }
        }