[HLSL][RootSignature] Add lexing support for floating points (#137720)
- this takes care to add support to match the [behaviour of
DXC](34b6d0f91e/tools/clang/lib/Parse/HLSLRootSignature.cpp (L74))
acceptable floating point integers
Namely:
- Allow for specifying the decimal '.'
- Allow for specifying exponents with 'e' or 'E' and allow for 'f' to
denote an otherwise interpreted integer as a float
This pr is simply responsible of creating a token that could be
interpeted as a floating point integer by `NumericLiteralParser`. As
such, we are not required to validate that the special characters only
occur once and that 'f' is only at the end of the string. These will be
validated when invoking `NumericLiteralParser` during parsing.
Resolves #126565
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
TOK(invalid, "invalid identifier")
|
||||
TOK(end_of_stream, "end of stream")
|
||||
TOK(int_literal, "integer literal")
|
||||
TOK(float_literal, "float literal")
|
||||
|
||||
// Register Tokens:
|
||||
TOK(bReg, "b register")
|
||||
|
||||
@@ -16,8 +16,10 @@ using TokenKind = RootSignatureToken::Kind;
|
||||
// Lexer Definitions
|
||||
|
||||
static bool isNumberChar(char C) {
|
||||
// TODO(#126565): extend for float support exponents
|
||||
return isdigit(C); // integer support
|
||||
return isdigit(C) // integer support
|
||||
|| C == '.' // float support
|
||||
|| C == 'e' || C == 'E' || C == '-' || C == '+' // exponent support
|
||||
|| C == 'f' || C == 'F'; // explicit float support
|
||||
}
|
||||
|
||||
RootSignatureToken RootSignatureLexer::lexToken() {
|
||||
@@ -45,10 +47,15 @@ RootSignatureToken RootSignatureLexer::lexToken() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Integer literal
|
||||
if (isdigit(C)) {
|
||||
Result.TokKind = TokenKind::int_literal;
|
||||
// Number literal
|
||||
if (isdigit(C) || C == '.') {
|
||||
Result.NumSpelling = Buffer.take_while(isNumberChar);
|
||||
|
||||
// If all values are digits then we have an int literal
|
||||
bool IsInteger = Result.NumSpelling.find_if_not(isdigit) == StringRef::npos;
|
||||
|
||||
Result.TokKind =
|
||||
IsInteger ? TokenKind::int_literal : TokenKind::float_literal;
|
||||
advanceBuffer(Result.NumSpelling.size());
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
|
||||
// This test will check that we can lex different number tokens
|
||||
const llvm::StringLiteral Source = R"cc(
|
||||
-42 42 +42 +2147483648
|
||||
42. 4.2 .42
|
||||
42f 4.2F
|
||||
.42e+3 4.2E-12
|
||||
42.e+10f
|
||||
)cc";
|
||||
|
||||
auto TokLoc = SourceLocation();
|
||||
@@ -51,9 +55,14 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
|
||||
|
||||
SmallVector<hlsl::RootSignatureToken> Tokens;
|
||||
SmallVector<TokenKind> Expected = {
|
||||
TokenKind::pu_minus, TokenKind::int_literal, TokenKind::int_literal,
|
||||
TokenKind::pu_plus, TokenKind::int_literal, TokenKind::pu_plus,
|
||||
TokenKind::int_literal,
|
||||
TokenKind::pu_minus, TokenKind::int_literal,
|
||||
TokenKind::int_literal, TokenKind::pu_plus,
|
||||
TokenKind::int_literal, TokenKind::pu_plus,
|
||||
TokenKind::int_literal, TokenKind::float_literal,
|
||||
TokenKind::float_literal, TokenKind::float_literal,
|
||||
TokenKind::float_literal, TokenKind::float_literal,
|
||||
TokenKind::float_literal, TokenKind::float_literal,
|
||||
TokenKind::float_literal,
|
||||
};
|
||||
checkTokens(Lexer, Tokens, Expected);
|
||||
|
||||
@@ -73,13 +82,45 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexNumbersTest) {
|
||||
// is treated as an unsigned integer instead
|
||||
IntToken = Tokens[6];
|
||||
ASSERT_EQ(IntToken.NumSpelling, "2147483648");
|
||||
|
||||
// Sample decimal end
|
||||
hlsl::RootSignatureToken FloatToken = Tokens[7];
|
||||
ASSERT_EQ(FloatToken.NumSpelling, "42.");
|
||||
|
||||
// Sample decimal middle
|
||||
FloatToken = Tokens[8];
|
||||
ASSERT_EQ(FloatToken.NumSpelling, "4.2");
|
||||
|
||||
// Sample decimal start
|
||||
FloatToken = Tokens[9];
|
||||
ASSERT_EQ(FloatToken.NumSpelling, ".42");
|
||||
|
||||
// Sample float lower
|
||||
FloatToken = Tokens[10];
|
||||
ASSERT_EQ(FloatToken.NumSpelling, "42f");
|
||||
|
||||
// Sample float upper
|
||||
FloatToken = Tokens[11];
|
||||
ASSERT_EQ(FloatToken.NumSpelling, "4.2F");
|
||||
|
||||
// Sample exp +
|
||||
FloatToken = Tokens[12];
|
||||
ASSERT_EQ(FloatToken.NumSpelling, ".42e+3");
|
||||
|
||||
// Sample exp -
|
||||
FloatToken = Tokens[13];
|
||||
ASSERT_EQ(FloatToken.NumSpelling, "4.2E-12");
|
||||
|
||||
// Sample all combined
|
||||
FloatToken = Tokens[14];
|
||||
ASSERT_EQ(FloatToken.NumSpelling, "42.e+10f");
|
||||
}
|
||||
|
||||
TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
|
||||
// This test will check that we can lex all defined tokens as defined in
|
||||
// HLSLRootSignatureTokenKinds.def, plus some additional integer variations
|
||||
const llvm::StringLiteral Source = R"cc(
|
||||
42
|
||||
42 42.0f
|
||||
|
||||
b0 t43 u987 s234
|
||||
|
||||
|
||||
Reference in New Issue
Block a user