public static bool PeekAndParse(CharStream cs, out FTL.AST.Pattern pattern) { // A quoted-pattern is the easiest to detect, so we'll try that first if (cs.PeekNext() == '"') { pattern = ParseQuoted(cs); return(true); } // it might still be an unquoted-pattern, but this is trickier to detect // first let's try to detect a placeable and block-text if (Placeable.Peek(cs) || AnyText.PeekBlockText(cs)) { pattern = ParseUnquoted(cs); return(true); } // if not any of the above, the only thing left is unquoted-text int bufferPos = cs.Position; WhiteSpace.Parse(cs); char next = cs.PeekNext(); cs.Rewind(bufferPos); if (!CharStream.IsEOF(next) && !CharStream.IsNL(next)) { pattern = ParseUnquoted(cs); return(true); } pattern = null; return(false); }
public static FTL.AST.Member Parse(CharStream cs) { WhiteSpace.Parse(cs); bool isDefault = false; if (cs.PeekNext() == '*') { cs.SkipNext(); isDefault = true; } // Parse the MemberKey cs.SkipCharacter('['); FTL.AST.INode key = Memberkey.Parse(cs); cs.SkipCharacter(']'); // skip optional space WhiteSpace.Parse(cs); // Parse the actual pattern FTL.AST.Pattern pattern = Pattern.Parse(cs); // and return it all return(new FTL.AST.Member(key, pattern, isDefault)); }
public static FTL.AST.INode Parse(CharStream cs) { FTL.AST.INode result; // if it's an identifier, it could be either simply be an identifier, // or it could actually be a keyword-argument if (Identifier.PeekAndParse(cs, out result)) { int bufferPos = cs.Position; // ignore any whitespace WhiteSpace.Parse(cs); // if we now encounter a `=` char, we'll assume it's a keyword-argument, // and finish the parsing of that element, // otherwise we'll assume it's simply an identifier and return early if (cs.PeekNext() != '=') { cs.Rewind(bufferPos); return(Expresson.ParseWithIdentifier(cs, result as FTL.AST.StringPrimitive)); } cs.SkipNext(); WhiteSpace.Parse(cs); FTL.AST.Pattern pattern = Pattern.ParseQuoted(cs); return(new FTL.AST.KeywordArgument( result as L20n.FTL.AST.StringPrimitive, pattern)); } // it's not an identifier, so is must be any non-identifier expression return(Expresson.ParseNoneIdentifier(cs)); }
// (unquoted-text | placeable | block-text)+ public static FTL.AST.Pattern ParseUnquoted(CharStream cs) { FTL.AST.Pattern pattern = new FTL.AST.Pattern(false); FTL.AST.INode child = ParseUnquotedChild(cs); if (child == null) { throw cs.CreateException( "no unquoted child could be found, while at least one was expected", null); } do { pattern.AddChild(child); child = ParseUnquotedChild(cs); } while(child != null); return(pattern); }
private static FTL.AST.Message Parse(CharStream cs, Context ctx, FTL.AST.StringPrimitive identifier) { WhiteSpace.Parse(cs); cs.SkipCharacter('='); WhiteSpace.Parse(cs); FTL.AST.Pattern pattern = null; // check if we have a Pattern available bool hasPattern = Pattern.PeekAndParse(cs, out pattern); FTL.AST.MemberList memberList; bool parsedMemberList = MemberList.PeekAndParse(cs, out memberList); if (!parsedMemberList && !hasPattern) { throw cs.CreateException( "member-list was expected, as no pattern was found", null); } return(new FTL.AST.Message(identifier, pattern, memberList)); }
// '"' (placeable | quoted-text)* '"' public static FTL.AST.Pattern ParseQuoted(CharStream cs) { cs.SkipCharacter('"'); FTL.AST.Pattern pattern = new FTL.AST.Pattern(true); FTL.AST.INode child; while (cs.PeekNext() != '"') { if (Placeable.PeekAndParse(cs, out child)) { pattern.AddChild(child); continue; } // it's not a placeable, and we haven't seen a quote, // so it must be a quoted-text child = AnyText.ParseQuoted(cs); pattern.AddChild(child); } cs.SkipCharacter('"'); return(pattern); }