Пример #1
0
 private void WritePrefixOperatorNode(ComposedTokenStream tokenStream, TexExpressionNode node,
                                      ComposerState state)
 {
     if (node.Children.Count >= 1)
     {
         tokenStream.Write(TexToken.FromSymbol(node.Symbol));
         foreach (var argNode in node.Arguments)
         {
             if (argNode.Children.Count != 1)
             {
                 throw new TexComposerException(argNode, string.Format(
                                                    errorMessageUnexpectedNumberOfChildren, argNode.Symbol, argNode.Children.Count));
             }
             tokenStream.Write(TexToken.FromSymbol(argNode.Symbol));
             WriteNode(tokenStream, argNode.Children[0], state);
         }
         tokenStream.Write(TexToken.FromSymbol(TexSymbolKind.Space));
         foreach (var childNode in node.Children)
         {
             WriteNode(tokenStream, childNode, state);
         }
     }
     else
     {
         throw new TexComposerException(node, string.Format(
                                            errorMessageUnexpectedNumberOfChildren, node.Symbol, node.Children.Count));
     }
 }
Пример #2
0
        private int GetOperatorPrecedence(TexExpressionNode node)
        {
            // Higher value means higher precedence.
            switch (node.Symbol)
            {
            case TexSymbolKind.Plus:
            case TexSymbolKind.Minus:
            case TexSymbolKind.PlusMinus:
            case TexSymbolKind.MinusPlus:
                if (node.Children.Count == 1)
                {
                    return(3);
                }
                return(2);

            case TexSymbolKind.Star:
            case TexSymbolKind.Dot:
            case TexSymbolKind.Cross:
            case TexSymbolKind.Divide:
            case TexSymbolKind.Fraction:
            case TexSymbolKind.InlineModulo:
                return(4);

            case TexSymbolKind.RaiseToIndex:
            case TexSymbolKind.LowerToIndex:
                return(5);

            default:
                if (node.Symbol.IsRelationOperator())
                {
                    return(1);
                }
                return(-1);
            }
        }
        private static TexExpressionNode FromInfixOperatorParseNode(ParseNode parseNode)
        {
            if (parseNode.Children.Count == 1)
            {
                return(FromParseTree(parseNode.Children[0]));
            }
            else if (parseNode.Children.Count == 3)
            {
                var node = new TexExpressionNode(parseNode.Children[1].Token.Symbol);
                node.Children.Add(FromParseTree(parseNode.Children[0]));
                node.Children.Add(FromParseTree(parseNode.Children[2]));

                // If node is root of sub-expression and operator is left-recursive, then convert sub-tree from right
                // recursive to left recursive.
                if (!parseNode.IsSubExpression && node.Symbol.IsLtrInfixOperator())
                {
                    return(ConvertTreeToLeftRecursive(node, parseNode));
                }
                else
                {
                    return(node);
                }
            }

            throw new TexExpressionTreeBuilderException(parseNode, string.Format(
                                                            errorMessageUnexpectedNumberOfChildren, parseNode.Kind, parseNode.Children.Count));
        }
        private static IEnumerable <TexExpressionNode> FromPrefixOperatorIndicesParseNode(ParseNode parseNode)
        {
            TexExpressionNode indexNode = null;

            if (parseNode.Children.Count == 0)
            {
                yield break;
            }
            else if (parseNode.Children.Count == 2)
            {
                indexNode = new TexExpressionNode(parseNode.Children[0].Token.Symbol);
                indexNode.Children.Add(FromParseTree(parseNode.Children[1]));
                yield return(indexNode);

                yield break;
            }
            else if (parseNode.Children.Count == 4)
            {
                indexNode = new TexExpressionNode(parseNode.Children[0].Token.Symbol);
                indexNode.Children.Add(FromParseTree(parseNode.Children[1]));
                yield return(indexNode);

                indexNode = new TexExpressionNode(parseNode.Children[2].Token.Symbol);
                indexNode.Children.Add(FromParseTree(parseNode.Children[3]));
                yield return(indexNode);

                yield break;
            }

            throw new TexExpressionTreeBuilderException(parseNode, string.Format(
                                                            errorMessageUnexpectedNumberOfChildren, parseNode.Kind, parseNode.Children.Count));
        }
