Ejemplo n.º 1
0
        public static Dictionary <string, string> Read(TextReader reader, string filenameHint = null)
        {
            var properties = new Dictionary <string, string>(StringComparer.Ordinal);

            var yaml = new YamlLexer(reader, filenameHint);

            while (true)
            {
                var t = yaml.ReadNext();
                if (t.Kind == YamlTokenKind.EndOfFile)
                {
                    break;
                }

                if (t.Kind != YamlTokenKind.Property)
                {
                    // $$$ error
                    t = YamlToken.NewError(t.Span, "Only properties are supported in this context");
                }
                if (t.Kind == YamlTokenKind.Error)
                {
                    // ToString will include source span  and message.
                    throw new InvalidOperationException(t.ToString());
                }

                properties[t.Property] = t.Value;
            }
            return(properties);
        }
Ejemplo n.º 2
0
        // Parse the control definition line. Something like:
        //   Screen1 as Screen
        //   Label1 As Label.Variant
        private TypedNameNode ParseControlDef(YamlToken token)
        {
            string line = token.Property;

            if (!TryParseControlDefCore(line, out var controlName, out var templateName, out var variantName))
            {
                _errorContainer.ParseError(token.Span, "Can't parse control definition");
                throw new DocumentException();
            }

            return(new TypedNameNode
            {
                Identifier = controlName,
                Kind = new TypeNode
                {
                    TypeName = templateName,
                    OptionalVariant = variantName
                }
            });
        }
Ejemplo n.º 3
0
        private ArgMetadataBlockNode ParseArgMetadataBlock(YamlToken p)
        {
            var argNode = new ArgMetadataBlockNode()
            {
                Identifier = p.Property
            };

            while (true)
            {
                p = _yaml.ReadNext();
                switch (p.Kind)
                {
                case YamlTokenKind.EndObj:
                    return(argNode);

                case YamlTokenKind.Property:
                    if (p.Property == nameof(ArgMetadataBlockNode.Default))
                    {
                        argNode.Default = new ExpressionNode()
                        {
                            Expression = p.Value
                        }
                    }
                    ;
                    else
                    {
                        _errorContainer.ParseError(p.Span, $"Unexpected key in function definition: {p}");
                        throw new DocumentException();
                    }
                    break;

                case YamlTokenKind.Error:
                    _errorContainer.ParseError(p.Span, p.Value);
                    return(null);

                default:
                    _errorContainer.ParseError(p.Span, $"Unexpected yaml token: {p}");
                    throw new DocumentException();
                }
            }
        }
Ejemplo n.º 4
0
        // Name ( Parameter-Name As Data-type [ , Parameter-Name As Data-type ... ] ) :  (ThisProperty or Parameter-Name) :   Metadata-Name : Metadata-Value   ...  ...
        // Currently iterating on what fields are present in the property metadata blocks
        // Right now, only Default is permitted
        private FunctionNode ParseFunctionDef(YamlToken p)
        {
            // Validation here mirrors validation in PA-Client
            var paramRegex    = new Regex(@"^([\p{L}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]+?)\s+As\s+([\p{L}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]+)");
            var funcNameRegex = new Regex(@"^([\p{L}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]+?)\(");
            var line          = p.Property;
            var m             = funcNameRegex.Match(line);

            if (!m.Success)
            {
                _errorContainer.ParseError(p.Span, $"Can't parse Function definition");
                throw new DocumentException();
            }

            var funcName     = m.Groups[1].Value;
            var functionNode = new FunctionNode()
            {
                Identifier = funcName
            };

            line = line.Substring(m.Length);

            m = paramRegex.Match(line);
            while (m.Success)
            {
                string argName  = CharacterUtils.UnEscapeName(m.Groups[1].Value, _errorContainer);
                string kindName = CharacterUtils.UnEscapeName(m.Groups[2].Value, _errorContainer);

                functionNode.Args.Add(new TypedNameNode
                {
                    Identifier = argName,
                    Kind       = new TypeNode
                    {
                        TypeName = kindName
                    }
                });

                line = line.Substring(m.Length).TrimStart(',', ' ');
                m    = paramRegex.Match(line);
            }

            if (line != ")")
            {
                _errorContainer.ParseError(p.Span, $"Missing closing ')' in function definition");
                throw new DocumentException();
            }

            while (true)
            {
                p = _yaml.ReadNext();
                switch (p.Kind)
                {
                case YamlTokenKind.EndObj:
                    return(functionNode);

                // Expecting N+1 child objs where one is ThisProperty and the others N are the args
                case YamlTokenKind.StartObj:
                    functionNode.Metadata.Add(ParseArgMetadataBlock(p));
                    break;

                case YamlTokenKind.Error:
                    _errorContainer.ParseError(p.Span, p.Value);
                    return(null);

                default:
                    _errorContainer.ParseError(p.Span, $"Unexpected yaml token: {p}");
                    throw new DocumentException();
                }
            }
        }
Ejemplo n.º 5
0
        private BlockNode ParseNestedControl(YamlToken p)
        {
            if (p.Kind != YamlTokenKind.StartObj)
            {
                _errorContainer.ParseError(p.Span, $"Unexpected token {p}");
                throw new DocumentException();
            }

            var controlDef = ParseControlDef(p);

            var block = new BlockNode
            {
                Name = controlDef
            };

            while (true)
            {
                p = _yaml.ReadNext();
                switch (p.Kind)
                {
                case YamlTokenKind.EndObj:
                    return(block);

                case YamlTokenKind.Property:
                    block.Properties.Add(new PropertyNode
                    {
                        Identifier = CharacterUtils.UnEscapeName(p.Property, _errorContainer),
                        Expression = new ExpressionNode
                        {
                            Expression = p.Value
                        }
                    });
                    break;

                // StartObj can either be a Control or Function def
                case YamlTokenKind.StartObj:
                    if (IsControlStart(p.Property))
                    {
                        var childNode = ParseNestedControl(p);
                        if (_errorContainer.HasErrors)
                        {
                            return(null);
                        }
                        block.Children.Add(childNode);
                    }
                    else
                    {
                        var functionNode = ParseFunctionDef(p);
                        if (_errorContainer.HasErrors)
                        {
                            return(null);
                        }
                        block.Functions.Add(functionNode);
                    }
                    break;

                case YamlTokenKind.Error:
                    _errorContainer.ParseError(p.Span, p.Value);
                    return(null);

                default:
                    _errorContainer.ParseError(p.Span, $"Unexpected yaml token: {p}");
                    throw new DocumentException();
                }
            }
        }