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"); }
Ast.Placeable _GetPlaceable(FtlParserStream ps) { ps.ExpectChar('{'); var expression = GetExpression(ps); ps.ExpectChar('}'); return(new Ast.Placeable(expression)); }
Ast.SyntaxNode _GetVariantList(FtlParserStream ps) { ps.ExpectChar('{'); ps.SkipInlineWs(); var variants = GetVariants(ps); ps.ExpectIndent(); ps.ExpectChar('}'); return(new Ast.VariantList(variants)); }
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())); }
Ast.Identifier _GetTermIdentifier(FtlParserStream ps) { ps.ExpectChar('-'); var id = this.GetIdentifier(ps); return(new Ast.Identifier($"-{id.Name}")); }
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)); }
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)); }
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}'"); }
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"); }
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); }