private void ParseReplacement(TokenReader <DocumentToken> reader, List <IDocumentExpression> ret) { var openToken = AdvanceAndExpectConstantType(reader, DocumentTokenType.BeginReplacementSegment); var replacementKeyToken = AdvanceAndExpect(reader, DocumentTokenType.ReplacementKey, "replacement key", skipWhitespace: true); List <DocumentToken> parameters = new List <DocumentToken>(); List <DocumentToken> body = new List <DocumentToken>(); while (reader.CanAdvance(skipWhitespace: true) && reader.Peek(skipWhitespace: true).TokenType == DocumentTokenType.ReplacementParameter) { var paramToken = reader.Advance(skipWhitespace: true); parameters.Add(paramToken); } DocumentToken closeReplacementToken; if (reader.TryAdvance(out closeReplacementToken, skipWhitespace: true) == false) { throw Unexpected(string.Format("'{0}' or '{1}'", DocumentToken.GetTokenTypeValue(DocumentTokenType.EndReplacementSegment), DocumentToken.GetTokenTypeValue(DocumentTokenType.QuickTerminateReplacementSegment))); } if (closeReplacementToken.TokenType == DocumentTokenType.EndReplacementSegment) { body.AddRange(ReadReplacementBody(reader, replacementKeyToken)); } else if (closeReplacementToken.TokenType == DocumentTokenType.QuickTerminateReplacementSegment) { // do nothing, there is no body when the quick termination replacement segment is used } else { throw Unexpected(string.Format("'{0}' or '{1}'", DocumentToken.GetTokenTypeValue(DocumentTokenType.EndReplacementSegment), DocumentToken.GetTokenTypeValue(DocumentTokenType.QuickTerminateReplacementSegment)), closeReplacementToken); } IDocumentExpressionProvider provider; if (this.expressionProviders.TryGetValue(replacementKeyToken.Value, out provider) == false) { provider = new EvalExpressionProvider(); } var context = new DocumentExpressionContext { OpenToken = openToken, CloseToken = closeReplacementToken, Parameters = parameters.AsReadOnly(), Body = body.AsReadOnly(), ReplacementKeyToken = replacementKeyToken, }; var expression = provider.CreateExpression(context); ret.Add(expression); }
private DocumentToken AdvanceAndExpectConstantType(TokenReader <DocumentToken> reader, DocumentTokenType expectedType) { DocumentToken read; if (reader.TryAdvance(out read, skipWhitespace: true) == false) { throw Unexpected(DocumentToken.GetTokenTypeValue(expectedType)); } if (read.TokenType != expectedType) { throw Unexpected(DocumentToken.GetTokenTypeValue(expectedType), read); } return(read); }