public void Run() { string line; int lineNumber = 0; while ((line = _sourceStream.ReadLine()) != null) { lineNumber++; if (line.Contains('\t')) { throw new LexerException(lineNumber, "AHL file cannot contain tabs"); } line = StripComments(line); int indent = 0; while (indent < line.Length && line[indent] == ' ') { indent++; } // skip empty lines if (indent == line.Length) { continue; } line = line.Substring(indent); var match = LineRegex.Match(line); if (!match.Success) { throw new LexerException(lineNumber, $"Line doesn't match AHL syntax:\n{line}"); } string keyword = match.Groups["keyword"].Success ? match.Groups["keyword"].Captures[0].Value : null; string key = match.Groups["key"].Success ? Unquote(match.Groups["key"].Captures[0].Value) : null; var attributes = new List <AhlAttribute>(); for (int i = 0; i < match.Groups["attrName"].Captures.Count; i++) { var attrName = match.Groups["attrName"].Captures[i].Value; var attrValue = Unquote(match.Groups["attrValue"].Captures[i].Value); attributes.Add(new AhlAttribute(attrName, attrValue)); } _parsingContext.PushLine(lineNumber, indent, keyword, key, attributes); } _parsingContext.PushEof(); }