diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc index 5fbe325608..af8ab7ec34 100644 --- a/src/reader/wgsl/lexer.cc +++ b/src/reader/wgsl/lexer.cc @@ -411,10 +411,6 @@ Token Lexer::try_punctuation() { type = Token::Type::kBang; pos_ += 1; location_.column += 1; - } else if (matches(pos_, "::")) { - type = Token::Type::kNamespace; - pos_ += 2; - location_.column += 2; } else if (matches(pos_, ":")) { type = Token::Type::kColon; pos_ += 1; @@ -497,22 +493,14 @@ Token Lexer::try_punctuation() { Token Lexer::check_keyword(const Source& source, const std::string& str) { if (str == "array") return {Token::Type::kArray, source, "array"}; - if (str == "binding") - return {Token::Type::kBinding, source, "binding"}; if (str == "bitcast") return {Token::Type::kBitcast, source, "bitcast"}; - if (str == "block") - return {Token::Type::kBlock, source, "block"}; if (str == "bool") return {Token::Type::kBool, source, "bool"}; if (str == "break") return {Token::Type::kBreak, source, "break"}; - if (str == "builtin") - return {Token::Type::kBuiltin, source, "builtin"}; if (str == "case") return {Token::Type::kCase, source, "case"}; - if (str == "compute") - return {Token::Type::kCompute, source, "compute"}; if (str == "const") return {Token::Type::kConst, source, "const"}; if (str == "continue") @@ -607,8 +595,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kFormatRgba8Unorm, source, "rgba8unorm"}; if (str == "rgba8unorm_srgb") return {Token::Type::kFormatRgba8UnormSrgb, source, "rgba8unorm_srgb"}; - if (str == "fragment") - return {Token::Type::kFragment, source, "fragment"}; if (str == "function") return {Token::Type::kFunction, source, "function"}; if (str == "i32") @@ -621,8 +607,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kImport, source, "import"}; if (str == "in") return {Token::Type::kIn, source, "in"}; - if (str == "location") - return {Token::Type::kLocation, source, "location"}; if (str == "loop") return {Token::Type::kLoop, source, "loop"}; if (str == "mat2x2") @@ -643,8 +627,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kMat4x3, source, "mat4x3"}; if (str == "mat4x4") return {Token::Type::kMat4x4, source, "mat4x4"}; - if (str == "offset") - return {Token::Type::kOffset, source, "offset"}; if (str == "out") return {Token::Type::kOut, source, "out"}; if (str == "private") @@ -657,14 +639,8 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kSampler, source, "sampler"}; if (str == "sampler_comparison") return {Token::Type::kComparisonSampler, source, "sampler_comparison"}; - if (str == "set") - return {Token::Type::kSet, source, "set"}; - if (str == "stage") - return {Token::Type::kStage, source, "stage"}; if (str == "storage_buffer") return {Token::Type::kStorageBuffer, source, "storage_buffer"}; - if (str == "stride") - return {Token::Type::kStride, source, "stride"}; if (str == "struct") return {Token::Type::kStruct, source, "struct"}; if (str == "switch") @@ -807,14 +783,10 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kVec3, source, "vec3"}; if (str == "vec4") return {Token::Type::kVec4, source, "vec4"}; - if (str == "vertex") - return {Token::Type::kVertex, source, "vertex"}; if (str == "void") return {Token::Type::kVoid, source, "void"}; if (str == "workgroup") return {Token::Type::kWorkgroup, source, "workgroup"}; - if (str == "workgroup_size") - return {Token::Type::kWorkgroupSize, source, "workgroup_size"}; return {}; } diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc index 1f2d142fa8..3a9d7bbece 100644 --- a/src/reader/wgsl/lexer_test.cc +++ b/src/reader/wgsl/lexer_test.cc @@ -435,7 +435,6 @@ INSTANTIATE_TEST_SUITE_P( TokenData{"%", Token::Type::kMod}, TokenData{"!=", Token::Type::kNotEqual}, TokenData{"-", Token::Type::kMinus}, - TokenData{"::", Token::Type::kNamespace}, TokenData{".", Token::Type::kPeriod}, TokenData{"+", Token::Type::kPlus}, TokenData{"|", Token::Type::kOr}, @@ -468,14 +467,10 @@ INSTANTIATE_TEST_SUITE_P( KeywordTest, testing::Values( TokenData{"array", Token::Type::kArray}, - TokenData{"binding", Token::Type::kBinding}, TokenData{"bitcast", Token::Type::kBitcast}, - TokenData{"block", Token::Type::kBlock}, TokenData{"bool", Token::Type::kBool}, TokenData{"break", Token::Type::kBreak}, - TokenData{"builtin", Token::Type::kBuiltin}, TokenData{"case", Token::Type::kCase}, - TokenData{"compute", Token::Type::kCompute}, TokenData{"const", Token::Type::kConst}, TokenData{"continue", Token::Type::kContinue}, TokenData{"continuing", Token::Type::kContinuing}, @@ -523,14 +518,12 @@ INSTANTIATE_TEST_SUITE_P( TokenData{"rgba8uint", Token::Type::kFormatRgba8Uint}, TokenData{"rgba8unorm", Token::Type::kFormatRgba8Unorm}, TokenData{"rgba8unorm_srgb", Token::Type::kFormatRgba8UnormSrgb}, - TokenData{"fragment", Token::Type::kFragment}, TokenData{"function", Token::Type::kFunction}, TokenData{"i32", Token::Type::kI32}, TokenData{"if", Token::Type::kIf}, TokenData{"image", Token::Type::kImage}, TokenData{"import", Token::Type::kImport}, TokenData{"in", Token::Type::kIn}, - TokenData{"location", Token::Type::kLocation}, TokenData{"loop", Token::Type::kLoop}, TokenData{"mat2x2", Token::Type::kMat2x2}, TokenData{"mat2x3", Token::Type::kMat2x3}, @@ -541,17 +534,13 @@ INSTANTIATE_TEST_SUITE_P( TokenData{"mat4x2", Token::Type::kMat4x2}, TokenData{"mat4x3", Token::Type::kMat4x3}, TokenData{"mat4x4", Token::Type::kMat4x4}, - TokenData{"offset", Token::Type::kOffset}, TokenData{"out", Token::Type::kOut}, TokenData{"private", Token::Type::kPrivate}, TokenData{"ptr", Token::Type::kPtr}, TokenData{"return", Token::Type::kReturn}, TokenData{"sampler", Token::Type::kSampler}, TokenData{"sampler_comparison", Token::Type::kComparisonSampler}, - TokenData{"set", Token::Type::kSet}, - TokenData{"stage", Token::Type::kStage}, TokenData{"storage_buffer", Token::Type::kStorageBuffer}, - TokenData{"stride", Token::Type::kStride}, TokenData{"struct", Token::Type::kStruct}, TokenData{"switch", Token::Type::kSwitch}, TokenData{"texture_1d", Token::Type::kTextureSampled1d}, @@ -621,10 +610,8 @@ INSTANTIATE_TEST_SUITE_P( TokenData{"vec2", Token::Type::kVec2}, TokenData{"vec3", Token::Type::kVec3}, TokenData{"vec4", Token::Type::kVec4}, - TokenData{"vertex", Token::Type::kVertex}, TokenData{"void", Token::Type::kVoid}, - TokenData{"workgroup", Token::Type::kWorkgroup}, - TokenData{"workgroup_size", Token::Type::kWorkgroupSize})); + TokenData{"workgroup", Token::Type::kWorkgroup})); using KeywordTest_Reserved = testing::TestWithParam; TEST_P(KeywordTest_Reserved, Parses) { diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index 699bbd2f0e..ff79577632 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc @@ -91,6 +91,13 @@ constexpr uint32_t kMaxConstExprDepth = 128; /// parser on error. constexpr size_t const kMaxResynchronizeLookahead = 32; +const char kVertexStage[] = "vertex"; +const char kFragmentStage[] = "fragment"; +const char kComputeStage[] = "compute"; + +const char kReadAccessControl[] = "read"; +const char kReadWriteAccessControl[] = "read_write"; + ast::Builtin ident_to_builtin(const std::string& str) { if (str == "position") { return ast::Builtin::kPosition; @@ -122,10 +129,27 @@ ast::Builtin ident_to_builtin(const std::string& str) { return ast::Builtin::kNone; } +const char kAccessDecoration[] = "access"; +const char kBindingDecoration[] = "binding"; +const char kBlockDecoration[] = "block"; +const char kBuiltinDecoration[] = "builtin"; +const char kLocationDecoration[] = "location"; +const char kOffsetDecoration[] = "offset"; +const char kSetDecoration[] = "set"; +const char kStageDecoration[] = "stage"; +const char kStrideDecoration[] = "stride"; +const char kWorkgroupSizeDecoration[] = "workgroup_size"; + bool is_decoration(Token t) { - return t.IsLocation() || t.IsBinding() || t.IsSet() || t.IsBuiltin() || - t.IsWorkgroupSize() || t.IsStage() || t.IsBlock() || t.IsStride() || - t.IsOffset(); + if (!t.IsIdentifier()) + return false; + + auto s = t.to_str(); + return s == kAccessDecoration || s == kBindingDecoration || + s == kBlockDecoration || s == kBuiltinDecoration || + s == kLocationDecoration || s == kOffsetDecoration || + s == kSetDecoration || s == kStageDecoration || + s == kStrideDecoration || s == kWorkgroupSizeDecoration; } /// Enter-exit counters for block token types. @@ -850,9 +874,9 @@ Expect ParserImpl::expect_access_type() { if (ident.errored) return Failure::kErrored; - if (ident.value == "read") + if (ident.value == kReadAccessControl) return {ast::AccessControl::kReadOnly, ident.source}; - if (ident.value == "read_write") + if (ident.value == kReadWriteAccessControl) return {ast::AccessControl::kReadWrite, ident.source}; return add_error(ident.source, "invalid value for access decoration"); @@ -1338,15 +1362,24 @@ Expect ParserImpl::expect_param_list() { // | FRAGMENT // | COMPUTE Expect ParserImpl::expect_pipeline_stage() { - Source source; - if (match(Token::Type::kVertex, &source)) - return {ast::PipelineStage::kVertex, source}; + auto t = peek(); + if (!t.IsIdentifier()) { + return add_error(t, "invalid value for stage decoration"); + } - if (match(Token::Type::kFragment, &source)) - return {ast::PipelineStage::kFragment, source}; - - if (match(Token::Type::kCompute, &source)) - return {ast::PipelineStage::kCompute, source}; + auto s = t.to_str(); + if (s == kVertexStage) { + next(); // Consume the peek + return {ast::PipelineStage::kVertex, t.source()}; + } + if (s == kFragmentStage) { + next(); // Consume the peek + return {ast::PipelineStage::kFragment, t.source()}; + } + if (s == kComputeStage) { + next(); // Consume the peek + return {ast::PipelineStage::kCompute, t.source()}; + } return add_error(peek(), "invalid value for stage decoration"); } @@ -2774,7 +2807,13 @@ Expect ParserImpl::expect_decoration() { Maybe ParserImpl::decoration() { using Result = Maybe; auto t = next(); - if (t.IsIdentifier() && t.to_str() == "access") { + + if (!t.IsIdentifier()) { + return Failure::kNoMatch; + } + + auto s = t.to_str(); + if (s == kAccessDecoration) { const char* use = "access decoration"; return expect_paren_block(use, [&]() -> Result { auto val = expect_access_type(); @@ -2784,7 +2823,8 @@ Maybe ParserImpl::decoration() { return create(val.value, val.source); }); } - if (t.IsLocation()) { + + if (s == kLocationDecoration) { const char* use = "location decoration"; return expect_paren_block(use, [&]() -> Result { auto val = expect_positive_sint(use); @@ -2794,7 +2834,8 @@ Maybe ParserImpl::decoration() { return create(val.value, val.source); }); } - if (t.IsBinding()) { + + if (s == kBindingDecoration) { const char* use = "binding decoration"; return expect_paren_block(use, [&]() -> Result { auto val = expect_positive_sint(use); @@ -2804,7 +2845,8 @@ Maybe ParserImpl::decoration() { return create(val.value, val.source); }); } - if (t.IsSet()) { + + if (s == kSetDecoration) { const char* use = "set decoration"; return expect_paren_block(use, [&]() -> Result { auto val = expect_positive_sint(use); @@ -2814,7 +2856,8 @@ Maybe ParserImpl::decoration() { return create(val.value, val.source); }); } - if (t.IsBuiltin()) { + + if (s == kBuiltinDecoration) { return expect_paren_block("builtin decoration", [&]() -> Result { auto builtin = expect_builtin(); if (builtin.errored) @@ -2823,7 +2866,8 @@ Maybe ParserImpl::decoration() { return create(builtin.value, builtin.source); }); } - if (t.IsWorkgroupSize()) { + + if (s == kWorkgroupSizeDecoration) { return expect_paren_block("workgroup_size decoration", [&]() -> Result { uint32_t x; uint32_t y = 1; @@ -2851,7 +2895,8 @@ Maybe ParserImpl::decoration() { return create(x, y, z, t.source()); }); } - if (t.IsStage()) { + + if (s == kStageDecoration) { return expect_paren_block("stage decoration", [&]() -> Result { auto stage = expect_pipeline_stage(); if (stage.errored) @@ -2860,10 +2905,12 @@ Maybe ParserImpl::decoration() { return create(stage.value, stage.source); }); } - if (t.IsBlock()) { + + if (s == kBlockDecoration) { return create(t.source()); } - if (t.IsStride()) { + + if (s == kStrideDecoration) { const char* use = "stride decoration"; return expect_paren_block(use, [&]() -> Result { auto val = expect_nonzero_positive_sint(use); @@ -2873,7 +2920,8 @@ Maybe ParserImpl::decoration() { return create(val.value, t.source()); }); } - if (t.IsOffset()) { + + if (s == kOffsetDecoration) { const char* use = "offset decoration"; return expect_paren_block(use, [&]() -> Result { auto val = expect_positive_sint(use); @@ -2883,6 +2931,7 @@ Maybe ParserImpl::decoration() { return create(val.value, t.source()); }); } + return Failure::kNoMatch; } diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc index 4952d20f3f..4338ac29c4 100644 --- a/src/reader/wgsl/token.cc +++ b/src/reader/wgsl/token.cc @@ -84,8 +84,6 @@ std::string Token::TypeToName(Type type) { return "!="; case Token::Type::kMinus: return "-"; - case Token::Type::kNamespace: - return "::"; case Token::Type::kPeriod: return "."; case Token::Type::kPlus: @@ -107,22 +105,14 @@ std::string Token::TypeToName(Type type) { case Token::Type::kArray: return "array"; - case Token::Type::kBinding: - return "binding"; case Token::Type::kBitcast: return "bitcast"; - case Token::Type::kBlock: - return "block"; case Token::Type::kBool: return "bool"; case Token::Type::kBreak: return "break"; - case Token::Type::kBuiltin: - return "builtin"; case Token::Type::kCase: return "case"; - case Token::Type::kCompute: - return "compute"; case Token::Type::kConst: return "const"; case Token::Type::kContinue: @@ -217,8 +207,6 @@ std::string Token::TypeToName(Type type) { return "rgba8unorm"; case Token::Type::kFormatRgba8UnormSrgb: return "rgba8unorm_srgb"; - case Token::Type::kFragment: - return "fragment"; case Token::Type::kFunction: return "function"; case Token::Type::kI32: @@ -231,8 +219,6 @@ std::string Token::TypeToName(Type type) { return "import"; case Token::Type::kIn: return "in"; - case Token::Type::kLocation: - return "location"; case Token::Type::kLoop: return "loop"; case Token::Type::kMat2x2: @@ -253,8 +239,6 @@ std::string Token::TypeToName(Type type) { return "mat4x3"; case Token::Type::kMat4x4: return "mat4x4"; - case Token::Type::kOffset: - return "offset"; case Token::Type::kOut: return "out"; case Token::Type::kPrivate: @@ -267,14 +251,8 @@ std::string Token::TypeToName(Type type) { return "sampler"; case Token::Type::kComparisonSampler: return "sampler_comparison"; - case Token::Type::kSet: - return "set"; case Token::Type::kStorageBuffer: return "storage_buffer"; - case Token::Type::kStride: - return "stride"; - case Token::Type::kStage: - return "stage"; case Token::Type::kStruct: return "struct"; case Token::Type::kSwitch: @@ -341,14 +319,10 @@ std::string Token::TypeToName(Type type) { return "vec3"; case Token::Type::kVec4: return "vec4"; - case Token::Type::kVertex: - return "vertex"; case Token::Type::kVoid: return "void"; case Token::Type::kWorkgroup: return "workgroup"; - case Token::Type::kWorkgroupSize: - return "workgroup_size"; } return ""; diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h index d0b2501a14..2c76a8f9f7 100644 --- a/src/reader/wgsl/token.h +++ b/src/reader/wgsl/token.h @@ -93,8 +93,6 @@ class Token { kMod, /// A '-' kMinus, - /// A '::' - kNamespace, /// A '!=' kNotEqual, /// A '.' @@ -118,22 +116,14 @@ class Token { /// A 'array' kArray, - /// A 'binding' - kBinding, /// A 'bitcast' kBitcast, /// A 'bool' kBool, - /// A 'block' - kBlock, /// A 'break' kBreak, - /// A 'builtin' - kBuiltin, /// A 'case' kCase, - /// A 'compute' - kCompute, /// A 'const' kConst, /// A 'continue' @@ -228,8 +218,6 @@ class Token { kFormatRgba8Unorm, // A 'Rgba8UnormSrgb' format kFormatRgba8UnormSrgb, - /// A 'fragment' - kFragment, /// A 'function' kFunction, /// A 'i32' @@ -242,8 +230,6 @@ class Token { kImport, /// A 'in' kIn, - /// A 'location' - kLocation, /// A 'loop' kLoop, /// A 'mat2x2' @@ -264,8 +250,6 @@ class Token { kMat4x3, /// A 'mat4x4' kMat4x4, - /// A 'offset' - kOffset, /// A 'out' kOut, /// A 'private' @@ -278,14 +262,8 @@ class Token { kSampler, /// A 'sampler_comparison' kComparisonSampler, - /// A 'set' - kSet, /// A 'storage_buffer' kStorageBuffer, - /// A 'stage' - kStage, - /// A 'stride' - kStride, /// A 'struct' kStruct, /// A 'switch' @@ -352,14 +330,10 @@ class Token { kVec3, /// A 'vec4' kVec4, - /// A 'vertex' - kVertex, /// A 'void' kVoid, /// A 'workgroup' kWorkgroup, - /// A 'workgroup_size' - kWorkgroupSize, }; /// Converts a token type to a name @@ -468,8 +442,6 @@ class Token { bool IsMod() const { return type_ == Type::kMod; } /// @returns true if token is a '-' bool IsMinus() const { return type_ == Type::kMinus; } - /// @returns true if token is a '::' - bool IsNamespace() const { return type_ == Type::kNamespace; } /// @returns true if token is a '!=' bool IsNotEqual() const { return type_ == Type::kNotEqual; } /// @returns true if token is a '.' @@ -493,24 +465,16 @@ class Token { /// @returns true if token is a 'array' bool IsArray() const { return type_ == Type::kArray; } - /// @returns true if token is a 'binding' - bool IsBinding() const { return type_ == Type::kBinding; } /// @returns true if token is a 'bitcast' bool IsBitcast() const { return type_ == Type::kBitcast; } - /// @returns true if token is a 'block' - bool IsBlock() const { return type_ == Type::kBlock; } /// @returns true if token is a 'bool' bool IsBool() const { return type_ == Type::kBool; } /// @returns true if token is a 'break' bool IsBreak() const { return type_ == Type::kBreak; } - /// @returns true if token is a 'builtin' - bool IsBuiltin() const { return type_ == Type::kBuiltin; } /// @returns true if token is a 'case' bool IsCase() const { return type_ == Type::kCase; } /// @returns true if token is a 'sampler_comparison' bool IsComparisonSampler() const { return type_ == Type::kComparisonSampler; } - /// @returns true if token is a 'compute' - bool IsCompute() const { return type_ == Type::kCompute; } /// @returns true if token is a 'const' bool IsConst() const { return type_ == Type::kConst; } /// @returns true if token is a 'continue' @@ -613,8 +577,6 @@ class Token { bool IsFormatRgba8UnormSrgb() const { return type_ == Type::kFormatRgba8UnormSrgb; } - /// @returns true if token is a 'fragment' - bool IsFragment() const { return type_ == Type::kFragment; } /// @returns true if token is a 'function' bool IsFunction() const { return type_ == Type::kFunction; } /// @returns true if token is a 'i32' @@ -627,8 +589,6 @@ class Token { bool IsImport() const { return type_ == Type::kImport; } /// @returns true if token is a 'in' bool IsIn() const { return type_ == Type::kIn; } - /// @returns true if token is a 'location' - bool IsLocation() const { return type_ == Type::kLocation; } /// @returns true if token is a 'loop' bool IsLoop() const { return type_ == Type::kLoop; } /// @returns true if token is a 'mat2x2' @@ -649,8 +609,6 @@ class Token { bool IsMat4x3() const { return type_ == Type::kMat4x3; } /// @returns true if token is a 'mat4x4' bool IsMat4x4() const { return type_ == Type::kMat4x4; } - /// @returns true if token is a 'offset' - bool IsOffset() const { return type_ == Type::kOffset; } /// @returns true if token is a 'out' bool IsOut() const { return type_ == Type::kOut; } /// @returns true if token is a 'private' @@ -661,14 +619,8 @@ class Token { bool IsReturn() const { return type_ == Type::kReturn; } /// @returns true if token is a 'sampler' bool IsSampler() const { return type_ == Type::kSampler; } - /// @returns true if token is a 'set' - bool IsSet() const { return type_ == Type::kSet; } - /// @returns true if token is a 'stage' - bool IsStage() const { return type_ == Type::kStage; } /// @returns true if token is a 'storage_buffer' bool IsStorageBuffer() const { return type_ == Type::kStorageBuffer; } - /// @returns true if token is a 'stride' - bool IsStride() const { return type_ == Type::kStride; } /// @returns true if token is a 'struct' bool IsStruct() const { return type_ == Type::kStruct; } /// @returns true if token is a 'switch' @@ -769,14 +721,10 @@ class Token { bool IsVec3() const { return type_ == Type::kVec3; } /// @returns true if token is a 'vec4' bool IsVec4() const { return type_ == Type::kVec4; } - /// @returns true if token is a 'vertex' - bool IsVertex() const { return type_ == Type::kVertex; } /// @returns true if token is a 'void' bool IsVoid() const { return type_ == Type::kVoid; } /// @returns true if token is a 'workgroup' bool IsWorkgroup() const { return type_ == Type::kWorkgroup; } - /// @returns true if token is a 'workgroup_size' - bool IsWorkgroupSize() const { return type_ == Type::kWorkgroupSize; } /// @returns the source information for this token Source source() const { return source_; }