public static MqChunk Parse(MqTokenizer tokenizer) { while (tokenizer.Current.Kind == MqTokenizer.NewLineTokenKind) { tokenizer.MoveNext(); } var rt = new MqChunk { Name = tokenizer.Current.Kind == MqTokenizer.IdentifierTokenKind || tokenizer.Current.Kind == MqTokenizer.StringTokenKind ? tokenizer.Current.Text : null, }; var args = tokenizer.StartWith(tokenizer.Current.Kind == MqTokenizer.DigitTokenKind ? new[] { tokenizer.Current } : new Token[0]) .TakeWhile(_ => _.Kind != MqTokenizer.BeginChildrenTokenKind && _.Kind != MqTokenizer.NewLineTokenKind) .ToArray(); rt.Arguments = args.TakeWhile(_ => _.Kind == MqTokenizer.DigitTokenKind || _.Kind == MqTokenizer.StringTokenKind).Select(_ => _.Text).ToList(); rt.Attributes = Util.Defer(() => { var attrs = args.Skip(rt.Arguments.Count); var current = attrs.FirstOrDefault(); return(attrs.GroupBy(_ => { if (_.Kind == MqTokenizer.IdentifierTokenKind) { current = _; } return current; }) .Select(_ => new MqChunkAttribute { Name = _.Key.Text, Arguments = _.Skip(1).Select(t => t.Text).ToList(), })); }).ToList(); if (tokenizer.Current.Kind == MqTokenizer.BeginChildrenTokenKind) { rt.Children = tokenizer.TakeWhile(_ => _.Kind != MqTokenizer.EndChildrenTokenKind) .Select(_ => Parse(tokenizer)) .ToList(); tokenizer.MoveNext(MqTokenizer.EndChildrenTokenKind); } return(rt); }
public static MqDocument Parse(string text) { var rt = new MqDocument(); var tokenizer = new MqTokenizer(text); var header = new[] { "Metasequoia", "Document", "\n", "Format", "Text", "Ver" }; if (!tokenizer.Take(header.Length).Select(_ => _.Text).SequenceEqual(header)) { throw new InvalidOperationException("invalid format"); } rt.Version = float.Parse(tokenizer.MoveNext().EnsureKind(MqTokenizer.DigitTokenKind).Text); if (rt.Version >= 2) { throw new NotSupportedException("specified format version not supported"); } foreach (var i in tokenizer) { if (i.Kind == MqTokenizer.IdentifierTokenKind) { var chunk = MqChunk.Parse(tokenizer); switch (chunk.Name.ToLower()) { case "includexml": rt.IncludeXml = chunk.Arguments.First().Trim('"'); break; case "scene": rt.Scene = MqScene.Parse(chunk); break; case "material": rt.Materials = chunk.Children.Select(MqMaterial.Parse).ToList(); break; case "object": rt.Objects.Add(MqObject.Parse(chunk)); break; case "eof": break; default: rt.CustomChunks.Add(chunk); break; } } } return(rt); }
public static MqChunk Parse(MqTokenizer tokenizer) { while (tokenizer.Current.Kind == MqTokenizer.NewLineTokenKind) tokenizer.MoveNext(); var rt = new MqChunk { Name = tokenizer.Current.Kind == MqTokenizer.IdentifierTokenKind || tokenizer.Current.Kind == MqTokenizer.StringTokenKind ? tokenizer.Current.Text : null, }; var args = tokenizer.StartWith(tokenizer.Current.Kind == MqTokenizer.DigitTokenKind ? new[] { tokenizer.Current } : new Token[0]) .TakeWhile(_ => _.Kind != MqTokenizer.BeginChildrenTokenKind && _.Kind != MqTokenizer.NewLineTokenKind) .ToArray(); rt.Arguments = args.TakeWhile(_ => _.Kind == MqTokenizer.DigitTokenKind || _.Kind == MqTokenizer.StringTokenKind).Select(_ => _.Text).ToList(); rt.Attributes = Util.Defer(() => { var attrs = args.Skip(rt.Arguments.Count); var current = attrs.FirstOrDefault(); return attrs.GroupBy(_ => { if (_.Kind == MqTokenizer.IdentifierTokenKind) current = _; return current; }) .Select(_ => new MqChunkAttribute { Name = _.Key.Text, Arguments = _.Skip(1).Select(t => t.Text).ToList(), }); }).ToList(); if (tokenizer.Current.Kind == MqTokenizer.BeginChildrenTokenKind) { rt.Children = tokenizer.TakeWhile(_ => _.Kind != MqTokenizer.EndChildrenTokenKind) .Select(_ => Parse(tokenizer)) .ToList(); tokenizer.MoveNext(MqTokenizer.EndChildrenTokenKind); } return rt; }
public static MqDocument Parse(string text) { var rt = new MqDocument(); var tokenizer = new MqTokenizer(text); var header = new[] { "Metasequoia", "Document", "\n", "Format", "Text", "Ver" }; if (!tokenizer.Take(header.Length).Select(_ => _.Text).SequenceEqual(header)) throw new InvalidOperationException("invalid format"); rt.Version = float.Parse(tokenizer.MoveNext().EnsureKind(MqTokenizer.DigitTokenKind).Text); if (rt.Version >= 2) throw new NotSupportedException("specified format version not supported"); foreach (var i in tokenizer) if (i.Kind == MqTokenizer.IdentifierTokenKind) { var chunk = MqChunk.Parse(tokenizer); switch (chunk.Name.ToLower()) { case "includexml": rt.IncludeXml = chunk.Arguments.First().Trim('"'); break; case "scene": rt.Scene = MqScene.Parse(chunk); break; case "material": rt.Materials = chunk.Children.Select(MqMaterial.Parse).ToList(); break; case "object": rt.Objects.Add(MqObject.Parse(chunk)); break; case "eof": break; default: rt.CustomChunks.Add(chunk); break; } } return rt; }