IReadOnlyList <Ast.Variant> GetVariants(FtlParserStream ps) { var variants = new List <Ast.Variant>(); bool hasDefault = false; while (true) { ps.ExpectIndent(); var variant = GetVariant(ps, hasDefault); if (variant.IsDefault) { hasDefault = true; } variants.Add(variant); if (!ps.IsPeekNextLineVariantStart()) { break; } } if (!hasDefault) { throw new ParseException("E0010"); } return(variants); }
Ast.SyntaxNode _GetVariantList(FtlParserStream ps) { ps.ExpectChar('{'); ps.SkipInlineWs(); var variants = GetVariants(ps); ps.ExpectIndent(); ps.ExpectChar('}'); return(new Ast.VariantList(variants)); }
IReadOnlyList <Ast.Attribute> GetAttributes(FtlParserStream ps) { var attrs = new List <Ast.Attribute>(); while (true) { ps.ExpectIndent(); var attr = GetAttribute(ps); attrs.Add(attr); if (!ps.IsPeekNextLineAttributeStart()) { break; } } return(attrs); }
Ast.SyntaxNode _GetExpression(FtlParserStream ps) { ps.SkipInlineWs(); var selector = GetSelectorExpression(ps); ps.SkipInlineWs(); if (ps.CurrentIs('-')) { ps.Peek(); if (!ps.CurrentPeekIs('>')) { ps.ResetPeek(); return(selector); } if (selector is Ast.MessageReference) { throw new ParseException("E0016"); } if (selector is Ast.AttributeExpression ae && ae.Ref is Ast.MessageReference) { throw new ParseException("E0018"); } if (selector is Ast.VariantExpression) { throw new ParseException("E0017"); } ps.Next(); ps.Next(); ps.SkipInlineWs(); var variants = GetVariants(ps); if (variants.Count == 0) { throw new ParseException("E0011"); } // VariantLists are only allowed in other VariantLists. if (variants.Any(v => v.Value is Ast.VariantList)) { throw new ParseException("E0023"); } ps.ExpectIndent(); return(new Ast.SelectExpression(selector, variants)); } else if (selector is Ast.AttributeExpression ae && ae.Ref is Ast.TermReference) { throw new ParseException("E0019"); } return(selector); }