Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 1 | // 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 Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 23 | #include <vector> |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 24 | |
Ben Clayton | 93e8f52 | 2021-06-04 20:41:47 +0000 | [diff] [blame] | 25 | #include "src/ast/access.h" |
Ben Clayton | a6b9a8e | 2021-01-26 16:57:10 +0000 | [diff] [blame] | 26 | #include "src/program_builder.h" |
Ben Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 27 | #include "src/reader/wgsl/parser_impl_detail.h" |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 28 | #include "src/reader/wgsl/token.h" |
Antonio Maiorano | aea9c68 | 2021-04-19 22:54:43 +0000 | [diff] [blame] | 29 | #include "src/sem/storage_texture_type.h" |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 30 | |
| 31 | namespace tint { |
Antonio Maiorano | 73fdc16 | 2021-04-26 14:19:55 +0000 | [diff] [blame] | 32 | namespace ast { |
| 33 | class AssignmentStatement; |
| 34 | class BreakStatement; |
| 35 | class CallStatement; |
| 36 | class ContinueStatement; |
| 37 | class IfStatement; |
| 38 | class LoopStatement; |
| 39 | class ReturnStatement; |
| 40 | class SwitchStatement; |
| 41 | class VariableDeclStatement; |
| 42 | } // namespace ast |
| 43 | |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 44 | namespace reader { |
| 45 | namespace wgsl { |
| 46 | |
| 47 | class Lexer; |
| 48 | |
dan sinclair | 8d72a2b | 2020-08-26 20:38:46 +0000 | [diff] [blame] | 49 | /// Struct holding information for a for loop |
Tomek Ponitka | 63a5aa7 | 2020-08-24 18:22:22 +0000 | [diff] [blame] | 50 | struct ForHeader { |
dan sinclair | 8d72a2b | 2020-08-26 20:38:46 +0000 | [diff] [blame] | 51 | /// Constructor |
| 52 | /// @param init the initializer statement |
| 53 | /// @param cond the condition statement |
| 54 | /// @param cont the continuing statement |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 55 | ForHeader(ast::Statement* init, ast::Expression* cond, ast::Statement* cont); |
Tomek Ponitka | 63a5aa7 | 2020-08-24 18:22:22 +0000 | [diff] [blame] | 56 | |
| 57 | ~ForHeader(); |
dan sinclair | 8d72a2b | 2020-08-26 20:38:46 +0000 | [diff] [blame] | 58 | |
| 59 | /// The for loop initializer |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 60 | ast::Statement* initializer = nullptr; |
dan sinclair | 8d72a2b | 2020-08-26 20:38:46 +0000 | [diff] [blame] | 61 | /// The for loop condition |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 62 | ast::Expression* condition = nullptr; |
dan sinclair | 8d72a2b | 2020-08-26 20:38:46 +0000 | [diff] [blame] | 63 | /// The for loop continuing statement |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 64 | ast::Statement* continuing = nullptr; |
Tomek Ponitka | 63a5aa7 | 2020-08-24 18:22:22 +0000 | [diff] [blame] | 65 | }; |
| 66 | |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 67 | /// ParserImpl for WGSL source data |
| 68 | class ParserImpl { |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 69 | /// Failure holds enumerator values used for the constructing an Expect and |
| 70 | /// Match in an errored state. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 71 | struct Failure { |
| 72 | enum Errored { kErrored }; |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 73 | enum NoMatch { kNoMatch }; |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 74 | }; |
| 75 | |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 76 | public: |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 77 | /// 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 Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 80 | /// add_error() and #errored will be set to true. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 81 | 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 Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 110 | /// @return a pointer to the returned value. If T is a pointer or |
| 111 | /// std::unique_ptr, operator->() automatically dereferences so that the |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 112 | /// return type will always be a pointer to a non-pointer type. #errored |
Ben Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 113 | /// must be false to call. |
| 114 | inline typename detail::OperatorArrow<T>::type operator->() { |
Ben Clayton | ffd28e2 | 2021-06-24 11:27:36 +0000 | [diff] [blame] | 115 | TINT_ASSERT(Reader, !errored); |
Ben Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 116 | return detail::OperatorArrow<T>::ptr(value); |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 117 | } |
| 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 Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 128 | /// 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 Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 131 | /// In the case of a successful grammar match, the Maybe will have #matched |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 132 | /// set to true. |
| 133 | /// In the case of a parse error the called method will have called |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 134 | /// add_error() and the Maybe will have #errored set to true. |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 135 | 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 Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 153 | /// @param e the Expect to copy this Maybe from |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 154 | 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 Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 162 | /// @param e the Expect to move this Maybe from |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 163 | 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 Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 181 | /// @return a pointer to the returned value. If T is a pointer or |
| 182 | /// std::unique_ptr, operator->() automatically dereferences so that the |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 183 | /// return type will always be a pointer to a non-pointer type. #errored |
Ben Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 184 | /// must be false to call. |
| 185 | inline typename detail::OperatorArrow<T>::type operator->() { |
Ben Clayton | ffd28e2 | 2021-06-24 11:27:36 +0000 | [diff] [blame] | 186 | TINT_ASSERT(Reader, !errored); |
Ben Clayton | 0573714 | 2020-11-09 20:44:34 +0000 | [diff] [blame] | 187 | return detail::OperatorArrow<T>::ptr(value); |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 188 | } |
| 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 Clayton | 580d6c7 | 2020-11-02 15:25:18 +0000 | [diff] [blame] | 201 | /// TypedIdentifier holds a parsed identifier and type. Returned by |
| 202 | /// variable_ident_decl(). |
| 203 | struct TypedIdentifier { |
Antonio Maiorano | 05abdf5 | 2021-04-23 08:19:33 +0000 | [diff] [blame] | 204 | /// 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 Clayton | 7e00263 | 2021-06-16 09:19:36 +0000 | [diff] [blame] | 213 | TypedIdentifier(ast::Type* type_in, std::string name_in, Source source_in); |
Antonio Maiorano | 05abdf5 | 2021-04-23 08:19:33 +0000 | [diff] [blame] | 214 | /// Destructor |
| 215 | ~TypedIdentifier(); |
| 216 | |
Antonio Maiorano | 9834fef | 2021-06-04 15:28:47 +0000 | [diff] [blame] | 217 | /// Parsed type. May be nullptr for inferred types. |
| 218 | ast::Type* type = nullptr; |
Ben Clayton | 2d89d98 | 2020-11-02 18:02:18 +0000 | [diff] [blame] | 219 | /// Parsed identifier. |
| 220 | std::string name; |
| 221 | /// Source to the identifier. |
| 222 | Source source; |
Ben Clayton | 580d6c7 | 2020-11-02 15:25:18 +0000 | [diff] [blame] | 223 | }; |
| 224 | |
Ben Clayton | 234b7de | 2020-12-07 20:45:14 +0000 | [diff] [blame] | 225 | /// 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 Price | feecbe0 | 2021-03-15 17:01:34 +0000 | [diff] [blame] | 237 | /// @param ret_decos return type decorations |
Ben Clayton | 234b7de | 2020-12-07 20:45:14 +0000 | [diff] [blame] | 238 | FunctionHeader(Source src, |
| 239 | std::string n, |
| 240 | ast::VariableList p, |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 241 | ast::Type* ret_ty, |
James Price | feecbe0 | 2021-03-15 17:01:34 +0000 | [diff] [blame] | 242 | ast::DecorationList ret_decos); |
Ben Clayton | 234b7de | 2020-12-07 20:45:14 +0000 | [diff] [blame] | 243 | /// 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 Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 257 | ast::Type* return_type; |
James Price | feecbe0 | 2021-03-15 17:01:34 +0000 | [diff] [blame] | 258 | /// Function return type decorations |
| 259 | ast::DecorationList return_type_decorations; |
Ben Clayton | 234b7de | 2020-12-07 20:45:14 +0000 | [diff] [blame] | 260 | }; |
| 261 | |
Ben Clayton | a80511e | 2020-12-11 13:07:02 +0000 | [diff] [blame] | 262 | /// VarDeclInfo contains the parsed information for variable declaration. |
| 263 | struct VarDeclInfo { |
Antonio Maiorano | 73fdc16 | 2021-04-26 14:19:55 +0000 | [diff] [blame] | 264 | /// 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 Clayton | 93e8f52 | 2021-06-04 20:41:47 +0000 | [diff] [blame] | 273 | /// @param access_in variable access control |
Antonio Maiorano | 73fdc16 | 2021-04-26 14:19:55 +0000 | [diff] [blame] | 274 | /// @param type_in variable type |
| 275 | VarDeclInfo(Source source_in, |
| 276 | std::string name_in, |
| 277 | ast::StorageClass storage_class_in, |
Ben Clayton | 93e8f52 | 2021-06-04 20:41:47 +0000 | [diff] [blame] | 278 | ast::Access access_in, |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 279 | ast::Type* type_in); |
Antonio Maiorano | 73fdc16 | 2021-04-26 14:19:55 +0000 | [diff] [blame] | 280 | /// Destructor |
| 281 | ~VarDeclInfo(); |
| 282 | |
Ben Clayton | a80511e | 2020-12-11 13:07:02 +0000 | [diff] [blame] | 283 | /// Variable declaration source |
| 284 | Source source; |
| 285 | /// Variable name |
| 286 | std::string name; |
| 287 | /// Variable storage class |
Ben Clayton | 93e8f52 | 2021-06-04 20:41:47 +0000 | [diff] [blame] | 288 | ast::StorageClass storage_class = ast::StorageClass::kNone; |
| 289 | /// Variable access control |
| 290 | ast::Access access = ast::Access::kUndefined; |
Ben Clayton | a80511e | 2020-12-11 13:07:02 +0000 | [diff] [blame] | 291 | /// Variable type |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 292 | ast::Type* type = nullptr; |
Ben Clayton | a80511e | 2020-12-11 13:07:02 +0000 | [diff] [blame] | 293 | }; |
| 294 | |
Ben Clayton | 93e8f52 | 2021-06-04 20:41:47 +0000 | [diff] [blame] | 295 | /// 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 Clayton | 5bee67f | 2020-10-30 20:44:53 +0000 | [diff] [blame] | 303 | /// Creates a new parser using the given file |
Ben Clayton | 5bee67f | 2020-10-30 20:44:53 +0000 | [diff] [blame] | 304 | /// @param file the input source file to parse |
dan sinclair | 685cb02 | 2020-12-02 21:17:58 +0000 | [diff] [blame] | 305 | explicit ParserImpl(Source::File const* file); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 306 | ~ParserImpl(); |
| 307 | |
| 308 | /// Run the parser |
| 309 | /// @returns true if the parse was successful, false otherwise. |
| 310 | bool Parse(); |
| 311 | |
Ben Clayton | 1e87fe5 | 2020-11-24 15:15:36 +0000 | [diff] [blame] | 312 | /// 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 Clayton | 5bee67f | 2020-10-30 20:44:53 +0000 | [diff] [blame] | 321 | /// @returns true if an error was encountered. |
Ben Clayton | fe2ceb9 | 2021-03-08 16:17:55 +0000 | [diff] [blame] | 322 | bool has_error() const { return builder_.Diagnostics().contains_errors(); } |
Ben Clayton | 3d54f13 | 2020-11-02 15:56:28 +0000 | [diff] [blame] | 323 | |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 324 | /// @returns the parser error string |
Ben Clayton | 3d54f13 | 2020-11-02 15:56:28 +0000 | [diff] [blame] | 325 | std::string error() const { |
Ben Clayton | d221738 | 2021-01-11 21:09:22 +0000 | [diff] [blame] | 326 | diag::Formatter formatter{{false, false, false, false}}; |
Ben Clayton | fe2ceb9 | 2021-03-08 16:17:55 +0000 | [diff] [blame] | 327 | return formatter.format(builder_.Diagnostics()); |
Ben Clayton | 3d54f13 | 2020-11-02 15:56:28 +0000 | [diff] [blame] | 328 | } |
| 329 | |
Ben Clayton | a6b9a8e | 2021-01-26 16:57:10 +0000 | [diff] [blame] | 330 | /// @returns the Program. The program builder in the parser will be reset |
| 331 | /// after this. |
| 332 | Program program() { return Program(std::move(builder_)); } |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 333 | |
Ben Clayton | a6b9a8e | 2021-01-26 16:57:10 +0000 | [diff] [blame] | 334 | /// @returns the program builder. |
| 335 | ProgramBuilder& builder() { return builder_; } |
Ben Clayton | 0fb5168 | 2020-11-23 19:50:55 +0000 | [diff] [blame] | 336 | |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 337 | /// @returns the next token |
| 338 | Token next(); |
dan sinclair | bf1ec30 | 2021-07-12 11:21:51 +0000 | [diff] [blame] | 339 | /// Peeks ahead and returns the token at `idx` ahead of the current position |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 340 | /// @param idx the index of the token to return |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 341 | /// @returns the token `idx` positions ahead without advancing |
dan sinclair | bf1ec30 | 2021-07-12 11:21:51 +0000 | [diff] [blame] | 342 | 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 Maiorano | 4b16a16 | 2021-04-27 17:32:37 +0000 | [diff] [blame] | 349 | /// @returns the last token that was returned by `next()` |
| 350 | Token last_token() const; |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 351 | /// Appends an error at `t` with the message `msg` |
Ben Clayton | 88cd156 | 2020-11-04 02:23:10 +0000 | [diff] [blame] | 352 | /// @param t the token to associate the error with |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 353 | /// @param msg the error message |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 354 | /// @return `Failure::Errored::kError` so that you can combine an add_error() |
| 355 | /// call and return on the same line. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 356 | Failure::Errored add_error(const Token& t, const std::string& msg); |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 357 | /// Appends an error raised when parsing `use` at `t` with the message |
| 358 | /// `msg` |
Ben Clayton | b8df120 | 2020-11-09 18:41:23 +0000 | [diff] [blame] | 359 | /// @param source the source to associate the error with |
Ben Clayton | 88cd156 | 2020-11-04 02:23:10 +0000 | [diff] [blame] | 360 | /// @param msg the error message |
| 361 | /// @param use a description of what was being parsed when the error was |
| 362 | /// raised. |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 363 | /// @return `Failure::Errored::kError` so that you can combine an add_error() |
| 364 | /// call and return on the same line. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 365 | Failure::Errored add_error(const Source& source, |
| 366 | const std::string& msg, |
| 367 | const std::string& use); |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 368 | /// Appends an error at `source` with the message `msg` |
Ben Clayton | 88cd156 | 2020-11-04 02:23:10 +0000 | [diff] [blame] | 369 | /// @param source the source to associate the error with |
| 370 | /// @param msg the error message |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 371 | /// @return `Failure::Errored::kError` so that you can combine an add_error() |
| 372 | /// call and return on the same line. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 373 | Failure::Errored add_error(const Source& source, const std::string& msg); |
Ben Clayton | 9328d94 | 2021-04-08 14:39:47 +0000 | [diff] [blame] | 374 | /// 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 Clayton | 950809f | 2021-06-09 14:32:14 +0000 | [diff] [blame] | 379 | /// Registers a declared type into the parser |
Ben Clayton | c9ee7eb | 2021-05-05 16:19:22 +0000 | [diff] [blame] | 380 | /// TODO(crbug.com/tint/724): Remove |
Ben Clayton | 950809f | 2021-06-09 14:32:14 +0000 | [diff] [blame] | 381 | /// @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 Clayton | c9ee7eb | 2021-05-05 16:19:22 +0000 | [diff] [blame] | 385 | /// TODO(crbug.com/tint/724): Remove |
dan sinclair | 7156d3e | 2020-10-19 15:31:47 +0000 | [diff] [blame] | 386 | /// @param name The name to lookup |
Ben Clayton | 950809f | 2021-06-09 14:32:14 +0000 | [diff] [blame] | 387 | /// @returns the declared type for `name` or `nullptr` if not found |
| 388 | const ast::TypeDecl* get_type(const std::string& name); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 389 | |
| 390 | /// Parses the `translation_unit` grammar element |
| 391 | void translation_unit(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 392 | /// Parses the `global_decl` grammar element, erroring on parse failure. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 393 | /// @return true on parse success, otherwise an error. |
| 394 | Expect<bool> expect_global_decl(); |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 395 | /// Parses a `global_variable_decl` grammar element with the initial |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 396 | /// `variable_decoration_list*` provided as `decos` |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 397 | /// @returns the variable parsed or nullptr |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 398 | /// @param decos the list of decorations for the variable declaration. |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 399 | Maybe<ast::Variable*> global_variable_decl(ast::DecorationList& decos); |
James Price | a6ced4d | 2021-02-01 14:59:13 +0000 | [diff] [blame] | 400 | /// Parses a `global_constant_decl` grammar element with the initial |
| 401 | /// `variable_decoration_list*` provided as `decos` |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 402 | /// @returns the const object or nullptr |
James Price | a6ced4d | 2021-02-01 14:59:13 +0000 | [diff] [blame] | 403 | /// @param decos the list of decorations for the constant declaration. |
| 404 | Maybe<ast::Variable*> global_constant_decl(ast::DecorationList& decos); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 405 | /// Parses a `variable_decl` grammar element |
Antonio Maiorano | 9834fef | 2021-06-04 15:28:47 +0000 | [diff] [blame] | 406 | /// @param allow_inferred if true, do not fail if variable decl does not |
| 407 | /// specify type |
Ben Clayton | a80511e | 2020-12-11 13:07:02 +0000 | [diff] [blame] | 408 | /// @returns the parsed variable declaration info |
Antonio Maiorano | 9834fef | 2021-06-04 15:28:47 +0000 | [diff] [blame] | 409 | Maybe<VarDeclInfo> variable_decl(bool allow_inferred = false); |
Ben Clayton | b8df120 | 2020-11-09 18:41:23 +0000 | [diff] [blame] | 410 | /// 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 Maiorano | 9834fef | 2021-06-04 15:28:47 +0000 | [diff] [blame] | 413 | /// @param allow_inferred if true, do not fail if variable decl does not |
| 414 | /// specify type |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 415 | /// @returns the identifier and type parsed or empty otherwise |
Antonio Maiorano | 9834fef | 2021-06-04 15:28:47 +0000 | [diff] [blame] | 416 | Expect<TypedIdentifier> expect_variable_ident_decl( |
| 417 | const std::string& use, |
| 418 | bool allow_inferred = false); |
Ben Clayton | 93e8f52 | 2021-06-04 20:41:47 +0000 | [diff] [blame] | 419 | /// Parses a `variable_qualifier` grammar element |
| 420 | /// @returns the variable qualifier information |
| 421 | Maybe<VariableQualifier> variable_qualifier(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 422 | /// Parses a `type_alias` grammar element |
| 423 | /// @returns the type alias or nullptr on error |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 424 | Maybe<ast::Alias*> type_alias(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 425 | /// Parses a `type_decl` grammar element |
Tomek Ponitka | c354200 | 2020-09-02 13:26:15 +0000 | [diff] [blame] | 426 | /// @returns the parsed Type or nullptr if none matched. |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 427 | Maybe<ast::Type*> type_decl(); |
dan sinclair | 7214f40 | 2020-11-19 18:55:01 +0000 | [diff] [blame] | 428 | /// 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 Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 432 | Maybe<ast::Type*> type_decl(ast::DecorationList& decos); |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 433 | /// 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 Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 435 | /// @returns the storage class or StorageClass::kNone if none matched |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 436 | Expect<ast::StorageClass> expect_storage_class(const std::string& use); |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 437 | /// Parses a `struct_decl` grammar element with the initial |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 438 | /// `struct_decoration_decl*` provided as `decos`. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 439 | /// @returns the struct type or nullptr on error |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 440 | /// @param decos the list of decorations for the struct declaration. |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 441 | Maybe<ast::Struct*> struct_decl(ast::DecorationList& decos); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 442 | /// Parses a `struct_body_decl` grammar element, erroring on parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 443 | /// @returns the struct members |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 444 | Expect<ast::StructMemberList> expect_struct_body_decl(); |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 445 | /// Parses a `struct_member` grammar element with the initial |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 446 | /// `struct_member_decoration_decl+` provided as `decos`, erroring on parse |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 447 | /// failure. |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 448 | /// @param decos the list of decorations for the struct member. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 449 | /// @returns the struct member or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 450 | Expect<ast::StructMember*> expect_struct_member(ast::DecorationList& decos); |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 451 | /// Parses a `function_decl` grammar element with the initial |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 452 | /// `function_decoration_decl*` provided as `decos`. |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 453 | /// @param decos the list of decorations for the function declaration. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 454 | /// @returns the parsed function, nullptr otherwise |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 455 | Maybe<ast::Function*> function_decl(ast::DecorationList& decos); |
Tomek Ponitka | 4beff41 | 2020-09-02 14:16:35 +0000 | [diff] [blame] | 456 | /// Parses a `texture_sampler_types` grammar element |
| 457 | /// @returns the parsed Type or nullptr if none matched. |
Ben Clayton | 7e00263 | 2021-06-16 09:19:36 +0000 | [diff] [blame] | 458 | Maybe<ast::Type*> texture_sampler_types(); |
Tomek Ponitka | c354200 | 2020-09-02 13:26:15 +0000 | [diff] [blame] | 459 | /// Parses a `sampler_type` grammar element |
| 460 | /// @returns the parsed Type or nullptr if none matched. |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 461 | Maybe<ast::Type*> sampler_type(); |
dan sinclair | d3f75ca | 2020-09-17 03:53:04 +0000 | [diff] [blame] | 462 | /// Parses a `multisampled_texture_type` grammar element |
| 463 | /// @returns returns the multisample texture dimension or kNone if none |
| 464 | /// matched. |
Ben Clayton | fec63b7 | 2021-04-21 13:47:12 +0000 | [diff] [blame] | 465 | Maybe<ast::TextureDimension> multisampled_texture_type(); |
Tomek Ponitka | fd3ca9e | 2020-09-02 15:52:15 +0000 | [diff] [blame] | 466 | /// Parses a `sampled_texture_type` grammar element |
| 467 | /// @returns returns the sample texture dimension or kNone if none matched. |
Ben Clayton | fec63b7 | 2021-04-21 13:47:12 +0000 | [diff] [blame] | 468 | Maybe<ast::TextureDimension> sampled_texture_type(); |
Tomek Ponitka | bcb6eb0 | 2020-09-08 16:48:09 +0000 | [diff] [blame] | 469 | /// Parses a `storage_texture_type` grammar element |
dan sinclair | 904c5b9 | 2021-01-14 08:34:46 +0000 | [diff] [blame] | 470 | /// @returns returns the storage texture dimension. |
| 471 | /// Returns kNone if none matched. |
Ben Clayton | fec63b7 | 2021-04-21 13:47:12 +0000 | [diff] [blame] | 472 | Maybe<ast::TextureDimension> storage_texture_type(); |
Tomek Ponitka | cbd1ef8 | 2020-09-02 14:06:45 +0000 | [diff] [blame] | 473 | /// Parses a `depth_texture_type` grammar element |
| 474 | /// @returns the parsed Type or nullptr if none matched. |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 475 | Maybe<ast::Type*> depth_texture_type(); |
Brandon Jones | 145f865 | 2021-04-22 22:47:03 +0000 | [diff] [blame] | 476 | /// Parses a 'texture_external_type' grammar element |
| 477 | /// @returns the parsed Type or nullptr if none matched |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 478 | Maybe<ast::Type*> external_texture_type(); |
Tomek Ponitka | 03f5e2f | 2020-09-08 16:38:39 +0000 | [diff] [blame] | 479 | /// Parses a `image_storage_type` grammar element |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 480 | /// @param use a description of what was being parsed if an error was raised |
Tomek Ponitka | 03f5e2f | 2020-09-08 16:38:39 +0000 | [diff] [blame] | 481 | /// @returns returns the image format or kNone if none matched. |
Ben Clayton | fec63b7 | 2021-04-21 13:47:12 +0000 | [diff] [blame] | 482 | Expect<ast::ImageFormat> expect_image_storage_type(const std::string& use); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 483 | /// Parses a `function_header` grammar element |
Ben Clayton | 234b7de | 2020-12-07 20:45:14 +0000 | [diff] [blame] | 484 | /// @returns the parsed function header |
| 485 | Maybe<FunctionHeader> function_header(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 486 | /// Parses a `param_list` grammar element, erroring on parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 487 | /// @returns the parsed variables |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 488 | Expect<ast::VariableList> expect_param_list(); |
James Price | 5c460bf | 2021-03-10 23:18:29 +0000 | [diff] [blame] | 489 | /// Parses a `param` grammar element, erroring on parse failure. |
| 490 | /// @returns the parsed variable |
| 491 | Expect<ast::Variable*> expect_param(); |
Ben Clayton | 32ba9b6 | 2020-11-04 20:00:31 +0000 | [diff] [blame] | 492 | /// Parses a `pipeline_stage` grammar element, erroring if the next token does |
| 493 | /// not match a stage name. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 494 | /// @returns the pipeline stage. |
| 495 | Expect<ast::PipelineStage> expect_pipeline_stage(); |
Ben Clayton | 93e8f52 | 2021-06-04 20:41:47 +0000 | [diff] [blame] | 496 | /// 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 sinclair | 7214f40 | 2020-11-19 18:55:01 +0000 | [diff] [blame] | 499 | /// @returns the parsed access control. |
Ben Clayton | 93e8f52 | 2021-06-04 20:41:47 +0000 | [diff] [blame] | 500 | Expect<ast::Access> expect_access(const std::string& use); |
Ben Clayton | b8791a5 | 2020-11-04 20:06:21 +0000 | [diff] [blame] | 501 | /// Parses a builtin identifier, erroring if the next token does not match a |
| 502 | /// valid builtin name. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 503 | /// @returns the parsed builtin. |
| 504 | Expect<ast::Builtin> expect_builtin(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 505 | /// Parses a `body_stmt` grammar element, erroring on parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 506 | /// @returns the parsed statements |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 507 | Expect<ast::BlockStatement*> expect_body_stmt(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 508 | /// Parses a `paren_rhs_stmt` grammar element, erroring on parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 509 | /// @returns the parsed element or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 510 | Expect<ast::Expression*> expect_paren_rhs_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 511 | /// Parses a `statements` grammar element |
| 512 | /// @returns the statements parsed |
Ben Clayton | d408f24 | 2020-12-14 20:31:17 +0000 | [diff] [blame] | 513 | Expect<ast::StatementList> expect_statements(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 514 | /// Parses a `statement` grammar element |
| 515 | /// @returns the parsed statement or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 516 | Maybe<ast::Statement*> statement(); |
dan sinclair | 091b2b5 | 2020-06-01 13:44:06 +0000 | [diff] [blame] | 517 | /// Parses a `break_stmt` grammar element |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 518 | /// @returns the parsed statement or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 519 | Maybe<ast::BreakStatement*> break_stmt(); |
dan sinclair | 091b2b5 | 2020-06-01 13:44:06 +0000 | [diff] [blame] | 520 | /// Parses a `return_stmt` grammar element |
| 521 | /// @returns the parsed statement or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 522 | Maybe<ast::ReturnStatement*> return_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 523 | /// Parses a `continue_stmt` grammar element |
| 524 | /// @returns the parsed statement or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 525 | Maybe<ast::ContinueStatement*> continue_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 526 | /// Parses a `variable_stmt` grammar element |
| 527 | /// @returns the parsed variable or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 528 | Maybe<ast::VariableDeclStatement*> variable_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 529 | /// Parses a `if_stmt` grammar element |
| 530 | /// @returns the parsed statement or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 531 | Maybe<ast::IfStatement*> if_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 532 | /// Parses a `elseif_stmt` grammar element |
| 533 | /// @returns the parsed elements |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 534 | Maybe<ast::ElseStatementList> elseif_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 535 | /// Parses a `else_stmt` grammar element |
| 536 | /// @returns the parsed statement or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 537 | Maybe<ast::ElseStatement*> else_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 538 | /// Parses a `switch_stmt` grammar element |
| 539 | /// @returns the parsed statement or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 540 | Maybe<ast::SwitchStatement*> switch_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 541 | /// Parses a `switch_body` grammar element |
| 542 | /// @returns the parsed statement or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 543 | Maybe<ast::CaseStatement*> switch_body(); |
dan sinclair | 1aadbd4 | 2020-06-01 16:56:46 +0000 | [diff] [blame] | 544 | /// Parses a `case_selectors` grammar element |
| 545 | /// @returns the list of literals |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 546 | Expect<ast::CaseSelectorList> expect_case_selectors(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 547 | /// Parses a `case_body` grammar element |
| 548 | /// @returns the parsed statements |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 549 | Maybe<ast::BlockStatement*> case_body(); |
dan sinclair | fbbc617 | 2020-07-21 15:13:36 +0000 | [diff] [blame] | 550 | /// Parses a `func_call_stmt` grammar element |
| 551 | /// @returns the parsed function call or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 552 | Maybe<ast::CallStatement*> func_call_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 553 | /// Parses a `loop_stmt` grammar element |
| 554 | /// @returns the parsed loop or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 555 | Maybe<ast::LoopStatement*> loop_stmt(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 556 | /// Parses a `for_header` grammar element, erroring on parse failure. |
Tomek Ponitka | 63a5aa7 | 2020-08-24 18:22:22 +0000 | [diff] [blame] | 557 | /// @returns the parsed for header or nullptr |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 558 | Expect<std::unique_ptr<ForHeader>> expect_for_header(); |
Tomek Ponitka | 63a5aa7 | 2020-08-24 18:22:22 +0000 | [diff] [blame] | 559 | /// Parses a `for_stmt` grammar element |
| 560 | /// @returns the parsed for loop or nullptr |
Ben Clayton | 1b03f0a | 2021-07-08 21:23:33 +0000 | [diff] [blame] | 561 | Maybe<ast::ForLoopStatement*> for_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 562 | /// Parses a `continuing_stmt` grammar element |
| 563 | /// @returns the parsed statements |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 564 | Maybe<ast::BlockStatement*> continuing_stmt(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 565 | /// Parses a `const_literal` grammar element |
| 566 | /// @returns the const literal parsed or nullptr if none found |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 567 | Maybe<ast::Literal*> const_literal(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 568 | /// Parses a `const_expr` grammar element, erroring on parse failure. |
dan sinclair | a322f5d | 2020-03-30 22:46:06 +0000 | [diff] [blame] | 569 | /// @returns the parsed constructor expression or nullptr on error |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 570 | Expect<ast::ConstructorExpression*> expect_const_expr(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 571 | /// Parses a `primary_expression` grammar element |
| 572 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 573 | Maybe<ast::Expression*> primary_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 574 | /// Parses a `argument_expression_list` grammar element, erroring on parse |
| 575 | /// failure. |
James Price | e80887d | 2021-04-29 15:49:44 +0000 | [diff] [blame] | 576 | /// @param use a description of what was being parsed if an error was raised |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 577 | /// @returns the list of arguments |
James Price | e80887d | 2021-04-29 15:49:44 +0000 | [diff] [blame] | 578 | Expect<ast::ExpressionList> expect_argument_expression_list( |
| 579 | const std::string& use); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 580 | /// 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 Price | 961dc6f | 2021-04-29 15:02:15 +0000 | [diff] [blame] | 583 | Maybe<ast::Expression*> postfix_expression(ast::Expression* prefix); |
| 584 | /// Parses a `singular_expression` grammar elment |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 585 | /// @returns the parsed expression or nullptr |
James Price | 961dc6f | 2021-04-29 15:02:15 +0000 | [diff] [blame] | 586 | Maybe<ast::Expression*> singular_expression(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 587 | /// Parses a `unary_expression` grammar element |
| 588 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 589 | Maybe<ast::Expression*> unary_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 590 | /// Parses the recursive part of the `multiplicative_expression`, erroring on |
| 591 | /// parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 592 | /// @param lhs the left side of the expression |
| 593 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 594 | Expect<ast::Expression*> expect_multiplicative_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 595 | /// Parses the `multiplicative_expression` grammar element |
| 596 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 597 | Maybe<ast::Expression*> multiplicative_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 598 | /// Parses the recursive part of the `additive_expression`, erroring on parse |
| 599 | /// failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 600 | /// @param lhs the left side of the expression |
| 601 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 602 | Expect<ast::Expression*> expect_additive_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 603 | /// Parses the `additive_expression` grammar element |
| 604 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 605 | Maybe<ast::Expression*> additive_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 606 | /// Parses the recursive part of the `shift_expression`, erroring on parse |
| 607 | /// failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 608 | /// @param lhs the left side of the expression |
| 609 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 610 | Expect<ast::Expression*> expect_shift_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 611 | /// Parses the `shift_expression` grammar element |
| 612 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 613 | Maybe<ast::Expression*> shift_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 614 | /// Parses the recursive part of the `relational_expression`, erroring on |
| 615 | /// parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 616 | /// @param lhs the left side of the expression |
| 617 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 618 | Expect<ast::Expression*> expect_relational_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 619 | /// Parses the `relational_expression` grammar element |
| 620 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 621 | Maybe<ast::Expression*> relational_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 622 | /// Parses the recursive part of the `equality_expression`, erroring on parse |
| 623 | /// failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 624 | /// @param lhs the left side of the expression |
| 625 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 626 | Expect<ast::Expression*> expect_equality_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 627 | /// Parses the `equality_expression` grammar element |
| 628 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 629 | Maybe<ast::Expression*> equality_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 630 | /// Parses the recursive part of the `and_expression`, erroring on parse |
| 631 | /// failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 632 | /// @param lhs the left side of the expression |
| 633 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 634 | Expect<ast::Expression*> expect_and_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 635 | /// Parses the `and_expression` grammar element |
| 636 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 637 | Maybe<ast::Expression*> and_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 638 | /// Parses the recursive part of the `exclusive_or_expression`, erroring on |
| 639 | /// parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 640 | /// @param lhs the left side of the expression |
| 641 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 642 | Expect<ast::Expression*> expect_exclusive_or_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 643 | /// Parses the `exclusive_or_expression` grammar elememnt |
| 644 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 645 | Maybe<ast::Expression*> exclusive_or_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 646 | /// Parses the recursive part of the `inclusive_or_expression`, erroring on |
| 647 | /// parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 648 | /// @param lhs the left side of the expression |
| 649 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 650 | Expect<ast::Expression*> expect_inclusive_or_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 651 | /// Parses the `inclusive_or_expression` grammar element |
| 652 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 653 | Maybe<ast::Expression*> inclusive_or_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 654 | /// Parses the recursive part of the `logical_and_expression`, erroring on |
| 655 | /// parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 656 | /// @param lhs the left side of the expression |
| 657 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 658 | Expect<ast::Expression*> expect_logical_and_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 659 | /// Parses a `logical_and_expression` grammar element |
| 660 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 661 | Maybe<ast::Expression*> logical_and_expression(); |
Ben Clayton | 7b750dc | 2020-11-09 15:49:33 +0000 | [diff] [blame] | 662 | /// Parses the recursive part of the `logical_or_expression`, erroring on |
| 663 | /// parse failure. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 664 | /// @param lhs the left side of the expression |
| 665 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 666 | Expect<ast::Expression*> expect_logical_or_expr(ast::Expression* lhs); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 667 | /// Parses a `logical_or_expression` grammar element |
| 668 | /// @returns the parsed expression or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 669 | Maybe<ast::Expression*> logical_or_expression(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 670 | /// Parses a `assignment_stmt` grammar element |
| 671 | /// @returns the parsed assignment or nullptr |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 672 | Maybe<ast::AssignmentStatement*> assignment_stmt(); |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 673 | /// Parses one or more bracketed decoration lists. |
| 674 | /// @return the parsed decoration list, or an empty list on error. |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 675 | Maybe<ast::DecorationList> decoration_list(); |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 676 | /// 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 Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 680 | Maybe<bool> decoration_bracketed_list(ast::DecorationList& decos); |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 681 | /// 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 Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 689 | Maybe<ast::Decoration*> decoration(); |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 690 | /// 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 Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 694 | Expect<ast::Decoration*> expect_decoration(); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 695 | |
| 696 | private: |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 697 | /// ReturnType resolves to the return type for the function or lambda F. |
Ben Clayton | 786bc92 | 2020-11-04 20:08:51 +0000 | [diff] [blame] | 698 | template <typename F> |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 699 | using ReturnType = typename std::result_of<F()>::type; |
| 700 | |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 701 | /// ResultType resolves to `T` for a `RESULT` of type Expect<T>. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 702 | template <typename RESULT> |
| 703 | using ResultType = typename RESULT::type; |
Ben Clayton | 786bc92 | 2020-11-04 20:08:51 +0000 | [diff] [blame] | 704 | |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 705 | /// @returns true and consumes the next token if it equals `tok` |
Ben Clayton | 4ce7a93 | 2020-11-04 18:39:41 +0000 | [diff] [blame] | 706 | /// @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 Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 709 | /// Errors if the next token is not equal to `tok` |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 710 | /// Consumes the next token on match. |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 711 | /// expect() also updates #synchronized_, setting it to `true` if the next |
| 712 | /// token is equal to `tok`, otherwise `false`. |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 713 | /// @param use a description of what was being parsed if an error was raised. |
| 714 | /// @param tok the token to test against |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 715 | /// @returns true if the next token equals `tok` |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 716 | 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 Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 719 | /// Consumes the next token on match. |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 720 | /// @param use a description of what was being parsed if an error was raised |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 721 | /// @returns the parsed integer. |
| 722 | Expect<int32_t> expect_sint(const std::string& use); |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 723 | /// 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 Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 725 | /// Consumes the next token if it is a signed integer (not necessarily |
| 726 | /// negative). |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 727 | /// @param use a description of what was being parsed if an error was raised |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 728 | /// @returns the parsed integer. |
| 729 | Expect<uint32_t> expect_positive_sint(const std::string& use); |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 730 | /// 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 Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 732 | /// Consumes the next token if it is a signed integer (not necessarily |
| 733 | /// >= 1). |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 734 | /// @param use a description of what was being parsed if an error was raised |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 735 | /// @returns the parsed integer. |
| 736 | Expect<uint32_t> expect_nonzero_positive_sint(const std::string& use); |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 737 | /// Errors if the next token is not an identifier. |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 738 | /// Consumes the next token on match. |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 739 | /// @param use a description of what was being parsed if an error was raised |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 740 | /// @returns the parsed identifier. |
| 741 | Expect<std::string> expect_ident(const std::string& use); |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 742 | /// 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 Clayton | 786bc92 | 2020-11-04 20:08:51 +0000 | [diff] [blame] | 748 | /// @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 Clayton | 00bc8ba | 2020-11-11 14:10:25 +0000 | [diff] [blame] | 752 | /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`. |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 753 | /// @return the value returned by `body` if no errors are raised, otherwise |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 754 | /// an Expect with error state. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 755 | template <typename F, typename T = ReturnType<F>> |
Ben Clayton | 786bc92 | 2020-11-04 20:08:51 +0000 | [diff] [blame] | 756 | T expect_block(Token::Type start, |
| 757 | Token::Type end, |
| 758 | const std::string& use, |
| 759 | F&& body); |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 760 | /// 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 Clayton | 786bc92 | 2020-11-04 20:08:51 +0000 | [diff] [blame] | 763 | /// @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 Clayton | 00bc8ba | 2020-11-11 14:10:25 +0000 | [diff] [blame] | 765 | /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`. |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 766 | /// @return the value returned by `body` if no errors are raised, otherwise |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 767 | /// an Expect with error state. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 768 | template <typename F, typename T = ReturnType<F>> |
Ben Clayton | 786bc92 | 2020-11-04 20:08:51 +0000 | [diff] [blame] | 769 | T expect_paren_block(const std::string& use, F&& body); |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 770 | /// 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 Clayton | 786bc92 | 2020-11-04 20:08:51 +0000 | [diff] [blame] | 773 | /// @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 Clayton | 00bc8ba | 2020-11-11 14:10:25 +0000 | [diff] [blame] | 775 | /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`. |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 776 | /// @return the value returned by `body` if no errors are raised, otherwise |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 777 | /// an Expect with error state. |
Ben Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 778 | template <typename F, typename T = ReturnType<F>> |
Ben Clayton | 786bc92 | 2020-11-04 20:08:51 +0000 | [diff] [blame] | 779 | T expect_brace_block(const std::string& use, F&& body); |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 780 | /// 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 Clayton | 00bc8ba | 2020-11-11 14:10:25 +0000 | [diff] [blame] | 783 | /// @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 Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 786 | /// @return the value returned by `body` if no errors are raised, otherwise |
Ben Clayton | 00bc8ba | 2020-11-11 14:10:25 +0000 | [diff] [blame] | 787 | /// 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 Clayton | 653c404 | 2020-11-09 19:39:34 +0000 | [diff] [blame] | 790 | |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 791 | /// 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 Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 795 | /// |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 796 | /// 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 Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 802 | /// |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 803 | /// sync() updates #synchronized_, setting it to `true` if the next |
| 804 | /// resynchronization token found was `tok`, otherwise `false`. |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 805 | /// |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 806 | /// @param tok the token to attempt to synchronize the parser to if `func` |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 807 | /// fails. |
| 808 | /// @param func a function or lambda with the signature: `Expect<Result>()` or |
| 809 | /// `Maybe<Result>()`. |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 810 | /// @return the value returned by `func` |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 811 | 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 Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 814 | /// resynchronization token or `tok` (whichever comes first). |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 815 | /// |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 816 | /// Synchronization tokens are transiently defined by calls to sync(). |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 817 | /// |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 818 | /// sync_to() updates #synchronized_, setting it to `true` if a |
| 819 | /// resynchronization token was found and it was `tok`, otherwise `false`. |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 820 | /// |
| 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 Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 823 | /// `tok` then sync_to() will also consume `tok`. |
| 824 | /// @return the state of #synchronized_. |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 825 | /// @see sync(). |
| 826 | bool sync_to(Token::Type tok, bool consume); |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 827 | /// @return true if `t` is in the stack of resynchronization tokens. |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 828 | /// @see sync(). |
| 829 | bool is_sync_token(const Token& t) const; |
| 830 | |
Ben Clayton | 3797ab6 | 2021-07-12 16:50:31 +0000 | [diff] [blame] | 831 | /// @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 Clayton | c41c7cd | 2021-06-28 16:09:57 +0000 | [diff] [blame] | 836 | |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 837 | /// without_error() calls the function `func` muting any grammatical errors |
Ben Clayton | aa5f23e | 2020-11-19 14:19:31 +0000 | [diff] [blame] | 838 | /// 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 Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 842 | /// @return the value returned by `func` |
Ben Clayton | aa5f23e | 2020-11-19 14:19:31 +0000 | [diff] [blame] | 843 | template <typename F, typename T = ReturnType<F>> |
| 844 | T without_error(F&& func); |
| 845 | |
Ben Clayton | f8971ae | 2020-12-02 15:31:08 +0000 | [diff] [blame] | 846 | /// Reports an error if the decoration list `list` is not empty. |
Ben Clayton | 88dc2a4 | 2020-11-04 20:55:31 +0000 | [diff] [blame] | 847 | /// Used to ensure that all decorations are consumed. |
| 848 | bool expect_decorations_consumed(const ast::DecorationList& list); |
Ben Clayton | d70f251 | 2020-11-04 14:14:40 +0000 | [diff] [blame] | 849 | |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 850 | Expect<ast::Type*> expect_type_decl_pointer(Token t); |
Ben Clayton | 989c3a1 | 2021-06-17 15:48:39 +0000 | [diff] [blame] | 851 | Expect<ast::Type*> expect_type_decl_atomic(Token t); |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 852 | 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 Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 855 | |
Ben Clayton | b7bd0e1 | 2021-05-06 15:57:13 +0000 | [diff] [blame] | 856 | Expect<ast::Type*> expect_type(const std::string& use); |
Ben Clayton | 00bc8ba | 2020-11-11 14:10:25 +0000 | [diff] [blame] | 857 | |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 858 | Maybe<ast::Statement*> non_block_statement(); |
| 859 | Maybe<ast::Statement*> for_header_initializer(); |
| 860 | Maybe<ast::Statement*> for_header_continuing(); |
Ben Clayton | ab5dfee | 2020-11-09 19:52:24 +0000 | [diff] [blame] | 861 | |
Antonio Maiorano | 4b16a16 | 2021-04-27 17:32:37 +0000 | [diff] [blame] | 862 | class MultiTokenSource; |
| 863 | MultiTokenSource make_source_range(); |
| 864 | MultiTokenSource make_source_range_from(const Source& start); |
| 865 | |
Ben Clayton | 2f4096b | 2020-11-18 20:58:20 +0000 | [diff] [blame] | 866 | /// Creates a new `ast::Node` owned by the Module. When the Module is |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 867 | /// 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 Clayton | f65799e | 2020-11-16 16:11:19 +0000 | [diff] [blame] | 870 | template <typename T, typename... ARGS> |
Ben Clayton | b053acf | 2020-11-16 16:31:07 +0000 | [diff] [blame] | 871 | T* create(ARGS&&... args) { |
Ben Clayton | a6b9a8e | 2021-01-26 16:57:10 +0000 | [diff] [blame] | 872 | return builder_.create<T>(std::forward<ARGS>(args)...); |
Ben Clayton | f65799e | 2020-11-16 16:11:19 +0000 | [diff] [blame] | 873 | } |
| 874 | |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 875 | std::unique_ptr<Lexer> lexer_; |
| 876 | std::deque<Token> token_queue_; |
Antonio Maiorano | 4b16a16 | 2021-04-27 17:32:37 +0000 | [diff] [blame] | 877 | Token last_token_; |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 878 | bool synchronized_ = true; |
Ben Clayton | e7257eb | 2021-06-21 19:36:26 +0000 | [diff] [blame] | 879 | uint32_t parse_depth_ = 0; |
Ben Clayton | af8091e | 2020-11-11 18:44:36 +0000 | [diff] [blame] | 880 | std::vector<Token::Type> sync_tokens_; |
Ben Clayton | aa5f23e | 2020-11-19 14:19:31 +0000 | [diff] [blame] | 881 | int silence_errors_ = 0; |
Ben Clayton | 950809f | 2021-06-09 14:32:14 +0000 | [diff] [blame] | 882 | std::unordered_map<std::string, const ast::TypeDecl*> registered_types_; |
Ben Clayton | a6b9a8e | 2021-01-26 16:57:10 +0000 | [diff] [blame] | 883 | ProgramBuilder builder_; |
Ben Clayton | 1e87fe5 | 2020-11-24 15:15:36 +0000 | [diff] [blame] | 884 | size_t max_errors_ = 25; |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 885 | }; |
| 886 | |
| 887 | } // namespace wgsl |
| 888 | } // namespace reader |
| 889 | } // namespace tint |
| 890 | |
| 891 | #endif // SRC_READER_WGSL_PARSER_IMPL_H_ |