internal static object Analyze(this List <SegmentContext> segments, Separators separators, MessageContext messageContext) { if (segments == null) { throw new ArgumentNullException("segments"); } if (separators == null) { throw new ArgumentNullException("separators"); } if (messageContext == null) { throw new ArgumentNullException("messageContext"); } var messageGrammar = ParseNode.BuldTree(messageContext.SystemType, true); if (messageGrammar.Prefix != Prefixes.M) { throw new Exception(String.Format("Only messages are supported: {0}", messageGrammar.Name)); } var errorContext = new MessageErrorContext(messageContext.Tag, messageContext.ControlNumber); var segmentPosition = messageGrammar.Children.First(); var instancePosition = new ParseNode(messageContext.SystemType); foreach (var segment in segments) { if (segment.IsControl) { continue; } Logger.Log(String.Format("Segment to match: {0}", segment.LogName)); // Jump back to HL segment if needed if (segment.IsJump) { try { segmentPosition = messageGrammar.JumpToHl(instancePosition.Root(), segment.ParentId); } catch (Exception ex) { errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnexpectedSegment); throw new ParsingException(ErrorCodes.InvalidInterchangeContent, "Unable to resolve HL.", ex, segment.Value, errorContext); } } var currSeg = segmentPosition.TraverseSegmentsDepthFirst().FirstOrDefault(n => n.IsEqual(segment)); if (currSeg == null) { if (messageGrammar.Descendants().All(d => d.EdiName != segment.Name)) { errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnrecognizedSegment); throw new ParsingException(ErrorCodes.InvalidInterchangeContent, "Segment is not supported in rules class.", segment.Value, errorContext); } errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnexpectedSegment); throw new ParsingException(ErrorCodes.InvalidInterchangeContent, "Segment was not in the correct position according to the rules class.", segment.Value, errorContext); } 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, errorContext); } } segmentPosition = currSeg; Logger.Log(String.Format("Matched segment: {0}", segmentPosition.Name)); } return(instancePosition.Root().ToInstance()); }