public bool Match(SourceStream source, out MemberType result) { result = null; if (!source.IsValid()) { return(false); } var kind = MemberKind.unknown; var slice = source.GetSlice(); if (slice.MatchString(KeywordMemberList)) { kind |= MemberKind.List; } else if (!slice.MatchString(KeywordMemberType)) { return(false); } SkipCommentsAndWhitespace(slice); if (!slice.ReadWord(out string type_name)) { throw new ParseError("expected type name.", slice); } kind |= MemberType.ResolveKind(type_name); SkipCommentsAndWhitespace(slice); if (!slice.ReadWord(out string name)) { throw new ParseError("expected to read field name.", slice); } SkipCommentsAndWhitespace(slice); if (!slice.MatchString(TokenMemberAssignment)) { throw new ParseError($"expected '{TokenMemberAssignment}'.", slice); } SkipCommentsAndWhitespace(slice); if (!slice.ReadWord(out string ordstr)) { throw new ParseError("expected to read member ordinal.", slice); } if (!ordstr.TryParse(out int ordinal)) { slice.MoveBy(-ordstr.Length); throw new ParseError($"'{ordstr}' is not a valid oridinal.", slice); } SkipCommentsAndWhitespace(slice); if (!slice.MatchString(TokenMemberTerminator)) { throw new ParseError($"expected '{TokenMemberTerminator}'.", slice); } var span = source.Join(slice); result = new MemberType(name, type_name, ordinal, kind, span); return(true); }
public bool Match(SourceStream source, out NamespaceType result) { result = null; if (!source.IsValid()) { return(false); } var slice = source.GetSlice(); SkipCommentsAndWhitespace(slice); if (!slice.MatchString(KeywordNamespace)) { return(false); } SkipCommentsAndWhitespace(slice); string namespace_name = string.Empty; name_match: if (!slice.ReadWord(out string name)) { throw new ParseError($"expected namespace 'name'.", slice); } if (!name.IsNameLegal()) { slice.MoveBy(-name.Length); throw new ParseError($"'{name}' is not a legal namespace.", slice); } namespace_name += name; SkipCommentsAndWhitespace(slice); if (slice.MatchString(TokenNameExtension)) { namespace_name += TokenNameExtension; goto name_match; } if (!slice.MatchString(TokenNamespaceFirst)) { throw new ParseError($"expected '{TokenNamespaceFirst}'.", slice); } var types = new TypeList(); var parsers = new GrammarParserDelegate[] { MatchStruct, match_enum, MatchNamespace, }; while (slice.IsValid()) { SkipCommentsAndWhitespace(slice); if (slice.MatchString(TokenNamespaceFinal)) { break; } if (!MatchAny(slice, parsers, out BaseType type)) { throw new ParseError("cannot parse", slice); } types.Add(type); } var span = source.Join(slice); result = new NamespaceType(namespace_name, types, span); return(true); }
public bool Match(SourceStream source, out EnumType result) { result = null; if (!source.IsValid()) { return(false); } var slice = source.GetSlice(); if (!slice.MatchString(KeywordEnum)) { return(false); } SkipCommentsAndWhitespace(slice); if (!slice.ReadWord(out string name)) { throw new ParseError("expected to read enum name.", slice); } if (!name.IsNameLegal()) { slice.MoveBy(-name.Length); throw new ParseError($"'{name}' is not a legal enum name.", slice); } SkipCommentsAndWhitespace(slice); if (!slice.MatchString(TokenEnumFirst)) { throw new ParseError($"expected to find '{TokenEnumFirst}'.", slice); } SkipCommentsAndWhitespace(slice); List <(string name, byte ordinal)> values = new List <(string, byte)>(); while (slice.IsValid()) { SkipCommentsAndWhitespace(slice); if (slice.MatchString(TokenEnumFinal)) { break; } if (!slice.ReadWord(out string member_name)) { throw new ParseError("expected to read member name.", slice); } if (!member_name.IsNameLegal()) { slice.MoveBy(-member_name.Length); throw new ParseError($"'{member_name}' is not a legal member name.", slice); } SkipCommentsAndWhitespace(slice); if (!slice.MatchString(TokenEnumAssignment)) { throw new ParseError($"expected '{TokenEnumAssignment}'.", slice); } SkipCommentsAndWhitespace(slice); if (!slice.ReadWord(out string ordstr)) { throw new ParseError("unable to read enum value.", slice); } if (!ordstr.TryParse(out byte ordinal)) { slice.MoveBy(-ordstr.Length); throw new ParseError($"'{ordstr}' is not a valid oridinal.", slice); } values.Add((member_name, ordinal)); SkipCommentsAndWhitespace(slice); if (!slice.MatchString(TokenEnumSeparator)) { if (slice.MatchString(TokenEnumFinal)) { break; } throw new ParseError($"expected '{TokenEnumSeparator}' or '{TokenEnumFinal}'.", slice); } SkipCommentsAndWhitespace(slice); } var span = source.Join(slice); result = new EnumType(name, values.ToArray(), span); return(true); }