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(); } }
/// <summary>成员</summary> public static ExprNode CreateMember(ExprNodeMember Value) { return(new ExprNode { _Tag = ExprNodeTag.Member, Member = Value }); }