private SourceStream(SourceStream parent, int index, int count) { _content = parent._content + index; _count = count; _index = 0; _parent = parent; }
/// <summary> /// /// </summary> /// <returns></returns> public grammar.SourceStream GetSource() { lock (_syncpoint) { if (_sourceStream is null) { var info = new FileInfo(_path); if (!info.Exists) { throw new FileNotFoundException("File not found", _path); } using (var stream = info.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) using (var reader = new StreamReader(stream)) { string content = reader.ReadToEnd(); var array = content.ToCharArray(); _sourceStream = new grammar.SourceStream(array); } } return(_sourceStream); } }
void IDisposable.Dispose() { lock (_syncpoint) { if (_sourceStream is IDisposable disposable) { disposable.Dispose(); _sourceStream = null; } } }
static bool MatchAny(SourceStream source, GrammarParserDelegate[] parsers, out BaseType result) { for (int i = 0; i < parsers.Length; i += 1) { if (parsers[i](source, out result)) { return(true); } } result = null; return(false); }
public bool MatchStruct(SourceStream source, out BaseType result) { StructType value; if (Match(source, out value)) { result = value; return(true); } result = null; return(false); }
public bool ImportFile(SourceStream source, out SymbolTable result) { result = null; if (!source.IsValid()) { return(false); } var slice = source.GetSlice(); if (!slice.MatchString(KeywordImport)) { return(false); } SkipCommentsAndWhitespace(slice); if (!slice.MatchString(TokenImportFirst)) { throw new ParseError($"Expected '{TokenImportFirst}'.", slice); } int start = slice.Index(); int count = slice.FindNext(TokenImportFinal); if (count < 0) { throw new ParseError($"Expected '{TokenImportFinal}'.", slice); } if (!slice.ReadAbsolute(start, count, out string path)) { throw new ParseError("Unable to read inlcude path.", slice); } slice.MoveBy(path.Length); if (!slice.MatchString(TokenImportFinal)) { throw new ParseError($"Expected '{TokenImportFinal}'.", slice); } result = GetSymbolsFromFile(path); source.Join(slice); return(true); }
static bool SkipCommentsAndWhitespace(SourceStream source) { if (!source.IsValid()) { return(false); } var slice = source.GetSlice(); while (true) { slice.SkipWhitespace(); if (slice.MatchString(TokenCommentBlockFirst)) { int index = slice.FindNext(TokenCommentBlockFinal); if (index < 0) { slice.MoveBy(-TokenCommentBlockFirst.Length); throw new ParseError($"unterminated comment, expected to find '{TokenCommentBlockFinal}'.", slice); } slice.MoveBy(index + TokenCommentBlockFinal.Length); } else if (slice.MatchString(TokenCommentLineFirst)) { int index = slice.FindNext(TokenCommandLineFinal); if (index < 0) { if (index < 0) { slice.MoveBy(-TokenCommentLineFirst.Length); throw new ParseError($"unterminated comment, expected to find '\\n'.", slice); } } slice.MoveBy(index + TokenCommandLineFinal.Length); } else { source.Join(slice); return(true); } } }
public SourceSpan Join(SourceStream slice) { if (slice is null) { throw new ArgumentNullException(nameof(slice)); } if (slice._parent != this) { throw new ArgumentException($"Can only join children to parent `{nameof(SourceStream)}` instances.", nameof(slice)); } if (slice._index == 0) { return(new SourceSpan(this, _index, 0)); } var span = new SourceSpan(this, _index, slice._index - 1); _index += slice._index; return(span); }
public SourceSpan(SourceStream source, int index, int count) { _count = count; _index = index; _source = source; }
public ParseError(string message, SourceStream source) : base(format_message(message, source)) { }
static string format_message(string message, SourceStream source) { return($"parse error: {message}\n\n {source.AsString()}"); }
public bool Match(SourceStream source, out StructType result) { result = null; if (!source.IsValid()) { return(false); } var slice = source.GetSlice(); if (!slice.MatchString(KeywordStruct)) { return(false); } SkipCommentsAndWhitespace(slice); if (!slice.ReadWord(out string name)) { throw new ParseError("expected struct name.", slice); } if (!name.IsNameLegal()) { slice.MoveBy(-name.Length); throw new ParseError($"'{name}' is not a legal struct name.", slice); } SkipCommentsAndWhitespace(slice); if (!slice.MatchString(TokenStructFirst)) { throw new ParseError($"expeceted '{TokenStructFirst}'.", slice); } var members = new TypeSet(); while (slice.IsValid()) { SkipCommentsAndWhitespace(slice); if (slice.MatchString(TokenStructFinal)) { break; } if (!Match(slice, out MemberType member)) { throw new ParseError("failed to parse member.", slice); } members.Add(member.Ordinal(), member); } var span = source.Join(slice); result = new StructType(name, members, span); return(true); }