Beispiel #1
0
        Ast.Variant _GetVariant(FtlParserStream ps, bool hasDefault)
        {
            bool defaultIndex = false;

            if (ps.CurrentIs('*'))
            {
                if (hasDefault)
                {
                    throw new ParseException("E0015");
                }
                ps.Next();
                defaultIndex = true;
                hasDefault   = true;
            }

            ps.ExpectChar('[');

            var key = GetVariantKey(ps);

            ps.ExpectChar(']');

            if (ps.IsPeekValueStart())
            {
                ps.SkipIndent();
                var value = GetValue(ps);
                return(new Ast.Variant(key, value, defaultIndex));
            }

            throw new ParseException("E0012");
        }
Beispiel #2
0
        Ast.Placeable _GetPlaceable(FtlParserStream ps)
        {
            ps.ExpectChar('{');
            var expression = GetExpression(ps);

            ps.ExpectChar('}');
            return(new Ast.Placeable(expression));
        }
Beispiel #3
0
        Ast.SyntaxNode _GetVariantList(FtlParserStream ps)
        {
            ps.ExpectChar('{');
            ps.SkipInlineWs();
            var variants = GetVariants(ps);

            ps.ExpectIndent();
            ps.ExpectChar('}');
            return(new Ast.VariantList(variants));
        }
Beispiel #4
0
        Ast.StringLiteral _GetString(FtlParserStream ps)
        {
            var val = new StringBuilder();

            ps.ExpectChar('"');

            int ch;

            while ((ch = ps.TakeChar(x => x != '"' && x != '\r' && x != '\n')) != Eof)
            {
                if (ch == '\\')
                {
                    GetEscapeSequence(ps, new int[] { '{', '\\', '"' }, val);
                }
                else
                {
                    val.Append((char)ch);
                }
            }

            if (ps.CurrentIs('\r') || ps.CurrentIs('\n'))
            {
                throw new ParseException("E0020");
            }

            ps.Next();

            return(new Ast.StringLiteral(val.ToString()));
        }
Beispiel #5
0
        Ast.Identifier _GetTermIdentifier(FtlParserStream ps)
        {
            ps.ExpectChar('-');
            var id = this.GetIdentifier(ps);

            return(new Ast.Identifier($"-{id.Name}"));
        }
Beispiel #6
0
        Ast.Entry _GetTerm(FtlParserStream ps)
        {
            var id = GetTermIdentifier(ps);

            ps.SkipInlineWs();
            ps.ExpectChar('=');

            Ast.SyntaxNode value = null;
            if (ps.IsPeekValueStart())
            {
                ps.SkipIndent();
                value = GetValue(ps);
            }
            else
            {
                throw new ParseException("E0006", id.Name);
            }

            IReadOnlyList <Ast.Attribute> attrs = null;

            if (ps.IsPeekNextLineAttributeStart())
            {
                attrs = GetAttributes(ps);
            }
            return(new Ast.Term(id, value, attrs));
        }
Beispiel #7
0
        Ast.Entry _GetMessage(FtlParserStream ps)
        {
            var id = GetIdentifier(ps);

            ps.SkipInlineWs();
            ps.ExpectChar('=');

            Ast.Pattern pattern = null;
            if (ps.IsPeekValueStart())
            {
                ps.SkipIndent();
                pattern = GetPattern(ps);
            }
            else
            {
                ps.SkipInlineWs();
            }

            IReadOnlyList <Ast.Attribute> attrs = null;

            if (ps.IsPeekNextLineAttributeStart())
            {
                attrs = GetAttributes(ps);
            }

            if (pattern == null && attrs == null)
            {
                throw new ParseException("E0005", id.Name);
            }

            return(new Ast.Message(id, pattern, attrs));
        }
Beispiel #8
0
        public Ast.BaseComment _GetComment(FtlParserStream ps)
        {
            // 0 - comment
            // 1 - group comment
            // 2 - resource comment
            int level   = -1;
            var content = new StringBuilder();

            while (true)
            {
                int i = -1;
                while (ps.CurrentIs('#') && (i < (level == -1 ? 2 : level)))
                {
                    ps.Next();
                    i++;
                }

                if (level == -1)
                {
                    level = i;
                }

                if (!ps.IsPeekNewLine())
                {
                    ps.ExpectChar(' ');
                    int ch;
                    while ((ch = ps.TakeChar(x => x != '\r' && x != '\n')) != Eof)
                    {
                        content.Append((char)ch);
                    }
                }

                if (ps.IsPeekNextLineComment(level))
                {
                    content.Append('\n');
                    ps.SkipNewLine();
                }
                else
                {
                    break;
                }
            }

            var text = content.ToString();

            switch (level)
            {
            case 0:
                return(new Ast.Comment(text));

            case 1:
                return(new Ast.GroupComment(text));

            case 2:
                return(new Ast.ResourceComment(text));
            }
            throw new InvalidOperationException($"Unknown level value '{level}'");
        }
Beispiel #9
0
        Ast.Attribute _GetAttribute(FtlParserStream ps)
        {
            ps.ExpectChar('.');

            var key = GetIdentifier(ps);

            ps.SkipInlineWs();
            ps.ExpectChar('=');

            if (ps.IsPeekValueStart())
            {
                ps.SkipIndent();
                var value = GetPattern(ps);
                return(new Ast.Attribute(key, value));
            }

            throw new ParseException("E0012");
        }
Beispiel #10
0
        Ast.SyntaxNode _GetSelectorExpression(FtlParserStream ps)
        {
            if (ps.CurrentIs('{'))
            {
                return(GetPlaceable(ps));
            }

            var literal = GetLiteral(ps);

            var mtReference = literal as Ast.MessageTermReference;

            if (mtReference == null)
            {
                return(literal);
            }

            var ch = ps.Current;

            if (ch == '.')
            {
                ps.Next();

                var attr = GetIdentifier(ps);
                return(new Ast.AttributeExpression(mtReference, attr));
            }

            if (ch == '[')
            {
                ps.Next();

                if (mtReference is Ast.MessageReference)
                {
                    throw new ParseException("E0024");
                }

                var key = GetVariantKey(ps);

                ps.ExpectChar(']');

                return(new Ast.VariantExpression(literal, key));
            }

            if (ch == '(')
            {
                ps.Next();

                if (!s_fnName.IsMatch(mtReference.Id.Name))
                {
                    throw new ParseException("E0008");
                }

                var args = GetCallArgs(ps);

                ps.ExpectChar(')');

                var func = new Ast.Function(mtReference.Id.Name);
                if (_withSpans)
                {
                    func.AddSpan(mtReference.Span.Start, mtReference.Span.End);
                }

                return(new Ast.CallExpression(func, args.Positional, args.Named));
            }

            return(literal);
        }