Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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;
        }
Пример #4
0
        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;
        }