Пример #1
0
        internal static IEnumerable <ParseNode> TraverseSegmentsDepthFirst(this ParseNode startNode)
        {
            var visited = new HashSet <ParseNode>();
            var stack   = new Stack <ParseNode>();
            var parents = startNode.AncestorsAndSelf();

            stack.Push(startNode);

            while (stack.Any())
            {
                var current = stack.Pop();

                if (!visited.Add(current))
                {
                    continue;
                }

                if (current.Prefix == Prefixes.S)
                {
                    yield return(current);
                }

                var neighbours = current.NeighboursWithExclusion(parents).Where(p => !visited.Contains(p));

                foreach (var neighbour in neighbours.Reverse())
                {
                    stack.Push(neighbour);
                }
            }
        }
Пример #2
0
        internal static object Analyze(this List <SegmentContext> segments, Separators separators, Type type, string rulesAssemblyName)
        {
            if (segments == null)
            {
                throw new ArgumentNullException("segments");
            }
            if (separators == null)
            {
                throw new ArgumentNullException("separators");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var messageGrammar = ParseNode.BuldTree(type, true);

            if (messageGrammar.Prefix != Prefixes.M)
            {
                throw new Exception(string.Format("Only messages are supported: {0}", messageGrammar.Name));
            }

            var segmentPosition  = messageGrammar.Children.First();
            var instancePosition = new ParseNode(type);

            foreach (var segment in segments)
            {
                if (segment.IsHeader)
                {
                    continue;
                }

                Logger.Log(string.Format("Segment to match: {0}", segment.LogName));
                try
                {
                    // Jump back to HL segment if needed
                    if (segment.IsJump)
                    {
                        segmentPosition = messageGrammar.JumpToHl(instancePosition.Root(), segment.ParentId);
                    }

                    var currSeg = segmentPosition.TraverseSegmentsDepthFirst().FirstOrDefault(n => n.IsEqual(segment));
                    if (currSeg == null)
                    {
                        throw new Exception(
                                  string.Format(
                                      "Segment {0} was not found after segment {1} in class {2}.",
                                      segment.Value, segmentPosition.EdiName, type.Name));
                    }

                    var segmentTree = currSeg.AncestorsToIntersection(segmentPosition);
                    instancePosition = instancePosition.AncestorsAndSelf().Last(nt => nt.Name == segmentTree.First().Parent.Name);
                    foreach (var parseTree in segmentTree)
                    {
                        instancePosition = instancePosition.AddChild(parseTree.Type, parseTree.Type.Name);
                        if (parseTree.Prefix == Prefixes.S)
                        {
                            instancePosition.ParseSegment(segment.Value, separators);
                        }
                    }

                    segmentPosition = currSeg;
                }
                catch (Exception ex)
                {
                    throw new ParserException("Failed at line: " + segment.Value, ex);
                }
                Logger.Log(string.Format("Matched segment: {0}", segmentPosition.Name));
            }

            return(instancePosition.Root().ToInstance());
        }