/// <summary>Extract a token from the front of a lexical input queue.</summary> /// <param name="input">The input from which to extract a token. The extracted lexical bits will be removed from the queue.</param> /// <param name="impliedBraces">Whether we're parsing a token context (so the outer '{{' and '}}' are implied); else parse as a tokenizable string which main contain a mix of literal and {{token}} values.</param> /// <returns>Returns the token.</returns> public LexTokenToken ExtractToken(Queue <LexBit> input, bool impliedBraces) { LexBit GetNextAndAssert(string expectedPhrase) { if (!input.Any()) { throw new LexFormatException($"Reached end of input, expected {expectedPhrase}."); } return(input.Dequeue()); } // start token if (!impliedBraces) { LexBit startToken = GetNextAndAssert("start of token ('{{')"); if (startToken.Type != LexBitType.StartToken) { throw new LexFormatException($"Unexpected {startToken.Type} at start of token."); } } // extract token name LexBit name = GetNextAndAssert("token name"); if (name.Type != LexBitType.Literal) { throw new LexFormatException($"Unexpected {name.Type} where token name should be."); } // extract input argument if present LexTokenInputArg inputArg = null; if (input.Any() && input.Peek().Type == LexBitType.InputArgSeparator) { input.Dequeue(); inputArg = this.ExtractInputArgument(input); } // end token if (!impliedBraces) { LexBit endToken = GetNextAndAssert("end of token ('}}')"); if (endToken.Type != LexBitType.EndToken) { throw new LexFormatException($"Unexpected {endToken.Type} before end of token."); } } return(new LexTokenToken(name.Text.Trim(), inputArg, impliedBraces)); }
/// <summary>Construct an instance.</summary> /// <param name="raw">The raw token input argument.</param> /// <param name="context">The available token context.</param> public TokenString(LexTokenInputArg raw, IContext context) : this(lexTokens : raw?.Parts, context : context) { }