// Copyright 2020 The Tint Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SRC_READER_WGSL_PARSER_IMPL_H_ #define SRC_READER_WGSL_PARSER_IMPL_H_ #include #include #include #include #include #include "src/ast/assignment_statement.h" #include "src/ast/builtin.h" #include "src/ast/call_statement.h" #include "src/ast/case_statement.h" #include "src/ast/constructor_expression.h" #include "src/ast/else_statement.h" #include "src/ast/entry_point.h" #include "src/ast/function.h" #include "src/ast/import.h" #include "src/ast/literal.h" #include "src/ast/loop_statement.h" #include "src/ast/module.h" #include "src/ast/pipeline_stage.h" #include "src/ast/statement.h" #include "src/ast/storage_class.h" #include "src/ast/struct.h" #include "src/ast/struct_decoration.h" #include "src/ast/struct_member.h" #include "src/ast/struct_member_decoration.h" #include "src/ast/type/type.h" #include "src/ast/variable.h" #include "src/ast/variable_decoration.h" #include "src/context.h" #include "src/reader/wgsl/token.h" namespace tint { namespace reader { namespace wgsl { class Lexer; /// Struct holding information for a for loop struct ForHeader { /// Constructor /// @param init the initializer statement /// @param cond the condition statement /// @param cont the continuing statement ForHeader(std::unique_ptr init, std::unique_ptr cond, std::unique_ptr cont); ~ForHeader(); /// The for loop initializer std::unique_ptr initializer; /// The for loop condition std::unique_ptr condition; /// The for loop continuing statement std::unique_ptr continuing; }; /// ParserImpl for WGSL source data class ParserImpl { public: /// Creates a new parser /// @param ctx the non-null context object /// @param input the input string to parse ParserImpl(Context* ctx, const std::string& input); ~ParserImpl(); /// Run the parser /// @returns true if the parse was successful, false otherwise. bool Parse(); /// @returns true if an error was encountered bool has_error() const { return error_.size() > 0; } /// @returns the parser error string const std::string& error() const { return error_; } /// @returns the module. The module in the parser will be reset after this. ast::Module module() { return std::move(module_); } /// @returns the next token Token next(); /// @returns the next token without advancing Token peek(); /// Peeks ahead and returns the token at |idx| head of the current position /// @param idx the index of the token to return /// @returns the token |idx| positions ahead without advancing Token peek(size_t idx); /// Sets the error from |t| /// @param t the token to set the error from void set_error(const Token& t); /// Sets the error from |t| or |msg| if |t| is not in error /// @param t the token to set the error from /// @param msg the error message void set_error(const Token& t, const std::string& msg); /// Registers a type alias into the parser /// @param name the alias name /// @param type the alias'd type void register_alias(const std::string& name, ast::type::Type* type); /// Retrieves an aliased type /// @param name The alias name to lookup /// @returns the alias type for |name| or nullptr if not found ast::type::Type* get_alias(const std::string& name); /// Parses the `translation_unit` grammar element void translation_unit(); /// Parses the `global_decl` grammar element void global_decl(); /// Parses the `import_decl grammar element /// @returns the import object or nullptr if an error was encountered std::unique_ptr import_decl(); /// Parses a `global_variable_decl` grammar element /// @returns the variable parsed or nullptr std::unique_ptr global_variable_decl(); /// Parses a `global_constant_decl` grammar element /// @returns the const object or nullptr std::unique_ptr global_constant_decl(); /// Parses a `variable_decoration_list` grammar element /// @returns the parsed variable decorations ast::VariableDecorationList variable_decoration_list(); /// Parses a `variable_decoration` grammar element /// @returns the variable decoration or nullptr if an error is encountered std::unique_ptr variable_decoration(); /// Parses a `variable_decl` grammar element /// @returns the parsed variable or nullptr otherwise std::unique_ptr variable_decl(); /// Parses a `variable_ident_decl` grammar element /// @returns the identifier and type parsed or empty otherwise std::pair variable_ident_decl(); /// Parses a `variable_storage_decoration` grammar element /// @returns the storage class or StorageClass::kNone if none matched ast::StorageClass variable_storage_decoration(); /// Parses a `type_alias` grammar element /// @returns the type alias or nullptr on error ast::type::AliasType* type_alias(); /// Parses a `type_decl` grammar element /// @returns the parsed Type or nullptr if none matched. ast::type::Type* type_decl(); /// Parses a `storage_class` grammar element /// @returns the storage class or StorageClass::kNone if none matched ast::StorageClass storage_class(); /// Parses a `struct_decl` grammar element /// @returns the struct type or nullptr on error std::unique_ptr struct_decl(); /// Parses a `struct_decoration_decl` grammar element /// @returns the struct decoration or StructDecoraton::kNone ast::StructDecoration struct_decoration_decl(); /// Parses a `struct_decoration` grammar element /// @param t the current token /// @returns the struct decoration or StructDecoraton::kNone if none matched ast::StructDecoration struct_decoration(Token t); /// Parses a `struct_body_decl` grammar element /// @returns the struct members ast::StructMemberList struct_body_decl(); /// Parses a `struct_member` grammar element /// @returns the struct member or nullptr std::unique_ptr struct_member(); /// Parses a `struct_member_decoration_decl` grammar element /// @returns the list of decorations ast::StructMemberDecorationList struct_member_decoration_decl(); /// Parses a `struct_member_decoration` grammar element /// @returns the decoration or nullptr if none found std::unique_ptr struct_member_decoration(); /// Parses a `function_decl` grammar element /// @returns the parsed function, nullptr otherwise std::unique_ptr function_decl(); /// Parses a `sampler_type` grammar element /// @returns the parsed Type or nullptr if none matched. ast::type::Type* sampler_type(); /// Parses a `function_type_decl` grammar element /// @returns the parsed type or nullptr otherwise ast::type::Type* function_type_decl(); /// Parses a `function_header` grammar element /// @returns the parsed function nullptr otherwise std::unique_ptr function_header(); /// Parses a `param_list` grammar element /// @returns the parsed variables ast::VariableList param_list(); /// Parses a `entry_point_decl` grammar element /// @returns the EntryPoint or nullptr on error std::unique_ptr entry_point_decl(); /// Parses a `pipeline_stage` grammar element /// @returns the pipeline stage or PipelineStage::kNone if none matched ast::PipelineStage pipeline_stage(); /// Parses a `body_stmt` grammar element /// @returns the parsed statements std::unique_ptr body_stmt(); /// Parses a `paren_rhs_stmt` grammar element /// @returns the parsed element or nullptr std::unique_ptr paren_rhs_stmt(); /// Parses a `statements` grammar element /// @returns the statements parsed std::unique_ptr statements(); /// Parses a `statement` grammar element /// @returns the parsed statement or nullptr std::unique_ptr statement(); /// Parses a `break_stmt` grammar element /// @returns the parsed statement or nullptr std::unique_ptr break_stmt(); /// Parses a `return_stmt` grammar element /// @returns the parsed statement or nullptr std::unique_ptr return_stmt(); /// Parses a `continue_stmt` grammar element /// @returns the parsed statement or nullptr std::unique_ptr continue_stmt(); /// Parses a `variable_stmt` grammar element /// @returns the parsed variable or nullptr std::unique_ptr variable_stmt(); /// Parses a `if_stmt` grammar element /// @returns the parsed statement or nullptr std::unique_ptr if_stmt(); /// Parses a `elseif_stmt` grammar element /// @returns the parsed elements ast::ElseStatementList elseif_stmt(); /// Parses a `else_stmt` grammar element /// @returns the parsed statement or nullptr std::unique_ptr else_stmt(); /// Parses a `switch_stmt` grammar element /// @returns the parsed statement or nullptr std::unique_ptr switch_stmt(); /// Parses a `switch_body` grammar element /// @returns the parsed statement or nullptr std::unique_ptr switch_body(); /// Parses a `case_selectors` grammar element /// @returns the list of literals ast::CaseSelectorList case_selectors(); /// Parses a `case_body` grammar element /// @returns the parsed statements std::unique_ptr case_body(); /// Parses a `func_call_stmt` grammar element /// @returns the parsed function call or nullptr std::unique_ptr func_call_stmt(); /// Parses a `loop_stmt` grammar element /// @returns the parsed loop or nullptr std::unique_ptr loop_stmt(); /// Parses a `for_header` grammar element /// @returns the parsed for header or nullptr std::unique_ptr for_header(); /// Parses a `for_stmt` grammar element /// @returns the parsed for loop or nullptr std::unique_ptr for_stmt(); /// Parses a `continuing_stmt` grammar element /// @returns the parsed statements std::unique_ptr continuing_stmt(); /// Parses a `const_literal` grammar element /// @returns the const literal parsed or nullptr if none found std::unique_ptr const_literal(); /// Parses a `const_expr` grammar element /// @returns the parsed constructor expression or nullptr on error std::unique_ptr const_expr(); /// Parses a `primary_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr primary_expression(); /// Parses a `argument_expression_list` grammar element /// @returns the list of arguments ast::ExpressionList argument_expression_list(); /// Parses the recursive portion of the postfix_expression /// @param prefix the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr postfix_expr( std::unique_ptr prefix); /// Parses a `postfix_expression` grammar elment /// @returns the parsed expression or nullptr std::unique_ptr postfix_expression(); /// Parses a `unary_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr unary_expression(); /// Parses the recursive part of the `multiplicative_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr multiplicative_expr( std::unique_ptr lhs); /// Parses the `multiplicative_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr multiplicative_expression(); /// Parses the recursive part of the `additive_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr additive_expr( std::unique_ptr lhs); /// Parses the `additive_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr additive_expression(); /// Parses the recursive part of the `shift_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr shift_expr( std::unique_ptr lhs); /// Parses the `shift_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr shift_expression(); /// Parses the recursive part of the `relational_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr relational_expr( std::unique_ptr lhs); /// Parses the `relational_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr relational_expression(); /// Parses the recursive part of the `equality_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr equality_expr( std::unique_ptr lhs); /// Parses the `equality_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr equality_expression(); /// Parses the recursive part of the `and_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr and_expr( std::unique_ptr lhs); /// Parses the `and_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr and_expression(); /// Parses the recursive part of the `exclusive_or_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr exclusive_or_expr( std::unique_ptr lhs); /// Parses the `exclusive_or_expression` grammar elememnt /// @returns the parsed expression or nullptr std::unique_ptr exclusive_or_expression(); /// Parses the recursive part of the `inclusive_or_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr inclusive_or_expr( std::unique_ptr lhs); /// Parses the `inclusive_or_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr inclusive_or_expression(); /// Parses the recursive part of the `logical_and_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr logical_and_expr( std::unique_ptr lhs); /// Parses a `logical_and_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr logical_and_expression(); /// Parses the recursive part of the `logical_or_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr std::unique_ptr logical_or_expr( std::unique_ptr lhs); /// Parses a `logical_or_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr logical_or_expression(); /// Parses a `assignment_stmt` grammar element /// @returns the parsed assignment or nullptr std::unique_ptr assignment_stmt(); private: ast::type::Type* type_decl_pointer(Token t); ast::type::Type* type_decl_vector(Token t); ast::type::Type* type_decl_array(Token t, uint32_t stride); uint32_t array_decoration_list(); ast::type::Type* type_decl_matrix(Token t); std::unique_ptr const_expr_internal( uint32_t depth); Context& ctx_; std::string error_; std::unique_ptr lexer_; std::deque token_queue_; std::unordered_map registered_aliases_; ast::Module module_; }; } // namespace wgsl } // namespace reader } // namespace tint #endif // SRC_READER_WGSL_PARSER_IMPL_H_