private void CheckValidPlaceable(string input, string rest = "") { var cs = NCS(input); L20n.FTL.AST.INode result; Assert.IsTrue(Placeable.PeekAndParse(cs, out result)); Assert.IsNotNull(result); Assert.AreEqual(rest, cs.ReadUntilEnd()); Assert.AreEqual(typeof(L20n.FTL.AST.Placeable), result.GetType()); }
// '"' (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); }
private static FTL.AST.INode ParseUnquotedChild(CharStream cs) { FTL.AST.INode child; if (Placeable.PeekAndParse(cs, out child)) { return(child); } if (AnyText.PeekAndParseBlock(cs, out child)) { return(child); } // as long as we don't have a newline char, // we'll assume it's an unquoted-child if (AnyText.PeekUnquoted(cs)) { return(AnyText.ParseUnquoted(cs)); } // return null if no child could be found return(null); }
// NL __ '|' __ (unquoted-text | placeable)+ public static bool PeekAndParseBlock(CharStream cs, out FTL.AST.INode result) { char next = cs.PeekNext(); // if next char isn't a NewLine Character, we know for sure we // are not dealing with a block-text if (CharStream.IsEOF(next) || !CharStream.IsNL(next)) { result = null; return(false); } // from here on out, we're still not sure if we're dealing with a block-text // thus we start buffering so we can go back in time // here we check if we have the following pattern: `NL __ '|'` int bufferPos = cs.Position; NewLine.Parse(cs); WhiteSpace.Parse(cs); // if the next unbuffered char is not '|' we're not dealing with a block-text // and can return; if (cs.PeekNext() != '|') { cs.Rewind(bufferPos); result = null; return(false); } // we know for sure we're dealing with a block-text, // buffer can be flushed and we can start checking for more lines as well; FTL.AST.INode line; FTL.AST.BlockText blockText = new FTL.AST.BlockText(); do { cs.SkipNext(); // skip '|' WhiteSpace.Parse(cs); if (!Placeable.PeekAndParse(cs, out line)) { // it's not a placeable, so it must be unquoted-text line = ParseUnquoted(cs); } // add line blockText.AddLine(line); // peek if next char is a newline char // otherwise we can stop early with trying next = cs.PeekNext(); if (CharStream.IsEOF(next) || !CharStream.IsNL(next)) { break; } // check if we have more lines bufferPos = cs.Position; NewLine.Parse(cs); WhiteSpace.Parse(cs); // as long as the next char is '|' // we'll keep looping if (cs.PeekNext() != '|') { cs.Rewind(bufferPos); break; } } while(true); result = blockText; return(true); }