Files
UnrealEngine/Engine/Source/Developer/ShaderCompilerCommon/Private/HlslLexer.h
2025-05-18 13:04:45 +08:00

412 lines
6.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
HlslLexer.h - Interface for scanning & tokenizing hlsl.
=============================================================================*/
#pragma once
#include "CoreMinimal.h"
#include "Containers/IndirectArray.h"
#include "HlslUtils.h"
class Error;
namespace CrossCompiler
{
enum class EHlslToken
{
// Control
Invalid,
Pragma,
// Math
Plus,
PlusEqual,
Minus,
MinusEqual,
Times,
TimesEqual,
Div,
DivEqual,
Mod,
ModEqual,
LeftParenthesis,
RightParenthesis,
// Logical
EqualEqual,
NotEqual,
Lower,
LowerEqual,
Greater,
GreaterEqual,
AndAnd,
OrOr,
// Bit
LowerLower,
LowerLowerEqual,
GreaterGreater,
GreaterGreaterEqual,
And,
AndEqual,
Or,
OrEqual,
Xor,
XorEqual,
Not,
Neg,
// Statements
Equal,
LeftBrace,
RightBrace,
Semicolon,
If,
Else,
For,
While,
Do,
Return,
Switch,
Case,
Break,
Default,
Continue,
Goto,
// Unary
PlusPlus,
MinusMinus,
// Types
Void,
Const,
Precise,
Bool,
Bool1,
Bool2,
Bool3,
Bool4,
Bool1x1,
Bool2x1,
Bool3x1,
Bool4x1,
Bool1x2,
Bool2x2,
Bool3x2,
Bool4x2,
Bool1x3,
Bool2x3,
Bool3x3,
Bool4x3,
Bool1x4,
Bool2x4,
Bool3x4,
Bool4x4,
Int,
Int1,
Int2,
Int3,
Int4,
Int1x1,
Int2x1,
Int3x1,
Int4x1,
Int1x2,
Int2x2,
Int3x2,
Int4x2,
Int1x3,
Int2x3,
Int3x3,
Int4x3,
Int1x4,
Int2x4,
Int3x4,
Int4x4,
Uint,
Uint1,
Uint2,
Uint3,
Uint4,
Uint1x1,
Uint2x1,
Uint3x1,
Uint4x1,
Uint1x2,
Uint2x2,
Uint3x2,
Uint4x2,
Uint1x3,
Uint2x3,
Uint3x3,
Uint4x3,
Uint1x4,
Uint2x4,
Uint3x4,
Uint4x4,
Uint64_t,
Uint64_t1,
Uint64_t2,
Uint64_t3,
Uint64_t4,
Uint64_t1x1,
Uint64_t2x1,
Uint64_t3x1,
Uint64_t4x1,
Uint64_t1x2,
Uint64_t2x2,
Uint64_t3x2,
Uint64_t4x2,
Uint64_t1x3,
Uint64_t2x3,
Uint64_t3x3,
Uint64_t4x3,
Uint64_t1x4,
Uint64_t2x4,
Uint64_t3x4,
Uint64_t4x4,
Half,
Half1,
Half2,
Half3,
Half4,
Half1x1,
Half2x1,
Half3x1,
Half4x1,
Half1x2,
Half2x2,
Half3x2,
Half4x2,
Half1x3,
Half2x3,
Half3x3,
Half4x3,
Half1x4,
Half2x4,
Half3x4,
Half4x4,
Min16Float,
Min16Float1,
Min16Float2,
Min16Float3,
Min16Float4,
Min16Float1x1,
Min16Float2x1,
Min16Float3x1,
Min16Float4x1,
Min16Float1x2,
Min16Float2x2,
Min16Float3x2,
Min16Float4x2,
Min16Float1x3,
Min16Float2x3,
Min16Float3x3,
Min16Float4x3,
Min16Float1x4,
Min16Float2x4,
Min16Float3x4,
Min16Float4x4,
Float,
Float1,
Float2,
Float3,
Float4,
Float1x1,
Float2x1,
Float3x1,
Float4x1,
Float1x2,
Float2x2,
Float3x2,
Float4x2,
Float1x3,
Float2x3,
Float3x3,
Float4x3,
Float1x4,
Float2x4,
Float3x4,
Float4x4,
Texture, // texture (SM3)
Texture1D,
Texture1DArray,
Texture2D,
Texture2DArray,
Texture2DMS,
Texture2DMSArray,
Texture3D,
TextureCube,
TextureCubeArray,
Sampler, // sampler (SM3)
Sampler1D, // sampler1D (SM3)
Sampler2D, // sampler2D (SM3)
Sampler3D, // sampler3D (SM3)
SamplerCube, // samplerCUBE (SM3)
SamplerState,
SamplerComparisonState,
Buffer,
AppendStructuredBuffer,
ByteAddressBuffer,
ConsumeStructuredBuffer,
RWBuffer,
RWByteAddressBuffer,
RWStructuredBuffer,
RWTexture1D,
RWTexture1DArray,
RWTexture2D,
RWTexture2DArray,
RasterizerOrderedTexture2D,
RWTexture3D,
StructuredBuffer,
ConstantBuffer,
RaytracingAccelerationStructure,
// Modifiers
In,
Out,
InOut,
Static,
Uniform,
// Misc
LeftSquareBracket,
RightSquareBracket,
Question,
Colon,
ColonColon,
Comma,
Dot,
Struct,
CBuffer,
GroupShared,
RowMajor,
Register,
Inline,
Typedef,
PackOffset,
Namespace,
Identifier,
Operator, // HLSL2021
Literal,
BoolConstant,
StringConstant, // C-style "string"
StaticAssert, // _Static_assert (HLSL), static_assert (C++11)
C99Pragma, // _Pragma (C99/C++11)
};
enum class ELiteralType
{
Unknown = -1,
Float, // All variations
FloatSuffix, // All variations, ends with 'f'
Integer, // Just digits
IntegerSuffix, // has a 'u|U|l|L' suffix
Hex, // has '0x' or '0X' prefix
HexSuffix, // Hex + has a 'u|U|l|L' suffix
Octal, // 0[0..7]+
Bool, // true or false
};
static inline bool IsIntegerType(ELiteralType Type)
{
switch (Type)
{
case ELiteralType::Integer:
case ELiteralType::IntegerSuffix:
case ELiteralType::Hex:
case ELiteralType::HexSuffix:
case ELiteralType::Octal:
return true;
default:
break;
}
return false;
}
struct FHlslToken
{
EHlslToken Token;
ELiteralType LiteralType = ELiteralType::Unknown;
FString String; // yuriy-todo: allocate this from linear allocator or simply point to the input source code and use FStringView
FSourceInfo SourceInfo;
explicit FHlslToken(FStringView Identifier) : Token(EHlslToken::Identifier), String(Identifier) { DebugId(); }
explicit FHlslToken(EHlslToken InToken, FStringView Identifier) : Token(InToken), String(Identifier) { DebugId(); }
explicit FHlslToken(FStringView InLiteral, ELiteralType InLiteralType) :
Token(EHlslToken::Literal),
LiteralType(InLiteralType),
String(InLiteral)
{ DebugId(); }
void DebugId()
{
#if UE_BUILD_DEBUG
static int32 DebugID = 0;
//ensure(DebugID != 4787);
++DebugID;
#endif
}
};
class FHlslScanner
{
public:
FHlslScanner(FCompilerMessages& InCompilerMessages);
virtual ~FHlslScanner();
// Processing
bool Lex(const FString& String, const FString& Filename);
void Dump();
// Iterating after Processing
uint32 GetCurrentTokenIndex() const
{
return CurrentToken;
}
void SetCurrentTokenIndex(uint32 NewToken);
bool HasMoreTokens() const;
bool MatchToken(EHlslToken InToken);
bool MatchIntegerLiteral();
const FHlslToken* PeekToken(uint32 LookAhead = 0) const;
const FHlslToken* GetCurrentToken() const;
const FHlslToken* GetCurrentTokenAndAdvance();
void Advance() {++CurrentToken;}
void SourceError(const FString& Error);
private:
FCompilerMessages& CompilerMessages;
TArray<FHlslToken> Tokens;
void EmplaceToken(FHlslToken&& Token, const struct FTokenizer& Tokenizer);
uint32 CurrentToken;
// Tokens point their source filenames here
TIndirectArray<FString> SourceFilenames;
void Clear(const FString& Filename);
friend struct FTokenizer;
};
}