// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) // This file is part of the "Nazara Engine - Shader module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once #ifndef NAZARA_SHADER_SHADERLANGPARSER_HPP #define NAZARA_SHADER_SHADERLANGPARSER_HPP #include #include #include #include #include #include namespace Nz::ShaderLang { class NAZARA_SHADER_API Parser { public: inline Parser(); ~Parser() = default; ShaderAst::ModulePtr Parse(const std::vector& tokens); private: struct Attribute { ShaderAst::AttributeType type; ShaderAst::ExpressionPtr args; SourceLocation sourceLocation; }; // Flow control const Token& Advance(); void Consume(std::size_t count = 1); const Token& Expect(const Token& token, TokenType type); const Token& ExpectNot(const Token& token, TokenType type); const Token& Expect(TokenType type); const Token& Peek(std::size_t advance = 0); std::vector ParseAttributes(); void ParseModuleStatement(std::vector attributes); void ParseVariableDeclaration(std::string& name, ShaderAst::ExpressionValue& type, ShaderAst::ExpressionPtr& initialValue, SourceLocation& sourceLocation); ShaderAst::ExpressionPtr BuildIdentifierAccess(ShaderAst::ExpressionPtr lhs, ShaderAst::ExpressionPtr rhs); ShaderAst::ExpressionPtr BuildIndexAccess(ShaderAst::ExpressionPtr lhs, ShaderAst::ExpressionPtr rhs); ShaderAst::ExpressionPtr BuildBinary(ShaderAst::BinaryType binaryType, ShaderAst::ExpressionPtr lhs, ShaderAst::ExpressionPtr rhs); // Statements ShaderAst::StatementPtr ParseAliasDeclaration(); ShaderAst::StatementPtr ParseBranchStatement(); ShaderAst::StatementPtr ParseConstStatement(); ShaderAst::StatementPtr ParseDiscardStatement(); ShaderAst::StatementPtr ParseExternalBlock(std::vector attributes = {}); ShaderAst::StatementPtr ParseForDeclaration(std::vector attributes = {}); ShaderAst::StatementPtr ParseFunctionDeclaration(std::vector attributes = {}); ShaderAst::DeclareFunctionStatement::Parameter ParseFunctionParameter(); ShaderAst::StatementPtr ParseImportStatement(); ShaderAst::StatementPtr ParseOptionDeclaration(); ShaderAst::StatementPtr ParseReturnStatement(); ShaderAst::StatementPtr ParseRootStatement(std::vector attributes = {}); ShaderAst::StatementPtr ParseSingleStatement(); ShaderAst::StatementPtr ParseStatement(); std::vector ParseStatementList(SourceLocation* sourceLocation); ShaderAst::StatementPtr ParseStructDeclaration(std::vector attributes = {}); ShaderAst::StatementPtr ParseVariableDeclaration(); ShaderAst::StatementPtr ParseWhileStatement(std::vector attributes); // Expressions ShaderAst::ExpressionPtr ParseBinOpRhs(int exprPrecedence, ShaderAst::ExpressionPtr lhs); ShaderAst::ExpressionPtr ParseConstSelectExpression(); ShaderAst::ExpressionPtr ParseExpression(); std::vector ParseExpressionList(TokenType terminationToken, SourceLocation* terminationLocation); ShaderAst::ExpressionPtr ParseFloatingPointExpression(); ShaderAst::ExpressionPtr ParseIdentifier(); ShaderAst::ExpressionPtr ParseIntegerExpression(); ShaderAst::ExpressionPtr ParseParenthesisExpression(); ShaderAst::ExpressionPtr ParsePrimaryExpression(); ShaderAst::ExpressionPtr ParseStringExpression(); ShaderAst::ExpressionPtr ParseVariableAssignation(); const std::string& ParseIdentifierAsName(SourceLocation* sourceLocation); std::string ParseModuleName(); ShaderAst::ExpressionPtr ParseType(); template void HandleUniqueAttribute(ShaderAst::ExpressionValue& targetAttribute, Attribute&& attribute); template void HandleUniqueAttribute(ShaderAst::ExpressionValue& targetAttribute, Attribute&& attribute, T defaultValue); template void HandleUniqueStringAttribute(ShaderAst::ExpressionValue& targetAttribute, Attribute&& attribute, const M& map, std::optional defaultValue = {}); static int GetTokenPrecedence(TokenType token); struct Context { std::size_t tokenCount; std::size_t tokenIndex = 0; ShaderAst::ModulePtr module; const Token* tokens; bool parsingImportedModule = false; }; Context* m_context; }; inline ShaderAst::ModulePtr Parse(const std::string_view& source, const std::string& filePath = std::string{}); inline ShaderAst::ModulePtr Parse(const std::vector& tokens); NAZARA_SHADER_API ShaderAst::ModulePtr ParseFromFile(const std::filesystem::path& sourcePath); } #include #endif // NAZARA_SHADER_SHADERLANGPARSER_HPP