TOptional<FExpressionError> ParseEscapedChar(FExpressionTokenConsumer& Consumer) { FTokenStream& Stream = Consumer.GetStream(); TOptional<FStringToken> Token = Stream.ParseSymbol(EscapeChar); if (!Token.IsSet()) { return TOptional<FExpressionError>(); } FStringToken& TokenValue = Token.GetValue(); // Accumulate the next character into the token TOptional<FStringToken> EscapedChar = Consumer.GetStream().ParseSymbol(&TokenValue); if (!EscapedChar.IsSet()) { return TOptional<FExpressionError>(); } // Check for a valid escape character const TCHAR Character = *EscapedChar->GetTokenStartPos(); if (IsValidEscapeChar(Character)) { // Add the token to the consumer - this moves the read position in the stream to the end of the token. Consumer.Add(TokenValue, FEscapedCharacter(Character)); } return TOptional<FExpressionError>(); }
/** Parse an escaped character */ TOptional<FExpressionError> ParseEscapedChar(FExpressionTokenConsumer& Consumer, bool bEmitErrors) { static const TCHAR* ValidEscapeChars = TEXT("{`"); TOptional<FStringToken> Token = Consumer.GetStream().ParseSymbol(EscapeChar); if (!Token.IsSet()) { return TOptional<FExpressionError>(); } // Accumulate the next character into the token TOptional<FStringToken> EscapedChar = Consumer.GetStream().ParseSymbol(&Token.GetValue()); if (!EscapedChar.IsSet()) { return TOptional<FExpressionError>(); } // Check for a valid escape character const TCHAR Character = *EscapedChar->GetTokenStartPos(); if (FCString::Strchr(ValidEscapeChars, Character)) { // Add the token to the consumer. This moves the read position in the stream to the end of the token. Consumer.Add(Token.GetValue(), FEscapedCharacter(Character)); return TOptional<FExpressionError>(); } else if (bEmitErrors) { FString CharStr; CharStr += Character; FFormatOrderedArguments Args; Args.Add(FText::FromString(CharStr)); return FExpressionError(FText::Format(LOCTEXT("InvalidEscapeCharacter", "Invalid escape character '{0}'"), Args)); } else { return TOptional<FExpressionError>(); } }