Пример #5
0
 private void WriteBracketedFunction(ComposedTokenStream tokenStream, TexExpressionNode node,
                                     ComposerState state)
 {
     if (node.Children.Count >= 1)
     {
         tokenStream.Write(TexToken.FromSymbol(node.Symbol));
         foreach (var argNode in node.Arguments)
         {
             tokenStream.Write(TexToken.FromSymbol(TexSymbolKind.SquareBracketOpen));
             state.IsParentNodeGroupOpen = true;
             WriteNode(tokenStream, argNode, state);
             tokenStream.Write(TexToken.FromSymbol(TexSymbolKind.SquareBracketClose));
         }
         foreach (var childNode in node.Children)
         {
             tokenStream.Write(TexToken.FromSymbol(TexSymbolKind.GroupOpen));
             state.IsParentNodeGroupOpen = true;
             WriteNode(tokenStream, childNode, state);
             tokenStream.Write(TexToken.FromSymbol(TexSymbolKind.GroupClose));
         }
     }
     else
     {
         throw new TexComposerException(node, string.Format(
                                            errorMessageUnexpectedNumberOfChildren, node.Symbol, node.Children.Count));
     }
 }
Пример #6
0
 public TokenStream Write(TexExpressionNode node)
 {
     using (var tokenStream = new ComposedTokenStream())
     {
         WriteNode(tokenStream, node, new ComposerState());
         return(tokenStream);
     }
 }
Пример #7
0
 private bool IsRightMostNode(TexExpressionNode node)
 {
     if (node.Parent == null)
     {
         return(true);
     }
     return(node.Parent.Children.IndexOf(node) == node.Parent.Children.Count &&
            IsRightMostNode(node.Parent));
 }
        private static TexExpressionNode ConvertTreeToLeftRecursive(TexExpressionNode node, ParseNode parseNode)
        {
            Debug.Assert(node.Children.Count == 2);
            Debug.Assert(parseNode.Children.Count == 3);
            if (!parseNode.Children[2].IsSubExpression)
            {
                return(node);
            }
            var secondOperandNode = node.Children[1];

            node.Children[1] = secondOperandNode.Children[0];
            secondOperandNode.Children[0] = node;
            return(ConvertTreeToLeftRecursive(secondOperandNode, parseNode.Children[2]));
        }
Пример #9
0
 private void WritePostfixOperatorNode(ComposedTokenStream tokenStream, TexExpressionNode node,
                                       ComposerState state)
 {
     if (node.Children.Count >= 1)
     {
         foreach (var childNode in node.Children)
         {
             WriteNode(tokenStream, childNode, state);
         }
         tokenStream.Write(TexToken.FromSymbol(node.Symbol));
     }
     else
     {
         throw new TexComposerException(node, string.Format(
                                            errorMessageUnexpectedNumberOfChildren, node.Symbol, node.Children.Count));
     }
 }
Пример #10
0
 public bool Equals(TexExpressionNode tree)
 {
     if (!this.Symbol.Equals(tree.Symbol))
     {
         return(false);
     }
     if (this.Value != null && !this.Value.Equals(tree.Value))
     {
         return(false);
     }
     if (!this.Children.Count.Equals(tree.Children.Count))
     {
         return(false);
     }
     for (int i = 0; i < tree.Children.Count; i++)
     {
         if (!this.Children[i].Equals(tree.Children[i]))
         {
             return(false);
         }
     }
     return(true);
 }
Пример #11
0
 private void WriteValueNode(ComposedTokenStream tokenStream, TexExpressionNode node,
                             ComposerState state)
 {
     tokenStream.Write(TexToken.FromValue(node.Symbol, node.Value));
 }
