private CtfPropertyBag GetPropertyBag(string str, int start, int stop) { Debug.Assert(str[start] == '{'); CtfPropertyBag result = new CtfPropertyBag(); foreach (string rawStatement in EnumerateStatements(str, start + 1, stop)) { string statement = StripComments(rawStatement); int i = statement.IndexOf('='); if (i <= 0) { continue; } if (statement[i - 1] == ':') { string name = statement.Substring(0, i - 1).Trim(); int open = statement.IndexOf('{', i + 1); int close = FindCloseBrace(statement, open); if (close > stop || close == -1) { string[] structNameParts = statement.Substring(i + 1).Trim().Split(' '); if (structNameParts.Length != 2 || structNameParts[0] != "struct") { throw new InvalidOperationException(); } CtfUnresolvedType unresolved = new CtfUnresolvedType(structNameParts[1]); result.AddValue(name, unresolved); } else { CtfField[] fields = ParseStructFields(statement, open, close).ToArray(); result.AddValue(name, new CtfStruct(null, fields)); } } else { string name = statement.Substring(0, i).Trim(); string value = statement.Substring(i + 1).Trim(); if (value.Length > 2 && value[0] == '\"' && value[value.Length - 1] == '\"') { value = value.Substring(1, value.Length - 2); } result.AddValue(name, value); } } return(result); }
private CtfMetadataDeclaration ParseOneDeclaration(string metadata, int index, out int end) { end = -1; int open = metadata.IndexOf('{', index); if (open == -1) { return(null); } int start = metadata.Substring(0, open).LastIndexOf('\n') + 1; if (start == 0) { return(null); } CtfDeclarationTypes directive = CtfDeclarationTypes.Unknown; string[] directiveElements = metadata.Substring(start, open - start).Trim().Split(' '); string directiveString = directiveElements[0]; string name = null; switch (directiveString) { case "trace": directive = CtfDeclarationTypes.Trace; break; case "typealias": directive = CtfDeclarationTypes.TypeAlias; int closeBrace = FindCloseBrace(metadata, open) + 1; CtfPropertyBag bag = GetPropertyBag(metadata, open, closeBrace); CtfMetadataType t = null; switch (directiveElements[1]) { case "integer": t = new CtfInteger(bag); break; default: throw new IOException(); } int colonEquals = metadata.IndexOf(":=", closeBrace) + 2; int semi = colonEquals; while (metadata[++semi] != ';') { ; } name = metadata.Substring(colonEquals, semi - colonEquals).Trim(); end = semi + 1; return(new CtfMetadataDeclaration(CtfDeclarationTypes.TypeAlias, t, name, directiveElements[1])); case "env": directive = CtfDeclarationTypes.Environment; break; case "clock": directive = CtfDeclarationTypes.Clock; break; case "struct": directive = CtfDeclarationTypes.Struct; name = directiveElements[1]; break; case "stream": directive = CtfDeclarationTypes.Stream; break; case "event": directive = CtfDeclarationTypes.Event; break; default: break; } int close = FindCloseBrace(metadata, open); int curr = close; while (metadata[curr++] != ';') { ; } int nameStart = metadata.IndexOf(":=", close); if (name == null && nameStart != -1 && nameStart < curr) { nameStart += 2; // move past := name = metadata.Substring(nameStart, curr - nameStart - 1).Trim(); } Debug.Assert(metadata[open] == '{'); Debug.Assert(metadata[close] == '}'); end = curr; if (directive == CtfDeclarationTypes.Struct) { CtfPropertyBag bag = null; Match match = s_align.Match(metadata, close, end - close); if (match.Success) { bag = new CtfPropertyBag(); bag.AddValue("align", match.Groups[1].ToString()); } CtfField[] fields = ParseStructFields(metadata, open, close).ToArray(); return(new CtfMetadataDeclaration(directive, bag, fields, name, metadata.Substring(index, curr - index))); } else { CtfPropertyBag properties = GetPropertyBag(metadata, open, close); return(new CtfMetadataDeclaration(directive, properties, name, metadata.Substring(index, curr - index))); } }