Beispiel #1
0
        public void PushToken(Token t, Text Text, Dictionary <Object, TextRange> TokenPositions, Dictionary <Object, TextRange> Positions)
        {
            if (Nodes.Count == 0)
            {
                if (TokenPositions.ContainsKey(t))
                {
                    LineRangeStart = TokenPositions[t];
                }
            }

            Action <Object, Object> Mark = (SemanticsObj, SyntaxObj) =>
            {
                if (TokenPositions.ContainsKey(SyntaxObj))
                {
                    var Range = TokenPositions[SyntaxObj];
                    Positions.Add(SemanticsObj, Range);
                }
            };
            Action <Object, Object, Object> Mark2 = (SemanticsObj, SyntaxObjStart, SyntaxObjEnd) =>
            {
                if ((TokenPositions.ContainsKey(SyntaxObjStart) || Positions.ContainsKey(SyntaxObjStart)) && TokenPositions.ContainsKey(SyntaxObjEnd))
                {
                    var RangeStart = TokenPositions.ContainsKey(SyntaxObjStart) ? TokenPositions[SyntaxObjStart] : Positions[SyntaxObjStart];
                    var RangeEnd   = TokenPositions[SyntaxObjEnd];
                    Positions.Add(SemanticsObj, new TextRange {
                        Start = RangeStart.Start, End = RangeEnd.End
                    });
                }
            };

            if (t.Type.OnDirect || (t.Type.OnOperator && (t.Type.Operator != ".")))
            {
                if (Nodes.Count >= 2)
                {
                    var PrevNode = Nodes.Last();
                    if (PrevNode.OnNode && PrevNode.Node.OnOperator && (PrevNode.Node.Operator == "."))
                    {
                        var PrevPrevNode = Nodes[Nodes.Count - 2];
                        if (PrevPrevNode.OnNode)
                        {
                            var Parent = PrevPrevNode.Node;
                            var Child  = t.Type.OnDirect ? ExprNode.CreateDirect(t.Type.Direct) : ExprNode.CreateOperator(t.Type.Operator);
                            Mark(Child, t);
                            var Member = new ExprNodeMember {
                                Parent = Parent, Child = Child
                            };
                            var nn = ExprNode.CreateMember(Member);
                            if (Positions.ContainsKey(Parent))
                            {
                                Mark2(Member, Positions[Parent], t);
                                Mark2(nn, Positions[Parent], t);
                            }
                            Nodes.RemoveRange(Nodes.Count - 2, 2);
                            Nodes.Add(StackNode.CreateNode(nn));
                            return;
                        }
                    }
                }
            }

            if (t.Type.OnDirect)
            {
                var n = ExprNode.CreateDirect(t.Type.Direct);
                Mark(n, t);
                Nodes.Add(StackNode.CreateNode(n));
            }
            else if (t.Type.OnQuoted)
            {
                var n = ExprNode.CreateLiteral(t.Type.Quoted);
                Mark(n, t);
                Nodes.Add(StackNode.CreateNode(n));
            }
            else if (t.Type.OnEscaped)
            {
                var n = ExprNode.CreateLiteral(t.Type.Escaped);
                Mark(n, t);
                Nodes.Add(StackNode.CreateNode(n));
            }
            else if (t.Type.OnLeftParenthesis)
            {
                Nodes.Add(StackNode.CreateToken(t));
            }
            else if (t.Type.OnRightParenthesis)
            {
                Reduce(t, Text, TokenPositions, Positions);
                var InnerNodes = Nodes.AsEnumerable().Reverse().TakeWhile(n => !(n.OnToken && n.Token.Type.OnLeftParenthesis)).Reverse().ToList();
                if (Nodes.Count - InnerNodes.Count - 1 < 0)
                {
                    throw new InvalidSyntaxException("InvalidParenthesis", new FileTextRange {
                        Text = Text, Range = TokenPositions.ContainsKey(t) ? TokenPositions[t] : Firefly.Texting.TreeFormat.Optional <TextRange> .Empty
                    });
                }
                var LeftParenthesis = Nodes[Nodes.Count - InnerNodes.Count - 1].Token;
                var Children        = new List <ExprNode>();
                if (InnerNodes.Count > 0)
                {
                    Children = Split(InnerNodes, n => n.OnToken && n.Token.Type.OnComma).Select(Part => Part.Single().Node).ToList();
                }
                if (!LeftParenthesis.IsAfterSpace && !LeftParenthesis.IsLeadingToken)
                {
                    var ParentNode = Nodes[Nodes.Count - InnerNodes.Count - 2];
                    if (ParentNode.OnNode)
                    {
                        if (Children.Count == 1)
                        {
                            var One = Children.Single();
                            if (One.OnStem && !One.Stem.Head.OnSome && One.Stem.CanMerge)
                            {
                                Children = One.Stem.Nodes;
                            }
                            else
                            {
                                Mark2(Children, LeftParenthesis, t);
                            }
                        }
                        else
                        {
                            Mark2(Children, LeftParenthesis, t);
                        }
                        var Stem = new ExprNodeStem {
                            Head = ParentNode.Node, Nodes = Children, CanMerge = false
                        };
                        Mark2(Stem, ParentNode.Node, t);
                        var Node = ExprNode.CreateStem(Stem);
                        Mark2(Node, ParentNode.Node, t);
                        Nodes.RemoveRange(Nodes.Count - InnerNodes.Count - 2, InnerNodes.Count + 2);
                        Nodes.Add(StackNode.CreateNode(Node));
                        return;
                    }
                }
                if (Children.Count == 1)
                {
                    var One = Children.Single();
                    if (One.OnStem && One.Stem.CanMerge)
                    {
                        var Stem = new ExprNodeStem {
                            Head = One.Stem.Head, Nodes = One.Stem.Nodes, CanMerge = false
                        };
                        Mark2(Stem, LeftParenthesis, t);
                        var Node = ExprNode.CreateStem(Stem);
                        Mark2(Node, LeftParenthesis, t);
                        Nodes.RemoveRange(Nodes.Count - InnerNodes.Count - 1, InnerNodes.Count + 1);
                        Nodes.Add(StackNode.CreateNode(Node));
                        return;
                    }
                    else if (One.OnUndetermined)
                    {
                        Nodes.RemoveRange(Nodes.Count - InnerNodes.Count - 1, InnerNodes.Count + 1);
                        Nodes.Add(StackNode.CreateNode(One));
                        return;
                    }
                }
                {
                    Mark2(Children, LeftParenthesis, t);
                    var Stem = new ExprNodeStem {
                        Head = Optional <ExprNode> .Empty, Nodes = Children, CanMerge = false
                    };
                    Mark2(Stem, LeftParenthesis, t);
                    var Node = ExprNode.CreateStem(Stem);
                    Mark2(Node, LeftParenthesis, t);
                    Nodes.RemoveRange(Nodes.Count - InnerNodes.Count - 1, InnerNodes.Count + 1);
                    Nodes.Add(StackNode.CreateNode(Node));
                }
            }
            else if (t.Type.OnComma)
            {
                Reduce(t, Text, TokenPositions, Positions);
                Nodes.Add(StackNode.CreateToken(t));
            }
            else if (t.Type.OnPreprocessDirective)
            {
                Nodes.Add(StackNode.CreateToken(t));
            }
            else if (t.Type.OnOperator)
            {
                var n = ExprNode.CreateOperator(t.Type.Operator);
                Mark(n, t);
                Nodes.Add(StackNode.CreateNode(n));
            }
            else if (t.Type.OnSingleLineComment)
            {
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Beispiel #2
0
 /// <summary>茎</summary>
 public static ExprNode CreateStem(ExprNodeStem Value)
 {
     return(new ExprNode {
         _Tag = ExprNodeTag.Stem, Stem = Value
     });
 }