public override void Apply(SubString name, IHRONVisitor visitor) { if (visitor == null) { return; } visitor.Object_Begin(name); for (var index = 0; index < m_members.Length; index++) { var pair = m_members[index]; var innerName = pair.Name.ToSubString(); pair.Value.Apply(innerName, visitor); } visitor.Object_End(name); }
static void VisitMember(SubString memberName, object memberValue, IHRONVisitor visitor, bool omitIfNullOrEmpty) { if (memberValue == null) { if (!omitIfNullOrEmpty) { visitor.Value_Begin(memberName); visitor.Value_End(memberName); } return; } var classDescriptor = memberValue.GetType().GetClassDescriptor(); if (classDescriptor.IsDictionaryLike) { visitor.Object_Begin(memberName); var dictionary = (IDictionary)memberValue; foreach (var key in dictionary.Keys) { var innerValue = dictionary[key]; var keyAsString = key as string; if (keyAsString != null) { VisitMember(keyAsString.ToSubString(), innerValue, visitor, omitIfNullOrEmpty); } } visitor.Object_End(memberName); } else if (classDescriptor.IsListLike) { var list = (IList)memberValue; for (var index = 0; index < list.Count; index++) { var innerValue = list[index]; VisitMember(memberName, innerValue, visitor, omitIfNullOrEmpty); } } else if (memberValue is string) { var innerValue = (string)memberValue; if (!innerValue.IsNullOrEmpty()) { visitor.Value_Begin(memberName); foreach (var line in innerValue.ReadLines()) { visitor.Value_Line(line); } visitor.Value_End(memberName); } else if (!omitIfNullOrEmpty) { visitor.Value_Begin(memberName); visitor.Value_End(memberName); } } else if (classDescriptor.Type.CanParse()) { var memberAsString = memberValue.ToString(); // These types are never multilined, but may be empty if (!memberAsString.IsNullOrEmpty()) { visitor.Value_Begin(memberName); visitor.Value_Line(memberAsString.ToSubString()); visitor.Value_End(memberName); } else if (!omitIfNullOrEmpty) { visitor.Value_Begin(memberName); visitor.Value_End(memberName); } } else { visitor.Object_Begin(memberName); VisitObject(memberValue, visitor); visitor.Object_End(memberName); } }
public static void Parse( int maxErrorCount, IEnumerable<SubString> lines, IHRONVisitor visitor ) { if (visitor == null) { return; } visitor.Document_Begin(); try { var errorCount = 0; lines = lines ?? Array<SubString>.Empty; var state = ParseState.ExpectingTag; var expectedIndent = 0; var lineNo = 0; var context = new Stack<SubString>(); var acceptsPreProcessor = true; foreach (var line in lines) { ++lineNo; var lineLength = line.Length; var begin = line.Begin; var end = line.End; var currentIndent = 0; var baseString = line.BaseString; if (acceptsPreProcessor) { if (lineLength > 0 && baseString[begin] == '!') { visitor.PreProcessor(line.ToSubString(1)); continue; } else { acceptsPreProcessor = false; } } for (var iter = begin; iter < end; ++iter) { var ch = baseString[iter]; if (ch == '\t') { ++currentIndent; } else { break; } } bool isComment; switch (state) { case ParseState.ExpectingTag: isComment = currentIndent < lineLength && baseString[currentIndent + begin] == '#' ; break; case ParseState.ExpectingValue: default: isComment = currentIndent < expectedIndent && currentIndent < lineLength && baseString[currentIndent + begin] == '#' ; break; } var isWhiteSpace = line.ToSubString(currentIndent).IsWhiteSpace; if (isComment) { visitor.Comment(currentIndent, line.ToSubString(currentIndent + 1)); } else if (isWhiteSpace && currentIndent < expectedIndent) { switch (state) { case ParseState.ExpectingValue: visitor.Value_Line(SubString.Empty); break; case ParseState.ExpectingTag: default: visitor.Empty(line); break; } } else if (isWhiteSpace) { switch (state) { case ParseState.ExpectingValue: visitor.Value_Line(line.ToSubString(expectedIndent)); break; case ParseState.ExpectingTag: default: visitor.Empty(line); break; } } else { if (currentIndent < expectedIndent) { switch (state) { case ParseState.ExpectingTag: for (var iter = currentIndent; iter < expectedIndent; ++iter) { visitor.Object_End(context.Peek()); context.Pop(); } break; case ParseState.ExpectingValue: default: visitor.Value_End(context.Peek()); // Popping the value name context.Pop(); for (var iter = currentIndent + 1; iter < expectedIndent; ++iter) { visitor.Object_End(context.Peek()); context.Pop(); } break; } expectedIndent = currentIndent; state = ParseState.ExpectingTag; } switch (state) { case ParseState.ExpectingTag: if (currentIndent > expectedIndent) { visitor.Error(lineNo, line, ParseError.IndentIncreasedMoreThanExpected); if (++errorCount > 0) { return; } } else if (currentIndent < lineLength) { var first = baseString[currentIndent + begin]; switch (first) { case '@': state = ParseState.ExpectingTag; ++expectedIndent; context.Push(line.ToSubString(currentIndent + 1)); visitor.Object_Begin(context.Peek()); break; case '=': state = ParseState.ExpectingValue; ++expectedIndent; context.Push(line.ToSubString(currentIndent + 1)); visitor.Value_Begin(context.Peek()); break; default: visitor.Error(lineNo, line, ParseError.TagIsNotCorrectlyFormatted); if (++errorCount > 0) { return; } break; } } else { visitor.Error(lineNo, line, ParseError.ProgrammingError); if (++errorCount > 0) { return; } } break; case ParseState.ExpectingValue: visitor.Value_Line(line.ToSubString(expectedIndent)); break; } } } switch (state) { case ParseState.ExpectingTag: for (var iter = 0; iter < expectedIndent; ++iter) { visitor.Object_End(context.Peek()); context.Pop(); } break; case ParseState.ExpectingValue: default: visitor.Value_End(context.Peek()); // Popping the value name context.Pop(); for (var iter = 0 + 1; iter < expectedIndent; ++iter) { visitor.Object_End(context.Peek()); context.Pop(); } break; } } finally { visitor.Document_End(); } }
public static void Parse( int maxErrorCount, IEnumerable <SubString> lines, IHRONVisitor visitor ) { if (visitor == null) { return; } visitor.Document_Begin(); try { var errorCount = 0; lines = lines ?? Array <SubString> .Empty; var state = ParseState.ExpectingTag; var expectedIndent = 0; var lineNo = 0; var context = new Stack <SubString>(); var acceptsPreProcessor = true; foreach (var line in lines) { ++lineNo; var lineLength = line.Length; var begin = line.Begin; var end = line.End; var currentIndent = 0; var baseString = line.BaseString; if (acceptsPreProcessor) { if (lineLength > 0 && baseString[begin] == '!') { visitor.PreProcessor(line.ToSubString(1)); continue; } else { acceptsPreProcessor = false; } } for (var iter = begin; iter < end; ++iter) { var ch = baseString[iter]; if (ch == '\t') { ++currentIndent; } else { break; } } bool isComment; switch (state) { case ParseState.ExpectingTag: isComment = currentIndent < lineLength && baseString[currentIndent + begin] == '#' ; break; case ParseState.ExpectingValue: default: isComment = currentIndent < expectedIndent && currentIndent < lineLength && baseString[currentIndent + begin] == '#' ; break; } var isWhiteSpace = line.ToSubString(currentIndent).IsWhiteSpace; if (isComment) { visitor.Comment(currentIndent, line.ToSubString(currentIndent + 1)); } else if (isWhiteSpace && currentIndent < expectedIndent) { switch (state) { case ParseState.ExpectingValue: visitor.Value_Line(SubString.Empty); break; case ParseState.ExpectingTag: default: visitor.Empty(line); break; } } else if (isWhiteSpace) { switch (state) { case ParseState.ExpectingValue: visitor.Value_Line(line.ToSubString(expectedIndent)); break; case ParseState.ExpectingTag: default: visitor.Empty(line); break; } } else { if (currentIndent < expectedIndent) { switch (state) { case ParseState.ExpectingTag: for (var iter = currentIndent; iter < expectedIndent; ++iter) { visitor.Object_End(context.Peek()); context.Pop(); } break; case ParseState.ExpectingValue: default: visitor.Value_End(context.Peek()); // Popping the value name context.Pop(); for (var iter = currentIndent + 1; iter < expectedIndent; ++iter) { visitor.Object_End(context.Peek()); context.Pop(); } break; } expectedIndent = currentIndent; state = ParseState.ExpectingTag; } switch (state) { case ParseState.ExpectingTag: if (currentIndent > expectedIndent) { visitor.Error(lineNo, line, ParseError.IndentIncreasedMoreThanExpected); if (++errorCount > 0) { return; } } else if (currentIndent < lineLength) { var first = baseString[currentIndent + begin]; switch (first) { case '@': state = ParseState.ExpectingTag; ++expectedIndent; context.Push(line.ToSubString(currentIndent + 1)); visitor.Object_Begin(context.Peek()); break; case '=': state = ParseState.ExpectingValue; ++expectedIndent; context.Push(line.ToSubString(currentIndent + 1)); visitor.Value_Begin(context.Peek()); break; default: visitor.Error(lineNo, line, ParseError.TagIsNotCorrectlyFormatted); if (++errorCount > 0) { return; } break; } } else { visitor.Error(lineNo, line, ParseError.ProgrammingError); if (++errorCount > 0) { return; } } break; case ParseState.ExpectingValue: visitor.Value_Line(line.ToSubString(expectedIndent)); break; } } } switch (state) { case ParseState.ExpectingTag: for (var iter = 0; iter < expectedIndent; ++iter) { visitor.Object_End(context.Peek()); context.Pop(); } break; case ParseState.ExpectingValue: default: visitor.Value_End(context.Peek()); // Popping the value name context.Pop(); for (var iter = 0 + 1; iter < expectedIndent; ++iter) { visitor.Object_End(context.Peek()); context.Pop(); } break; } } finally { visitor.Document_End(); } }
void IHRONEntity2.Apply(SubString name, IHRONVisitor visitor) { if (visitor == null) { return; } visitor.Object_Begin(name.BaseString, name.Begin, name.End); for (var index = 0; index < m_members.Length; index++) { var pair = m_members[index]; var innerName = pair.Name.ToSubString(); pair.Value.Apply(innerName, visitor); } visitor.Object_End(); }