Пример #12
0
        private void WriteInfixOperatorNode(ComposedTokenStream tokenStream, TexExpressionNode node,
                                            ComposerState state)
        {
            if (node.Children.Count == 1)
            {
                // Node is actually term prefix.
                tokenStream.Write(TexToken.FromSymbol(node.Symbol));
                WriteNode(tokenStream, node.Children[0], state);
            }
            else if (node.Children.Count == 2)
            {
                WriteNode(tokenStream, node.Children[0], state);

                bool writeOpSymbol = true;
                var  padSymbol     = (this.PadPlusAndMinusSigns && node.Symbol.IsPlusOrMinusOperator()) ||
                                     node.Symbol.IsLongOperator();
                if (node.Symbol == TexSymbolKind.Dot)
                {
                    var checkNode = node.Children[1];
                    while (checkNode.Symbol == TexSymbolKind.Dot || checkNode.Symbol == TexSymbolKind.RaiseToIndex ||
                           checkNode.Symbol == TexSymbolKind.LowerToIndex)
                    {
                        checkNode = checkNode.Children[0];
                    }

                    // If terms can be multipled implicitly, do not write operator token.
                    switch (checkNode.Symbol)
                    {
                    case TexSymbolKind.Number:
                    case TexSymbolKind.Text:
                        break;

                    default:
                        if (checkNode.Children.Count <= 1)
                        {
                            writeOpSymbol = false;
                            padSymbol     = false;
                        }
                        break;
                    }
                }

                if (padSymbol)
                {
                    tokenStream.Write(TexToken.FromSymbol(TexSymbolKind.Space));
                }
                if (writeOpSymbol)
                {
                    tokenStream.Write(TexToken.FromSymbol(node.Symbol));
                }
                if (padSymbol)
                {
                    tokenStream.Write(TexToken.FromSymbol(TexSymbolKind.Space));
                }

                WriteNode(tokenStream, node.Children[1], state);
            }
            else
            {
                throw new TexComposerException(node, string.Format(
                                                   errorMessageUnexpectedNumberOfChildren, node.Symbol, node.Children.Count));
            }
        }
Пример #13
0
        public static TokenStream CreateTokenStream(this TexExpressionNode tree)
        {
            var texComposer = new TexComposer();

            return(texComposer.Write(tree));
        }
        private static TexExpressionNode FromPostfixOperatorIndicesParseNode(ParseNode parseNode,
                                                                             ParseNode childParseNode)
        {
            TexExpressionNode firstIndexNode  = null;
            TexExpressionNode secondIndexNode = null;

            if (parseNode.Children.Count == 0)
            {
                return(FromParseTree(childParseNode));
            }
            else if (parseNode.Children.Count == 2)
            {
                firstIndexNode = new TexExpressionNode(parseNode.Children[0].Token.Symbol);
            }
            else if (parseNode.Children.Count == 4)
            {
                firstIndexNode  = new TexExpressionNode(parseNode.Children[0].Token.Symbol);
                secondIndexNode = new TexExpressionNode(parseNode.Children[2].Token.Symbol);
            }
            else
            {
                throw new TexExpressionTreeBuilderException(parseNode, string.Format(
                                                                errorMessageUnexpectedNumberOfChildren, parseNode.Kind, parseNode.Children.Count));
            }

            Debug.Assert(firstIndexNode == null || firstIndexNode.Symbol == TexSymbolKind.RaiseToIndex ||
                         firstIndexNode.Symbol == TexSymbolKind.LowerToIndex,
                         "First index node is not RaiseToIndex or LowerToIndex.");
            Debug.Assert(secondIndexNode == null || secondIndexNode.Symbol == TexSymbolKind.RaiseToIndex ||
                         secondIndexNode.Symbol == TexSymbolKind.LowerToIndex,
                         "Second index node is not RaiseToIndex or LowerToIndex.");

            TexExpressionNode outerIndexNode;
            TexExpressionNode innerIndexNode;

            if (secondIndexNode == null)
            {
                outerIndexNode = firstIndexNode;
                innerIndexNode = firstIndexNode;
            }
            else
            {
                // Use raised index as outer exprNode.
                if (firstIndexNode.Symbol == TexSymbolKind.RaiseToIndex)
                {
                    outerIndexNode = firstIndexNode;
                    innerIndexNode = secondIndexNode;
                }
                else
                {
                    outerIndexNode = secondIndexNode;
                    innerIndexNode = firstIndexNode;
                }
                outerIndexNode.Children.Add(innerIndexNode);
            }

            // Add child nodes, and then nodes for indices.
            innerIndexNode.Children.Add(FromParseTree(childParseNode));
            firstIndexNode.Children.Add(FromParseTree(parseNode.Children[1]));
            if (secondIndexNode != null)
            {
                secondIndexNode.Children.Add(FromParseTree(parseNode.Children[3]));
            }

            return(outerIndexNode);
        }
Пример #15
0
 public TexComposerException(TexExpressionNode node, string message)
     : base(message)
 {
     this.Node = node;
 }
Пример #16
0
 public TexComposerException(TexExpressionNode node, ICollection <TexSymbolKind> expectedSymbolKinds)
     : this(node, string.Format(errorMessageInvalidSymbol,
                                string.Join(", ", expectedSymbolKinds.Select(tokenKind => tokenKind.ToString()).ToArray())))
 {
 }
