Пример #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 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));
     }
 }
Пример #3
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));
     }
 }
Пример #4
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));
            }
        }
Пример #5
0
 private void WriteValueNode(ComposedTokenStream tokenStream, TexExpressionNode node,
                             ComposerState state)
 {
     tokenStream.Write(TexToken.FromValue(node.Symbol, node.Value));
 }
Пример #6
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));
            }
        }