blob: 33a6d64b17df352ea4050934029f2121d18e0d39 [file] [log] [blame]
Dan Sinclair6e581892020-03-02 15:47:43 -05001// Copyright 2020 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef SRC_READER_WGSL_PARSER_IMPL_H_
16#define SRC_READER_WGSL_PARSER_IMPL_H_
17
18#include <deque>
19#include <memory>
20#include <string>
21#include <unordered_map>
22#include <utility>
Ben Clayton88dc2a42020-11-04 20:55:31 +000023#include <vector>
Dan Sinclair6e581892020-03-02 15:47:43 -050024
Ben Clayton93e8f522021-06-04 20:41:47 +000025#include "src/ast/access.h"
Ben Claytona6b9a8e2021-01-26 16:57:10 +000026#include "src/program_builder.h"
Ben Clayton05737142020-11-09 20:44:34 +000027#include "src/reader/wgsl/parser_impl_detail.h"
Dan Sinclair6e581892020-03-02 15:47:43 -050028#include "src/reader/wgsl/token.h"
Antonio Maioranoaea9c682021-04-19 22:54:43 +000029#include "src/sem/storage_texture_type.h"
Dan Sinclair6e581892020-03-02 15:47:43 -050030
31namespace tint {
Antonio Maiorano73fdc162021-04-26 14:19:55 +000032namespace ast {
33class AssignmentStatement;
34class BreakStatement;
35class CallStatement;
36class ContinueStatement;
37class IfStatement;
38class LoopStatement;
39class ReturnStatement;
40class SwitchStatement;
41class VariableDeclStatement;
42} // namespace ast
43
Dan Sinclair6e581892020-03-02 15:47:43 -050044namespace reader {
45namespace wgsl {
46
47class Lexer;
48
dan sinclair8d72a2b2020-08-26 20:38:46 +000049/// Struct holding information for a for loop
Tomek Ponitka63a5aa72020-08-24 18:22:22 +000050struct ForHeader {
dan sinclair8d72a2b2020-08-26 20:38:46 +000051 /// Constructor
52 /// @param init the initializer statement
53 /// @param cond the condition statement
54 /// @param cont the continuing statement
Ben Claytonb053acf2020-11-16 16:31:07 +000055 ForHeader(ast::Statement* init, ast::Expression* cond, ast::Statement* cont);
Tomek Ponitka63a5aa72020-08-24 18:22:22 +000056
57 ~ForHeader();
dan sinclair8d72a2b2020-08-26 20:38:46 +000058
59 /// The for loop initializer
Ben Claytonb053acf2020-11-16 16:31:07 +000060 ast::Statement* initializer = nullptr;
dan sinclair8d72a2b2020-08-26 20:38:46 +000061 /// The for loop condition
Ben Claytonb053acf2020-11-16 16:31:07 +000062 ast::Expression* condition = nullptr;
dan sinclair8d72a2b2020-08-26 20:38:46 +000063 /// The for loop continuing statement
Ben Claytonb053acf2020-11-16 16:31:07 +000064 ast::Statement* continuing = nullptr;
Tomek Ponitka63a5aa72020-08-24 18:22:22 +000065};
66
Dan Sinclair6e581892020-03-02 15:47:43 -050067/// ParserImpl for WGSL source data
68class ParserImpl {
Ben Claytonab5dfee2020-11-09 19:52:24 +000069 /// Failure holds enumerator values used for the constructing an Expect and
70 /// Match in an errored state.
Ben Clayton653c4042020-11-09 19:39:34 +000071 struct Failure {
72 enum Errored { kErrored };
Ben Claytonab5dfee2020-11-09 19:52:24 +000073 enum NoMatch { kNoMatch };
Ben Clayton653c4042020-11-09 19:39:34 +000074 };
75
Dan Sinclair6e581892020-03-02 15:47:43 -050076 public:
Ben Clayton653c4042020-11-09 19:39:34 +000077 /// Expect is the return type of the parser methods that are expected to
78 /// return a parsed value of type T, unless there was an parse error.
79 /// In the case of a parse error the called method will have called
Ben Claytonf8971ae2020-12-02 15:31:08 +000080 /// add_error() and #errored will be set to true.
Ben Clayton653c4042020-11-09 19:39:34 +000081 template <typename T>
82 struct Expect {
83 /// An alias to the templated type T.
84 using type = T;
85
86 /// Don't allow an Expect to take a nullptr.
87 inline Expect(std::nullptr_t) = delete; // NOLINT
88
89 /// Constructor for a successful parse.
90 /// @param val the result value of the parse
91 /// @param s the optional source of the value
92 template <typename U>
93 inline Expect(U&& val, const Source& s = {}) // NOLINT
94 : value(std::forward<U>(val)), source(s) {}
95
96 /// Constructor for parse error.
97 inline Expect(Failure::Errored) : errored(true) {} // NOLINT
98
99 /// Copy constructor
100 inline Expect(const Expect&) = default;
101 /// Move constructor
102 inline Expect(Expect&&) = default;
103 /// Assignment operator
104 /// @return this Expect
105 inline Expect& operator=(const Expect&) = default;
106 /// Assignment move operator
107 /// @return this Expect
108 inline Expect& operator=(Expect&&) = default;
109
Ben Clayton05737142020-11-09 20:44:34 +0000110 /// @return a pointer to the returned value. If T is a pointer or
111 /// std::unique_ptr, operator->() automatically dereferences so that the
Ben Claytonf8971ae2020-12-02 15:31:08 +0000112 /// return type will always be a pointer to a non-pointer type. #errored
Ben Clayton05737142020-11-09 20:44:34 +0000113 /// must be false to call.
114 inline typename detail::OperatorArrow<T>::type operator->() {
Ben Claytonffd28e22021-06-24 11:27:36 +0000115 TINT_ASSERT(Reader, !errored);
Ben Clayton05737142020-11-09 20:44:34 +0000116 return detail::OperatorArrow<T>::ptr(value);
Ben Clayton653c4042020-11-09 19:39:34 +0000117 }
118
119 /// The expected value of a successful parse.
120 /// Zero-initialized when there was a parse error.
121 T value{};
122 /// Optional source of the value.
123 Source source;
124 /// True if there was a error parsing.
125 bool errored = false;
126 };
127
Ben Claytonab5dfee2020-11-09 19:52:24 +0000128 /// Maybe is the return type of the parser methods that attempts to match a
129 /// grammar and return a parsed value of type T, or may parse part of the
130 /// grammar and then hit a parse error.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000131 /// In the case of a successful grammar match, the Maybe will have #matched
Ben Claytonab5dfee2020-11-09 19:52:24 +0000132 /// set to true.
133 /// In the case of a parse error the called method will have called
Ben Claytonf8971ae2020-12-02 15:31:08 +0000134 /// add_error() and the Maybe will have #errored set to true.
Ben Claytonab5dfee2020-11-09 19:52:24 +0000135 template <typename T>
136 struct Maybe {
137 inline Maybe(std::nullptr_t) = delete; // NOLINT
138
139 /// Constructor for a successful parse.
140 /// @param val the result value of the parse
141 /// @param s the optional source of the value
142 template <typename U>
143 inline Maybe(U&& val, const Source& s = {}) // NOLINT
144 : value(std::forward<U>(val)), source(s), matched(true) {}
145
146 /// Constructor for parse error state.
147 inline Maybe(Failure::Errored) : errored(true) {} // NOLINT
148
149 /// Constructor for the no-match state.
150 inline Maybe(Failure::NoMatch) {} // NOLINT
151
152 /// Constructor from an Expect.
Ben Clayton05737142020-11-09 20:44:34 +0000153 /// @param e the Expect to copy this Maybe from
Ben Claytonab5dfee2020-11-09 19:52:24 +0000154 template <typename U>
155 inline Maybe(const Expect<U>& e) // NOLINT
156 : value(e.value),
157 source(e.value),
158 errored(e.errored),
159 matched(!e.errored) {}
160
161 /// Move from an Expect.
Ben Clayton05737142020-11-09 20:44:34 +0000162 /// @param e the Expect to move this Maybe from
Ben Claytonab5dfee2020-11-09 19:52:24 +0000163 template <typename U>
164 inline Maybe(Expect<U>&& e) // NOLINT
165 : value(std::move(e.value)),
166 source(std::move(e.source)),
167 errored(e.errored),
168 matched(!e.errored) {}
169
170 /// Copy constructor
171 inline Maybe(const Maybe&) = default;
172 /// Move constructor
173 inline Maybe(Maybe&&) = default;
174 /// Assignment operator
175 /// @return this Maybe
176 inline Maybe& operator=(const Maybe&) = default;
177 /// Assignment move operator
178 /// @return this Maybe
179 inline Maybe& operator=(Maybe&&) = default;
180
Ben Clayton05737142020-11-09 20:44:34 +0000181 /// @return a pointer to the returned value. If T is a pointer or
182 /// std::unique_ptr, operator->() automatically dereferences so that the
Ben Claytonf8971ae2020-12-02 15:31:08 +0000183 /// return type will always be a pointer to a non-pointer type. #errored
Ben Clayton05737142020-11-09 20:44:34 +0000184 /// must be false to call.
185 inline typename detail::OperatorArrow<T>::type operator->() {
Ben Claytonffd28e22021-06-24 11:27:36 +0000186 TINT_ASSERT(Reader, !errored);
Ben Clayton05737142020-11-09 20:44:34 +0000187 return detail::OperatorArrow<T>::ptr(value);
Ben Claytonab5dfee2020-11-09 19:52:24 +0000188 }
189
190 /// The value of a successful parse.
191 /// Zero-initialized when there was a parse error.
192 T value{};
193 /// Optional source of the value.
194 Source source;
195 /// True if there was a error parsing.
196 bool errored = false;
197 /// True if there was a error parsing.
198 bool matched = false;
199 };
200
Ben Clayton580d6c72020-11-02 15:25:18 +0000201 /// TypedIdentifier holds a parsed identifier and type. Returned by
202 /// variable_ident_decl().
203 struct TypedIdentifier {
Antonio Maiorano05abdf52021-04-23 08:19:33 +0000204 /// Constructor
205 TypedIdentifier();
206 /// Copy constructor
207 /// @param other the FunctionHeader to copy
208 TypedIdentifier(const TypedIdentifier& other);
209 /// Constructor
210 /// @param type_in parsed type
211 /// @param name_in parsed identifier
212 /// @param source_in source to the identifier
Ben Clayton7e002632021-06-16 09:19:36 +0000213 TypedIdentifier(ast::Type* type_in, std::string name_in, Source source_in);
Antonio Maiorano05abdf52021-04-23 08:19:33 +0000214 /// Destructor
215 ~TypedIdentifier();
216
Antonio Maiorano9834fef2021-06-04 15:28:47 +0000217 /// Parsed type. May be nullptr for inferred types.
218 ast::Type* type = nullptr;
Ben Clayton2d89d982020-11-02 18:02:18 +0000219 /// Parsed identifier.
220 std::string name;
221 /// Source to the identifier.
222 Source source;
Ben Clayton580d6c72020-11-02 15:25:18 +0000223 };
224
Ben Clayton234b7de2020-12-07 20:45:14 +0000225 /// FunctionHeader contains the parsed information for a function header.
226 struct FunctionHeader {
227 /// Constructor
228 FunctionHeader();
229 /// Copy constructor
230 /// @param other the FunctionHeader to copy
231 FunctionHeader(const FunctionHeader& other);
232 /// Constructor
233 /// @param src parsed header source
234 /// @param n function name
235 /// @param p function parameters
236 /// @param ret_ty function return type
James Pricefeecbe02021-03-15 17:01:34 +0000237 /// @param ret_decos return type decorations
Ben Clayton234b7de2020-12-07 20:45:14 +0000238 FunctionHeader(Source src,
239 std::string n,
240 ast::VariableList p,
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000241 ast::Type* ret_ty,
James Pricefeecbe02021-03-15 17:01:34 +0000242 ast::DecorationList ret_decos);
Ben Clayton234b7de2020-12-07 20:45:14 +0000243 /// Destructor
244 ~FunctionHeader();
245 /// Assignment operator
246 /// @param other the FunctionHeader to copy
247 /// @returns this FunctionHeader
248 FunctionHeader& operator=(const FunctionHeader& other);
249
250 /// Parsed header source
251 Source source;
252 /// Function name
253 std::string name;
254 /// Function parameters
255 ast::VariableList params;
256 /// Function return type
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000257 ast::Type* return_type;
James Pricefeecbe02021-03-15 17:01:34 +0000258 /// Function return type decorations
259 ast::DecorationList return_type_decorations;
Ben Clayton234b7de2020-12-07 20:45:14 +0000260 };
261
Ben Claytona80511e2020-12-11 13:07:02 +0000262 /// VarDeclInfo contains the parsed information for variable declaration.
263 struct VarDeclInfo {
Antonio Maiorano73fdc162021-04-26 14:19:55 +0000264 /// Constructor
265 VarDeclInfo();
266 /// Copy constructor
267 /// @param other the VarDeclInfo to copy
268 VarDeclInfo(const VarDeclInfo& other);
269 /// Constructor
270 /// @param source_in variable declaration source
271 /// @param name_in variable name
272 /// @param storage_class_in variable storage class
Ben Clayton93e8f522021-06-04 20:41:47 +0000273 /// @param access_in variable access control
Antonio Maiorano73fdc162021-04-26 14:19:55 +0000274 /// @param type_in variable type
275 VarDeclInfo(Source source_in,
276 std::string name_in,
277 ast::StorageClass storage_class_in,
Ben Clayton93e8f522021-06-04 20:41:47 +0000278 ast::Access access_in,
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000279 ast::Type* type_in);
Antonio Maiorano73fdc162021-04-26 14:19:55 +0000280 /// Destructor
281 ~VarDeclInfo();
282
Ben Claytona80511e2020-12-11 13:07:02 +0000283 /// Variable declaration source
284 Source source;
285 /// Variable name
286 std::string name;
287 /// Variable storage class
Ben Clayton93e8f522021-06-04 20:41:47 +0000288 ast::StorageClass storage_class = ast::StorageClass::kNone;
289 /// Variable access control
290 ast::Access access = ast::Access::kUndefined;
Ben Claytona80511e2020-12-11 13:07:02 +0000291 /// Variable type
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000292 ast::Type* type = nullptr;
Ben Claytona80511e2020-12-11 13:07:02 +0000293 };
294
Ben Clayton93e8f522021-06-04 20:41:47 +0000295 /// VariableQualifier contains the parsed information for a variable qualifier
296 struct VariableQualifier {
297 /// The variable's storage class
298 ast::StorageClass storage_class = ast::StorageClass::kNone;
299 /// The variable's access control
300 ast::Access access = ast::Access::kUndefined;
301 };
302
Ben Clayton5bee67f2020-10-30 20:44:53 +0000303 /// Creates a new parser using the given file
Ben Clayton5bee67f2020-10-30 20:44:53 +0000304 /// @param file the input source file to parse
dan sinclair685cb022020-12-02 21:17:58 +0000305 explicit ParserImpl(Source::File const* file);
Dan Sinclair6e581892020-03-02 15:47:43 -0500306 ~ParserImpl();
307
308 /// Run the parser
309 /// @returns true if the parse was successful, false otherwise.
310 bool Parse();
311
Ben Clayton1e87fe52020-11-24 15:15:36 +0000312 /// set_max_diagnostics sets the maximum number of reported errors before
313 /// aborting parsing.
314 /// @param limit the new maximum number of errors
315 void set_max_errors(size_t limit) { max_errors_ = limit; }
316
317 /// @return the number of maximum number of reported errors before aborting
318 /// parsing.
319 size_t get_max_errors() const { return max_errors_; }
320
Ben Clayton5bee67f2020-10-30 20:44:53 +0000321 /// @returns true if an error was encountered.
Ben Claytonfe2ceb92021-03-08 16:17:55 +0000322 bool has_error() const { return builder_.Diagnostics().contains_errors(); }
Ben Clayton3d54f132020-11-02 15:56:28 +0000323
Dan Sinclair6e581892020-03-02 15:47:43 -0500324 /// @returns the parser error string
Ben Clayton3d54f132020-11-02 15:56:28 +0000325 std::string error() const {
Ben Claytond2217382021-01-11 21:09:22 +0000326 diag::Formatter formatter{{false, false, false, false}};
Ben Claytonfe2ceb92021-03-08 16:17:55 +0000327 return formatter.format(builder_.Diagnostics());
Ben Clayton3d54f132020-11-02 15:56:28 +0000328 }
329
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000330 /// @returns the Program. The program builder in the parser will be reset
331 /// after this.
332 Program program() { return Program(std::move(builder_)); }
Dan Sinclair6e581892020-03-02 15:47:43 -0500333
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000334 /// @returns the program builder.
335 ProgramBuilder& builder() { return builder_; }
Ben Clayton0fb51682020-11-23 19:50:55 +0000336
Dan Sinclair6e581892020-03-02 15:47:43 -0500337 /// @returns the next token
338 Token next();
dan sinclairbf1ec302021-07-12 11:21:51 +0000339 /// Peeks ahead and returns the token at `idx` ahead of the current position
Dan Sinclair6e581892020-03-02 15:47:43 -0500340 /// @param idx the index of the token to return
Ben Claytonf8971ae2020-12-02 15:31:08 +0000341 /// @returns the token `idx` positions ahead without advancing
dan sinclairbf1ec302021-07-12 11:21:51 +0000342 Token peek(size_t idx = 0);
343 /// Peeks ahead and returns true if the token at `idx` ahead of the current
344 /// position is |tok|
345 /// @param idx the index of the token to return
346 /// @param tok the token to look for
347 /// @returns true if the token `idx` positions ahead is |tok|
348 bool peek_is(Token::Type tok, size_t idx = 0);
Antonio Maiorano4b16a162021-04-27 17:32:37 +0000349 /// @returns the last token that was returned by `next()`
350 Token last_token() const;
Ben Claytonf8971ae2020-12-02 15:31:08 +0000351 /// Appends an error at `t` with the message `msg`
Ben Clayton88cd1562020-11-04 02:23:10 +0000352 /// @param t the token to associate the error with
Dan Sinclair6e581892020-03-02 15:47:43 -0500353 /// @param msg the error message
Ben Claytonf8971ae2020-12-02 15:31:08 +0000354 /// @return `Failure::Errored::kError` so that you can combine an add_error()
355 /// call and return on the same line.
Ben Clayton653c4042020-11-09 19:39:34 +0000356 Failure::Errored add_error(const Token& t, const std::string& msg);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000357 /// Appends an error raised when parsing `use` at `t` with the message
358 /// `msg`
Ben Claytonb8df1202020-11-09 18:41:23 +0000359 /// @param source the source to associate the error with
Ben Clayton88cd1562020-11-04 02:23:10 +0000360 /// @param msg the error message
361 /// @param use a description of what was being parsed when the error was
362 /// raised.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000363 /// @return `Failure::Errored::kError` so that you can combine an add_error()
364 /// call and return on the same line.
Ben Clayton653c4042020-11-09 19:39:34 +0000365 Failure::Errored add_error(const Source& source,
366 const std::string& msg,
367 const std::string& use);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000368 /// Appends an error at `source` with the message `msg`
Ben Clayton88cd1562020-11-04 02:23:10 +0000369 /// @param source the source to associate the error with
370 /// @param msg the error message
Ben Claytonf8971ae2020-12-02 15:31:08 +0000371 /// @return `Failure::Errored::kError` so that you can combine an add_error()
372 /// call and return on the same line.
Ben Clayton653c4042020-11-09 19:39:34 +0000373 Failure::Errored add_error(const Source& source, const std::string& msg);
Ben Clayton9328d942021-04-08 14:39:47 +0000374 /// Appends a deprecated-language-feature warning at `source` with the message
375 /// `msg`
376 /// @param source the source to associate the error with
377 /// @param msg the warning message
378 void deprecated(const Source& source, const std::string& msg);
Ben Clayton950809f2021-06-09 14:32:14 +0000379 /// Registers a declared type into the parser
Ben Claytonc9ee7eb2021-05-05 16:19:22 +0000380 /// TODO(crbug.com/tint/724): Remove
Ben Clayton950809f2021-06-09 14:32:14 +0000381 /// @param name the type name
382 /// @param type_decl the type declaration
383 void register_type(const std::string& name, const ast::TypeDecl* type_decl);
384 /// Retrieves a declared type
Ben Claytonc9ee7eb2021-05-05 16:19:22 +0000385 /// TODO(crbug.com/tint/724): Remove
dan sinclair7156d3e2020-10-19 15:31:47 +0000386 /// @param name The name to lookup
Ben Clayton950809f2021-06-09 14:32:14 +0000387 /// @returns the declared type for `name` or `nullptr` if not found
388 const ast::TypeDecl* get_type(const std::string& name);
Dan Sinclair6e581892020-03-02 15:47:43 -0500389
390 /// Parses the `translation_unit` grammar element
391 void translation_unit();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000392 /// Parses the `global_decl` grammar element, erroring on parse failure.
Ben Clayton653c4042020-11-09 19:39:34 +0000393 /// @return true on parse success, otherwise an error.
394 Expect<bool> expect_global_decl();
Ben Clayton88dc2a42020-11-04 20:55:31 +0000395 /// Parses a `global_variable_decl` grammar element with the initial
Ben Claytonf8971ae2020-12-02 15:31:08 +0000396 /// `variable_decoration_list*` provided as `decos`
Dan Sinclair6e581892020-03-02 15:47:43 -0500397 /// @returns the variable parsed or nullptr
Ben Clayton88dc2a42020-11-04 20:55:31 +0000398 /// @param decos the list of decorations for the variable declaration.
Ben Claytonb053acf2020-11-16 16:31:07 +0000399 Maybe<ast::Variable*> global_variable_decl(ast::DecorationList& decos);
James Pricea6ced4d2021-02-01 14:59:13 +0000400 /// Parses a `global_constant_decl` grammar element with the initial
401 /// `variable_decoration_list*` provided as `decos`
Dan Sinclair6e581892020-03-02 15:47:43 -0500402 /// @returns the const object or nullptr
James Pricea6ced4d2021-02-01 14:59:13 +0000403 /// @param decos the list of decorations for the constant declaration.
404 Maybe<ast::Variable*> global_constant_decl(ast::DecorationList& decos);
Dan Sinclair6e581892020-03-02 15:47:43 -0500405 /// Parses a `variable_decl` grammar element
Antonio Maiorano9834fef2021-06-04 15:28:47 +0000406 /// @param allow_inferred if true, do not fail if variable decl does not
407 /// specify type
Ben Claytona80511e2020-12-11 13:07:02 +0000408 /// @returns the parsed variable declaration info
Antonio Maiorano9834fef2021-06-04 15:28:47 +0000409 Maybe<VarDeclInfo> variable_decl(bool allow_inferred = false);
Ben Claytonb8df1202020-11-09 18:41:23 +0000410 /// Parses a `variable_ident_decl` grammar element, erroring on parse
411 /// failure.
412 /// @param use a description of what was being parsed if an error was raised.
Antonio Maiorano9834fef2021-06-04 15:28:47 +0000413 /// @param allow_inferred if true, do not fail if variable decl does not
414 /// specify type
Dan Sinclair6e581892020-03-02 15:47:43 -0500415 /// @returns the identifier and type parsed or empty otherwise
Antonio Maiorano9834fef2021-06-04 15:28:47 +0000416 Expect<TypedIdentifier> expect_variable_ident_decl(
417 const std::string& use,
418 bool allow_inferred = false);
Ben Clayton93e8f522021-06-04 20:41:47 +0000419 /// Parses a `variable_qualifier` grammar element
420 /// @returns the variable qualifier information
421 Maybe<VariableQualifier> variable_qualifier();
Dan Sinclair6e581892020-03-02 15:47:43 -0500422 /// Parses a `type_alias` grammar element
423 /// @returns the type alias or nullptr on error
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000424 Maybe<ast::Alias*> type_alias();
Dan Sinclair6e581892020-03-02 15:47:43 -0500425 /// Parses a `type_decl` grammar element
Tomek Ponitkac3542002020-09-02 13:26:15 +0000426 /// @returns the parsed Type or nullptr if none matched.
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000427 Maybe<ast::Type*> type_decl();
dan sinclair7214f402020-11-19 18:55:01 +0000428 /// Parses a `type_decl` grammar element with the given pre-parsed
429 /// decorations.
430 /// @param decos the list of decorations for the type.
431 /// @returns the parsed Type or nullptr if none matched.
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000432 Maybe<ast::Type*> type_decl(ast::DecorationList& decos);
Ben Clayton653c4042020-11-09 19:39:34 +0000433 /// Parses a `storage_class` grammar element, erroring on parse failure.
434 /// @param use a description of what was being parsed if an error was raised.
Dan Sinclair6e581892020-03-02 15:47:43 -0500435 /// @returns the storage class or StorageClass::kNone if none matched
Ben Clayton653c4042020-11-09 19:39:34 +0000436 Expect<ast::StorageClass> expect_storage_class(const std::string& use);
Ben Clayton88dc2a42020-11-04 20:55:31 +0000437 /// Parses a `struct_decl` grammar element with the initial
Ben Claytonf8971ae2020-12-02 15:31:08 +0000438 /// `struct_decoration_decl*` provided as `decos`.
Dan Sinclair6e581892020-03-02 15:47:43 -0500439 /// @returns the struct type or nullptr on error
Ben Clayton88dc2a42020-11-04 20:55:31 +0000440 /// @param decos the list of decorations for the struct declaration.
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000441 Maybe<ast::Struct*> struct_decl(ast::DecorationList& decos);
Ben Clayton7b750dc2020-11-09 15:49:33 +0000442 /// Parses a `struct_body_decl` grammar element, erroring on parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500443 /// @returns the struct members
Ben Clayton653c4042020-11-09 19:39:34 +0000444 Expect<ast::StructMemberList> expect_struct_body_decl();
Ben Clayton88dc2a42020-11-04 20:55:31 +0000445 /// Parses a `struct_member` grammar element with the initial
Ben Claytonf8971ae2020-12-02 15:31:08 +0000446 /// `struct_member_decoration_decl+` provided as `decos`, erroring on parse
Ben Clayton7b750dc2020-11-09 15:49:33 +0000447 /// failure.
Ben Clayton88dc2a42020-11-04 20:55:31 +0000448 /// @param decos the list of decorations for the struct member.
Dan Sinclair6e581892020-03-02 15:47:43 -0500449 /// @returns the struct member or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000450 Expect<ast::StructMember*> expect_struct_member(ast::DecorationList& decos);
Ben Clayton88dc2a42020-11-04 20:55:31 +0000451 /// Parses a `function_decl` grammar element with the initial
Ben Claytonf8971ae2020-12-02 15:31:08 +0000452 /// `function_decoration_decl*` provided as `decos`.
Ben Clayton88dc2a42020-11-04 20:55:31 +0000453 /// @param decos the list of decorations for the function declaration.
Dan Sinclair6e581892020-03-02 15:47:43 -0500454 /// @returns the parsed function, nullptr otherwise
Ben Claytonb053acf2020-11-16 16:31:07 +0000455 Maybe<ast::Function*> function_decl(ast::DecorationList& decos);
Tomek Ponitka4beff412020-09-02 14:16:35 +0000456 /// Parses a `texture_sampler_types` grammar element
457 /// @returns the parsed Type or nullptr if none matched.
Ben Clayton7e002632021-06-16 09:19:36 +0000458 Maybe<ast::Type*> texture_sampler_types();
Tomek Ponitkac3542002020-09-02 13:26:15 +0000459 /// Parses a `sampler_type` grammar element
460 /// @returns the parsed Type or nullptr if none matched.
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000461 Maybe<ast::Type*> sampler_type();
dan sinclaird3f75ca2020-09-17 03:53:04 +0000462 /// Parses a `multisampled_texture_type` grammar element
463 /// @returns returns the multisample texture dimension or kNone if none
464 /// matched.
Ben Claytonfec63b72021-04-21 13:47:12 +0000465 Maybe<ast::TextureDimension> multisampled_texture_type();
Tomek Ponitkafd3ca9e2020-09-02 15:52:15 +0000466 /// Parses a `sampled_texture_type` grammar element
467 /// @returns returns the sample texture dimension or kNone if none matched.
Ben Claytonfec63b72021-04-21 13:47:12 +0000468 Maybe<ast::TextureDimension> sampled_texture_type();
Tomek Ponitkabcb6eb02020-09-08 16:48:09 +0000469 /// Parses a `storage_texture_type` grammar element
dan sinclair904c5b92021-01-14 08:34:46 +0000470 /// @returns returns the storage texture dimension.
471 /// Returns kNone if none matched.
Ben Claytonfec63b72021-04-21 13:47:12 +0000472 Maybe<ast::TextureDimension> storage_texture_type();
Tomek Ponitkacbd1ef82020-09-02 14:06:45 +0000473 /// Parses a `depth_texture_type` grammar element
474 /// @returns the parsed Type or nullptr if none matched.
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000475 Maybe<ast::Type*> depth_texture_type();
Brandon Jones145f8652021-04-22 22:47:03 +0000476 /// Parses a 'texture_external_type' grammar element
477 /// @returns the parsed Type or nullptr if none matched
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000478 Maybe<ast::Type*> external_texture_type();
Tomek Ponitka03f5e2f2020-09-08 16:38:39 +0000479 /// Parses a `image_storage_type` grammar element
Ben Claytonab5dfee2020-11-09 19:52:24 +0000480 /// @param use a description of what was being parsed if an error was raised
Tomek Ponitka03f5e2f2020-09-08 16:38:39 +0000481 /// @returns returns the image format or kNone if none matched.
Ben Claytonfec63b72021-04-21 13:47:12 +0000482 Expect<ast::ImageFormat> expect_image_storage_type(const std::string& use);
Dan Sinclair6e581892020-03-02 15:47:43 -0500483 /// Parses a `function_header` grammar element
Ben Clayton234b7de2020-12-07 20:45:14 +0000484 /// @returns the parsed function header
485 Maybe<FunctionHeader> function_header();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000486 /// Parses a `param_list` grammar element, erroring on parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500487 /// @returns the parsed variables
Ben Clayton653c4042020-11-09 19:39:34 +0000488 Expect<ast::VariableList> expect_param_list();
James Price5c460bf2021-03-10 23:18:29 +0000489 /// Parses a `param` grammar element, erroring on parse failure.
490 /// @returns the parsed variable
491 Expect<ast::Variable*> expect_param();
Ben Clayton32ba9b62020-11-04 20:00:31 +0000492 /// Parses a `pipeline_stage` grammar element, erroring if the next token does
493 /// not match a stage name.
Ben Clayton653c4042020-11-09 19:39:34 +0000494 /// @returns the pipeline stage.
495 Expect<ast::PipelineStage> expect_pipeline_stage();
Ben Clayton93e8f522021-06-04 20:41:47 +0000496 /// Parses an access control identifier, erroring if the next token does not
497 /// match a valid access control.
498 /// @param use a description of what was being parsed if an error was raised
dan sinclair7214f402020-11-19 18:55:01 +0000499 /// @returns the parsed access control.
Ben Clayton93e8f522021-06-04 20:41:47 +0000500 Expect<ast::Access> expect_access(const std::string& use);
Ben Claytonb8791a52020-11-04 20:06:21 +0000501 /// Parses a builtin identifier, erroring if the next token does not match a
502 /// valid builtin name.
Ben Clayton653c4042020-11-09 19:39:34 +0000503 /// @returns the parsed builtin.
504 Expect<ast::Builtin> expect_builtin();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000505 /// Parses a `body_stmt` grammar element, erroring on parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500506 /// @returns the parsed statements
Ben Claytonb053acf2020-11-16 16:31:07 +0000507 Expect<ast::BlockStatement*> expect_body_stmt();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000508 /// Parses a `paren_rhs_stmt` grammar element, erroring on parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500509 /// @returns the parsed element or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000510 Expect<ast::Expression*> expect_paren_rhs_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500511 /// Parses a `statements` grammar element
512 /// @returns the statements parsed
Ben Claytond408f242020-12-14 20:31:17 +0000513 Expect<ast::StatementList> expect_statements();
Dan Sinclair6e581892020-03-02 15:47:43 -0500514 /// Parses a `statement` grammar element
515 /// @returns the parsed statement or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000516 Maybe<ast::Statement*> statement();
dan sinclair091b2b52020-06-01 13:44:06 +0000517 /// Parses a `break_stmt` grammar element
Dan Sinclair6e581892020-03-02 15:47:43 -0500518 /// @returns the parsed statement or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000519 Maybe<ast::BreakStatement*> break_stmt();
dan sinclair091b2b52020-06-01 13:44:06 +0000520 /// Parses a `return_stmt` grammar element
521 /// @returns the parsed statement or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000522 Maybe<ast::ReturnStatement*> return_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500523 /// Parses a `continue_stmt` grammar element
524 /// @returns the parsed statement or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000525 Maybe<ast::ContinueStatement*> continue_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500526 /// Parses a `variable_stmt` grammar element
527 /// @returns the parsed variable or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000528 Maybe<ast::VariableDeclStatement*> variable_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500529 /// Parses a `if_stmt` grammar element
530 /// @returns the parsed statement or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000531 Maybe<ast::IfStatement*> if_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500532 /// Parses a `elseif_stmt` grammar element
533 /// @returns the parsed elements
Ben Claytonab5dfee2020-11-09 19:52:24 +0000534 Maybe<ast::ElseStatementList> elseif_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500535 /// Parses a `else_stmt` grammar element
536 /// @returns the parsed statement or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000537 Maybe<ast::ElseStatement*> else_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500538 /// Parses a `switch_stmt` grammar element
539 /// @returns the parsed statement or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000540 Maybe<ast::SwitchStatement*> switch_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500541 /// Parses a `switch_body` grammar element
542 /// @returns the parsed statement or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000543 Maybe<ast::CaseStatement*> switch_body();
dan sinclair1aadbd42020-06-01 16:56:46 +0000544 /// Parses a `case_selectors` grammar element
545 /// @returns the list of literals
Ben Clayton653c4042020-11-09 19:39:34 +0000546 Expect<ast::CaseSelectorList> expect_case_selectors();
Dan Sinclair6e581892020-03-02 15:47:43 -0500547 /// Parses a `case_body` grammar element
548 /// @returns the parsed statements
Ben Claytonb053acf2020-11-16 16:31:07 +0000549 Maybe<ast::BlockStatement*> case_body();
dan sinclairfbbc6172020-07-21 15:13:36 +0000550 /// Parses a `func_call_stmt` grammar element
551 /// @returns the parsed function call or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000552 Maybe<ast::CallStatement*> func_call_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500553 /// Parses a `loop_stmt` grammar element
554 /// @returns the parsed loop or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000555 Maybe<ast::LoopStatement*> loop_stmt();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000556 /// Parses a `for_header` grammar element, erroring on parse failure.
Tomek Ponitka63a5aa72020-08-24 18:22:22 +0000557 /// @returns the parsed for header or nullptr
Ben Clayton653c4042020-11-09 19:39:34 +0000558 Expect<std::unique_ptr<ForHeader>> expect_for_header();
Tomek Ponitka63a5aa72020-08-24 18:22:22 +0000559 /// Parses a `for_stmt` grammar element
560 /// @returns the parsed for loop or nullptr
Ben Clayton1b03f0a2021-07-08 21:23:33 +0000561 Maybe<ast::ForLoopStatement*> for_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500562 /// Parses a `continuing_stmt` grammar element
563 /// @returns the parsed statements
Ben Claytonb053acf2020-11-16 16:31:07 +0000564 Maybe<ast::BlockStatement*> continuing_stmt();
Dan Sinclair6e581892020-03-02 15:47:43 -0500565 /// Parses a `const_literal` grammar element
566 /// @returns the const literal parsed or nullptr if none found
Ben Claytonb053acf2020-11-16 16:31:07 +0000567 Maybe<ast::Literal*> const_literal();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000568 /// Parses a `const_expr` grammar element, erroring on parse failure.
dan sinclaira322f5d2020-03-30 22:46:06 +0000569 /// @returns the parsed constructor expression or nullptr on error
Ben Claytonb053acf2020-11-16 16:31:07 +0000570 Expect<ast::ConstructorExpression*> expect_const_expr();
Dan Sinclair6e581892020-03-02 15:47:43 -0500571 /// Parses a `primary_expression` grammar element
572 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000573 Maybe<ast::Expression*> primary_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000574 /// Parses a `argument_expression_list` grammar element, erroring on parse
575 /// failure.
James Pricee80887d2021-04-29 15:49:44 +0000576 /// @param use a description of what was being parsed if an error was raised
Dan Sinclair6e581892020-03-02 15:47:43 -0500577 /// @returns the list of arguments
James Pricee80887d2021-04-29 15:49:44 +0000578 Expect<ast::ExpressionList> expect_argument_expression_list(
579 const std::string& use);
Dan Sinclair6e581892020-03-02 15:47:43 -0500580 /// Parses the recursive portion of the postfix_expression
581 /// @param prefix the left side of the expression
582 /// @returns the parsed expression or nullptr
James Price961dc6f2021-04-29 15:02:15 +0000583 Maybe<ast::Expression*> postfix_expression(ast::Expression* prefix);
584 /// Parses a `singular_expression` grammar elment
Dan Sinclair6e581892020-03-02 15:47:43 -0500585 /// @returns the parsed expression or nullptr
James Price961dc6f2021-04-29 15:02:15 +0000586 Maybe<ast::Expression*> singular_expression();
Dan Sinclair6e581892020-03-02 15:47:43 -0500587 /// Parses a `unary_expression` grammar element
588 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000589 Maybe<ast::Expression*> unary_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000590 /// Parses the recursive part of the `multiplicative_expression`, erroring on
591 /// parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500592 /// @param lhs the left side of the expression
593 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000594 Expect<ast::Expression*> expect_multiplicative_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500595 /// Parses the `multiplicative_expression` grammar element
596 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000597 Maybe<ast::Expression*> multiplicative_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000598 /// Parses the recursive part of the `additive_expression`, erroring on parse
599 /// failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500600 /// @param lhs the left side of the expression
601 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000602 Expect<ast::Expression*> expect_additive_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500603 /// Parses the `additive_expression` grammar element
604 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000605 Maybe<ast::Expression*> additive_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000606 /// Parses the recursive part of the `shift_expression`, erroring on parse
607 /// failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500608 /// @param lhs the left side of the expression
609 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000610 Expect<ast::Expression*> expect_shift_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500611 /// Parses the `shift_expression` grammar element
612 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000613 Maybe<ast::Expression*> shift_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000614 /// Parses the recursive part of the `relational_expression`, erroring on
615 /// parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500616 /// @param lhs the left side of the expression
617 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000618 Expect<ast::Expression*> expect_relational_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500619 /// Parses the `relational_expression` grammar element
620 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000621 Maybe<ast::Expression*> relational_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000622 /// Parses the recursive part of the `equality_expression`, erroring on parse
623 /// failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500624 /// @param lhs the left side of the expression
625 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000626 Expect<ast::Expression*> expect_equality_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500627 /// Parses the `equality_expression` grammar element
628 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000629 Maybe<ast::Expression*> equality_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000630 /// Parses the recursive part of the `and_expression`, erroring on parse
631 /// failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500632 /// @param lhs the left side of the expression
633 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000634 Expect<ast::Expression*> expect_and_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500635 /// Parses the `and_expression` grammar element
636 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000637 Maybe<ast::Expression*> and_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000638 /// Parses the recursive part of the `exclusive_or_expression`, erroring on
639 /// parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500640 /// @param lhs the left side of the expression
641 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000642 Expect<ast::Expression*> expect_exclusive_or_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500643 /// Parses the `exclusive_or_expression` grammar elememnt
644 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000645 Maybe<ast::Expression*> exclusive_or_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000646 /// Parses the recursive part of the `inclusive_or_expression`, erroring on
647 /// parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500648 /// @param lhs the left side of the expression
649 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000650 Expect<ast::Expression*> expect_inclusive_or_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500651 /// Parses the `inclusive_or_expression` grammar element
652 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000653 Maybe<ast::Expression*> inclusive_or_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000654 /// Parses the recursive part of the `logical_and_expression`, erroring on
655 /// parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500656 /// @param lhs the left side of the expression
657 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000658 Expect<ast::Expression*> expect_logical_and_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500659 /// Parses a `logical_and_expression` grammar element
660 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000661 Maybe<ast::Expression*> logical_and_expression();
Ben Clayton7b750dc2020-11-09 15:49:33 +0000662 /// Parses the recursive part of the `logical_or_expression`, erroring on
663 /// parse failure.
Dan Sinclair6e581892020-03-02 15:47:43 -0500664 /// @param lhs the left side of the expression
665 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000666 Expect<ast::Expression*> expect_logical_or_expr(ast::Expression* lhs);
Dan Sinclair6e581892020-03-02 15:47:43 -0500667 /// Parses a `logical_or_expression` grammar element
668 /// @returns the parsed expression or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000669 Maybe<ast::Expression*> logical_or_expression();
Dan Sinclair6e581892020-03-02 15:47:43 -0500670 /// Parses a `assignment_stmt` grammar element
671 /// @returns the parsed assignment or nullptr
Ben Claytonb053acf2020-11-16 16:31:07 +0000672 Maybe<ast::AssignmentStatement*> assignment_stmt();
Ben Clayton88dc2a42020-11-04 20:55:31 +0000673 /// Parses one or more bracketed decoration lists.
674 /// @return the parsed decoration list, or an empty list on error.
Ben Claytonab5dfee2020-11-09 19:52:24 +0000675 Maybe<ast::DecorationList> decoration_list();
Ben Clayton88dc2a42020-11-04 20:55:31 +0000676 /// Parses a list of decorations between `ATTR_LEFT` and `ATTR_RIGHT`
677 /// brackets.
678 /// @param decos the list to append newly parsed decorations to.
679 /// @return true if any decorations were be parsed, otherwise false.
Ben Claytonab5dfee2020-11-09 19:52:24 +0000680 Maybe<bool> decoration_bracketed_list(ast::DecorationList& decos);
Ben Clayton88dc2a42020-11-04 20:55:31 +0000681 /// Parses a single decoration of the following types:
682 /// * `struct_decoration`
683 /// * `struct_member_decoration`
684 /// * `array_decoration`
685 /// * `variable_decoration`
686 /// * `global_const_decoration`
687 /// * `function_decoration`
688 /// @return the parsed decoration, or nullptr.
Ben Claytonb053acf2020-11-16 16:31:07 +0000689 Maybe<ast::Decoration*> decoration();
Ben Clayton88dc2a42020-11-04 20:55:31 +0000690 /// Parses a single decoration, reporting an error if the next token does not
691 /// represent a decoration.
692 /// @see #decoration for the full list of decorations this method parses.
693 /// @return the parsed decoration, or nullptr on error.
Ben Claytonb053acf2020-11-16 16:31:07 +0000694 Expect<ast::Decoration*> expect_decoration();
Dan Sinclair6e581892020-03-02 15:47:43 -0500695
696 private:
Ben Clayton653c4042020-11-09 19:39:34 +0000697 /// ReturnType resolves to the return type for the function or lambda F.
Ben Clayton786bc922020-11-04 20:08:51 +0000698 template <typename F>
Ben Clayton653c4042020-11-09 19:39:34 +0000699 using ReturnType = typename std::result_of<F()>::type;
700
Ben Claytonf8971ae2020-12-02 15:31:08 +0000701 /// ResultType resolves to `T` for a `RESULT` of type Expect<T>.
Ben Clayton653c4042020-11-09 19:39:34 +0000702 template <typename RESULT>
703 using ResultType = typename RESULT::type;
Ben Clayton786bc922020-11-04 20:08:51 +0000704
Ben Claytonf8971ae2020-12-02 15:31:08 +0000705 /// @returns true and consumes the next token if it equals `tok`
Ben Clayton4ce7a932020-11-04 18:39:41 +0000706 /// @param source if not nullptr, the next token's source is written to this
707 /// pointer, regardless of success or error
708 bool match(Token::Type tok, Source* source = nullptr);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000709 /// Errors if the next token is not equal to `tok`
Ben Claytonaf8091e2020-11-11 18:44:36 +0000710 /// Consumes the next token on match.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000711 /// expect() also updates #synchronized_, setting it to `true` if the next
712 /// token is equal to `tok`, otherwise `false`.
Ben Claytond70f2512020-11-04 14:14:40 +0000713 /// @param use a description of what was being parsed if an error was raised.
714 /// @param tok the token to test against
Ben Claytonf8971ae2020-12-02 15:31:08 +0000715 /// @returns true if the next token equals `tok`
Ben Claytond70f2512020-11-04 14:14:40 +0000716 bool expect(const std::string& use, Token::Type tok);
717 /// Parses a signed integer from the next token in the stream, erroring if the
718 /// next token is not a signed integer.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000719 /// Consumes the next token on match.
Ben Claytond70f2512020-11-04 14:14:40 +0000720 /// @param use a description of what was being parsed if an error was raised
Ben Clayton653c4042020-11-09 19:39:34 +0000721 /// @returns the parsed integer.
722 Expect<int32_t> expect_sint(const std::string& use);
Ben Claytond70f2512020-11-04 14:14:40 +0000723 /// Parses a signed integer from the next token in the stream, erroring if
724 /// the next token is not a signed integer or is negative.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000725 /// Consumes the next token if it is a signed integer (not necessarily
726 /// negative).
Ben Claytond70f2512020-11-04 14:14:40 +0000727 /// @param use a description of what was being parsed if an error was raised
Ben Clayton653c4042020-11-09 19:39:34 +0000728 /// @returns the parsed integer.
729 Expect<uint32_t> expect_positive_sint(const std::string& use);
Ben Claytond70f2512020-11-04 14:14:40 +0000730 /// Parses a non-zero signed integer from the next token in the stream,
731 /// erroring if the next token is not a signed integer or is less than 1.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000732 /// Consumes the next token if it is a signed integer (not necessarily
733 /// >= 1).
Ben Claytond70f2512020-11-04 14:14:40 +0000734 /// @param use a description of what was being parsed if an error was raised
Ben Clayton653c4042020-11-09 19:39:34 +0000735 /// @returns the parsed integer.
736 Expect<uint32_t> expect_nonzero_positive_sint(const std::string& use);
Ben Claytond70f2512020-11-04 14:14:40 +0000737 /// Errors if the next token is not an identifier.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000738 /// Consumes the next token on match.
Ben Claytond70f2512020-11-04 14:14:40 +0000739 /// @param use a description of what was being parsed if an error was raised
Ben Clayton653c4042020-11-09 19:39:34 +0000740 /// @returns the parsed identifier.
741 Expect<std::string> expect_ident(const std::string& use);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000742 /// Parses a lexical block starting with the token `start` and ending with
743 /// the token `end`. `body` is called to parse the lexical block body
744 /// between the `start` and `end` tokens. If the `start` or `end` tokens
745 /// are not matched then an error is generated and a zero-initialized `T` is
746 /// returned. If `body` raises an error while parsing then a zero-initialized
747 /// `T` is returned.
Ben Clayton786bc922020-11-04 20:08:51 +0000748 /// @param start the token that begins the lexical block
749 /// @param end the token that ends the lexical block
750 /// @param use a description of what was being parsed if an error was raised
751 /// @param body a function or lambda that is called to parse the lexical block
Ben Clayton00bc8ba2020-11-11 14:10:25 +0000752 /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000753 /// @return the value returned by `body` if no errors are raised, otherwise
Ben Claytonab5dfee2020-11-09 19:52:24 +0000754 /// an Expect with error state.
Ben Clayton653c4042020-11-09 19:39:34 +0000755 template <typename F, typename T = ReturnType<F>>
Ben Clayton786bc922020-11-04 20:08:51 +0000756 T expect_block(Token::Type start,
757 Token::Type end,
758 const std::string& use,
759 F&& body);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000760 /// A convenience function that calls expect_block() passing
761 /// `Token::Type::kParenLeft` and `Token::Type::kParenRight` for the `start`
762 /// and `end` arguments, respectively.
Ben Clayton786bc922020-11-04 20:08:51 +0000763 /// @param use a description of what was being parsed if an error was raised
764 /// @param body a function or lambda that is called to parse the lexical block
Ben Clayton00bc8ba2020-11-11 14:10:25 +0000765 /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000766 /// @return the value returned by `body` if no errors are raised, otherwise
Ben Claytonab5dfee2020-11-09 19:52:24 +0000767 /// an Expect with error state.
Ben Clayton653c4042020-11-09 19:39:34 +0000768 template <typename F, typename T = ReturnType<F>>
Ben Clayton786bc922020-11-04 20:08:51 +0000769 T expect_paren_block(const std::string& use, F&& body);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000770 /// A convenience function that calls `expect_block` passing
771 /// `Token::Type::kBraceLeft` and `Token::Type::kBraceRight` for the `start`
772 /// and `end` arguments, respectively.
Ben Clayton786bc922020-11-04 20:08:51 +0000773 /// @param use a description of what was being parsed if an error was raised
774 /// @param body a function or lambda that is called to parse the lexical block
Ben Clayton00bc8ba2020-11-11 14:10:25 +0000775 /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000776 /// @return the value returned by `body` if no errors are raised, otherwise
Ben Claytonab5dfee2020-11-09 19:52:24 +0000777 /// an Expect with error state.
Ben Clayton653c4042020-11-09 19:39:34 +0000778 template <typename F, typename T = ReturnType<F>>
Ben Clayton786bc922020-11-04 20:08:51 +0000779 T expect_brace_block(const std::string& use, F&& body);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000780 /// A convenience function that calls `expect_block` passing
781 /// `Token::Type::kLessThan` and `Token::Type::kGreaterThan` for the `start`
782 /// and `end` arguments, respectively.
Ben Clayton00bc8ba2020-11-11 14:10:25 +0000783 /// @param use a description of what was being parsed if an error was raised
784 /// @param body a function or lambda that is called to parse the lexical block
785 /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000786 /// @return the value returned by `body` if no errors are raised, otherwise
Ben Clayton00bc8ba2020-11-11 14:10:25 +0000787 /// an Expect with error state.
788 template <typename F, typename T = ReturnType<F>>
789 T expect_lt_gt_block(const std::string& use, F&& body);
Ben Clayton653c4042020-11-09 19:39:34 +0000790
Ben Claytonf8971ae2020-12-02 15:31:08 +0000791 /// sync() calls the function `func`, and attempts to resynchronize the
792 /// parser to the next found resynchronization token if `func` fails. If the
793 /// next found resynchronization token is `tok`, then sync will also consume
794 /// `tok`.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000795 ///
Ben Claytonf8971ae2020-12-02 15:31:08 +0000796 /// sync() will transiently add `tok` to the parser's stack of
797 /// synchronization tokens for the duration of the call to `func`. Once @p
798 /// func returns,
799 /// `tok` is removed from the stack of resynchronization tokens. sync calls
800 /// may be nested, and so the number of resynchronization tokens is equal to
801 /// the number of sync() calls in the current stack frame.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000802 ///
Ben Claytonf8971ae2020-12-02 15:31:08 +0000803 /// sync() updates #synchronized_, setting it to `true` if the next
804 /// resynchronization token found was `tok`, otherwise `false`.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000805 ///
Ben Claytonf8971ae2020-12-02 15:31:08 +0000806 /// @param tok the token to attempt to synchronize the parser to if `func`
Ben Claytonaf8091e2020-11-11 18:44:36 +0000807 /// fails.
808 /// @param func a function or lambda with the signature: `Expect<Result>()` or
809 /// `Maybe<Result>()`.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000810 /// @return the value returned by `func`
Ben Claytonaf8091e2020-11-11 18:44:36 +0000811 template <typename F, typename T = ReturnType<F>>
812 T sync(Token::Type tok, F&& func);
813 /// sync_to() attempts to resynchronize the parser to the next found
Ben Claytonf8971ae2020-12-02 15:31:08 +0000814 /// resynchronization token or `tok` (whichever comes first).
Ben Claytonaf8091e2020-11-11 18:44:36 +0000815 ///
Ben Claytonf8971ae2020-12-02 15:31:08 +0000816 /// Synchronization tokens are transiently defined by calls to sync().
Ben Claytonaf8091e2020-11-11 18:44:36 +0000817 ///
Ben Claytonf8971ae2020-12-02 15:31:08 +0000818 /// sync_to() updates #synchronized_, setting it to `true` if a
819 /// resynchronization token was found and it was `tok`, otherwise `false`.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000820 ///
821 /// @param tok the token to attempt to synchronize the parser to.
822 /// @param consume if true and the next found resynchronization token is
Ben Claytonf8971ae2020-12-02 15:31:08 +0000823 /// `tok` then sync_to() will also consume `tok`.
824 /// @return the state of #synchronized_.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000825 /// @see sync().
826 bool sync_to(Token::Type tok, bool consume);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000827 /// @return true if `t` is in the stack of resynchronization tokens.
Ben Claytonaf8091e2020-11-11 18:44:36 +0000828 /// @see sync().
829 bool is_sync_token(const Token& t) const;
830
Ben Clayton3797ab62021-07-12 16:50:31 +0000831 /// @returns true if #synchronized_ is true and the number of reported errors
832 /// is less than #max_errors_.
833 bool continue_parsing() {
834 return synchronized_ && builder_.Diagnostics().error_count() < max_errors_;
835 }
Ben Claytonc41c7cd2021-06-28 16:09:57 +0000836
Ben Claytonf8971ae2020-12-02 15:31:08 +0000837 /// without_error() calls the function `func` muting any grammatical errors
Ben Claytonaa5f23e2020-11-19 14:19:31 +0000838 /// found while executing the function. This can be used as a best-effort to
839 /// produce a meaningful error message when the parser is out of sync.
840 /// @param func a function or lambda with the signature: `Expect<Result>()` or
841 /// `Maybe<Result>()`.
Ben Claytonf8971ae2020-12-02 15:31:08 +0000842 /// @return the value returned by `func`
Ben Claytonaa5f23e2020-11-19 14:19:31 +0000843 template <typename F, typename T = ReturnType<F>>
844 T without_error(F&& func);
845
Ben Claytonf8971ae2020-12-02 15:31:08 +0000846 /// Reports an error if the decoration list `list` is not empty.
Ben Clayton88dc2a42020-11-04 20:55:31 +0000847 /// Used to ensure that all decorations are consumed.
848 bool expect_decorations_consumed(const ast::DecorationList& list);
Ben Claytond70f2512020-11-04 14:14:40 +0000849
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000850 Expect<ast::Type*> expect_type_decl_pointer(Token t);
Ben Clayton989c3a12021-06-17 15:48:39 +0000851 Expect<ast::Type*> expect_type_decl_atomic(Token t);
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000852 Expect<ast::Type*> expect_type_decl_vector(Token t);
853 Expect<ast::Type*> expect_type_decl_array(Token t, ast::DecorationList decos);
854 Expect<ast::Type*> expect_type_decl_matrix(Token t);
Dan Sinclair6e581892020-03-02 15:47:43 -0500855
Ben Claytonb7bd0e12021-05-06 15:57:13 +0000856 Expect<ast::Type*> expect_type(const std::string& use);
Ben Clayton00bc8ba2020-11-11 14:10:25 +0000857
Ben Claytonb053acf2020-11-16 16:31:07 +0000858 Maybe<ast::Statement*> non_block_statement();
859 Maybe<ast::Statement*> for_header_initializer();
860 Maybe<ast::Statement*> for_header_continuing();
Ben Claytonab5dfee2020-11-09 19:52:24 +0000861
Antonio Maiorano4b16a162021-04-27 17:32:37 +0000862 class MultiTokenSource;
863 MultiTokenSource make_source_range();
864 MultiTokenSource make_source_range_from(const Source& start);
865
Ben Clayton2f4096b2020-11-18 20:58:20 +0000866 /// Creates a new `ast::Node` owned by the Module. When the Module is
Ben Claytonb053acf2020-11-16 16:31:07 +0000867 /// destructed, the `ast::Node` will also be destructed.
868 /// @param args the arguments to pass to the type constructor
869 /// @returns the node pointer
Ben Claytonf65799e2020-11-16 16:11:19 +0000870 template <typename T, typename... ARGS>
Ben Claytonb053acf2020-11-16 16:31:07 +0000871 T* create(ARGS&&... args) {
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000872 return builder_.create<T>(std::forward<ARGS>(args)...);
Ben Claytonf65799e2020-11-16 16:11:19 +0000873 }
874
Dan Sinclair6e581892020-03-02 15:47:43 -0500875 std::unique_ptr<Lexer> lexer_;
876 std::deque<Token> token_queue_;
Antonio Maiorano4b16a162021-04-27 17:32:37 +0000877 Token last_token_;
Ben Claytonaf8091e2020-11-11 18:44:36 +0000878 bool synchronized_ = true;
Ben Claytone7257eb2021-06-21 19:36:26 +0000879 uint32_t parse_depth_ = 0;
Ben Claytonaf8091e2020-11-11 18:44:36 +0000880 std::vector<Token::Type> sync_tokens_;
Ben Claytonaa5f23e2020-11-19 14:19:31 +0000881 int silence_errors_ = 0;
Ben Clayton950809f2021-06-09 14:32:14 +0000882 std::unordered_map<std::string, const ast::TypeDecl*> registered_types_;
Ben Claytona6b9a8e2021-01-26 16:57:10 +0000883 ProgramBuilder builder_;
Ben Clayton1e87fe52020-11-24 15:15:36 +0000884 size_t max_errors_ = 25;
Dan Sinclair6e581892020-03-02 15:47:43 -0500885};
886
887} // namespace wgsl
888} // namespace reader
889} // namespace tint
890
891#endif // SRC_READER_WGSL_PARSER_IMPL_H_