Пример #17
0
        private void WriteNode(ComposedTokenStream tokenStream, TexExpressionNode node, ComposerState state)
        {
            var openBracketSymbol  = TexSymbolKind.Null;
            var closeBracketSymbol = TexSymbolKind.Null;

            if ((node.Symbol.IsBinaryOperator() || node.Symbol.IsRelationOperator()) &&
                !node.Symbol.IsRaiseOrLowerOperator())
            {
                // Check if current operator needs brackets because it has lower precedence than parent operator.
                if (node.Parent != null && !node.Parent.Symbol.IsRaiseOrLowerOperator())
                {
                    var nodePrecedence       = GetOperatorPrecedence(node);
                    var parentNodePrecedence = GetOperatorPrecedence(node.Parent);
                    if (nodePrecedence != -1 && parentNodePrecedence != -1 &&
                        nodePrecedence < parentNodePrecedence ||
                        (nodePrecedence == parentNodePrecedence &&
                         (node.Parent.Children.IndexOf(node) == 0 ^ node.Parent.Symbol.IsLeftAssociativeOperator())))
                    {
                        openBracketSymbol  = TexSymbolKind.RoundBracketOpen;
                        closeBracketSymbol = TexSymbolKind.RoundBracketClose;
                    }
                }
            }
            else if (node.Symbol.IsFunctionOperator() || node.Symbol.IsBigOperator())
            {
                openBracketSymbol  = TexSymbolKind.GroupOpen;
                closeBracketSymbol = TexSymbolKind.GroupClose;
            }

            if (openBracketSymbol == TexSymbolKind.Null)
            {
                if (node.Parent != null)
                {
                    // If any descendant node has more than one child, then group is needed.
                    bool needGroup = false;
                    var  curNode   = node;
                    while (curNode.Children.Count >= 1)
                    {
                        if (curNode.Children.Count > 1)
                        {
                            needGroup = true;
                            break;
                        }
                        curNode = curNode.Children[0];
                    }

                    if (needGroup)
                    {
                        switch (node.Parent.Symbol)
                        {
                        case TexSymbolKind.LowerToIndex:
                        case TexSymbolKind.RaiseToIndex:
                            openBracketSymbol  = TexSymbolKind.GroupOpen;
                            closeBracketSymbol = TexSymbolKind.GroupClose;
                            break;

                        case TexSymbolKind.Factorial:
                            openBracketSymbol  = TexSymbolKind.GroupOpen;
                            closeBracketSymbol = TexSymbolKind.GroupClose;
                            break;
                        }
                    }
                }
            }

            if (IsRightMostNode(node))
            {
                // No need to write brackets, since current operator will be written last.
                state.IsParentNodeGroupOpen = false;
                openBracketSymbol           = TexSymbolKind.Null;
                closeBracketSymbol          = TexSymbolKind.Null;
            }
            else if (!state.IsParentNodeGroupOpen && openBracketSymbol == TexSymbolKind.GroupOpen)
            {
                // Do not directly nest group brackets.
                state.IsParentNodeGroupOpen = true;
            }

            if (openBracketSymbol != TexSymbolKind.Null)
            {
                tokenStream.Write(TexToken.FromSymbol(openBracketSymbol));
            }

            if (node.Symbol.IsBinaryOperator() || node.Symbol.IsRelationOperator())
            {
                WriteInfixOperatorNode(tokenStream, node, state);
            }
            else if (node.Symbol.IsBracketedFunction())
            {
                WriteBracketedFunction(tokenStream, node, state);
            }
            else if (node.Symbol.IsFunctionOperator() || node.Symbol.IsBigOperator())
            {
                WritePrefixOperatorNode(tokenStream, node, state);
            }
            else if (node.Symbol.IsPostfixOperator())
            {
                WritePostfixOperatorNode(tokenStream, node, state);
            }
            else if (node.Symbol.IsValue())
            {
                WriteValueNode(tokenStream, node, state);
            }
            else
            {
                throw new TexComposerException(node,
                                               "Unrecognised node symbol.");
            }

            if (closeBracketSymbol != TexSymbolKind.Null)
            {
                tokenStream.Write(TexToken.FromSymbol(closeBracketSymbol));
            }
        }
Пример #18
0
 public static string CreateText(this TexExpressionNode tree)
 {
     return(CreateText(CreateTokenStream(tree)));
 }