Shader: Fill SourceLocation info to AST when parsing

This commit is contained in:
SirLynix
2022-03-28 18:24:51 +02:00
committed by Jérôme Leclercq
parent 8429411755
commit 78f4751967
10 changed files with 339 additions and 173 deletions

View File

@@ -198,7 +198,7 @@ namespace Nz::ShaderBuilder
{
inline ShaderAst::WhileStatementPtr operator()(ShaderAst::ExpressionPtr condition, ShaderAst::StatementPtr body) const;
};
}
}
constexpr Impl::AccessIndex AccessIndex;
constexpr Impl::AccessMember AccessMember;

View File

@@ -315,6 +315,7 @@ namespace Nz::ShaderBuilder
inline ShaderAst::ExpressionStatementPtr Impl::ExpressionStatement::operator()(ShaderAst::ExpressionPtr expression) const
{
auto expressionStatementNode = std::make_unique<ShaderAst::ExpressionStatement>();
expressionStatementNode->sourceLocation = expression->sourceLocation;
expressionStatementNode->expression = std::move(expression);
return expressionStatementNode;
@@ -421,6 +422,7 @@ namespace Nz::ShaderBuilder
inline ShaderAst::ScopedStatementPtr Impl::Scoped::operator()(ShaderAst::StatementPtr statement) const
{
auto scopedNode = std::make_unique<ShaderAst::ScopedStatement>();
scopedNode->sourceLocation = statement->sourceLocation;
scopedNode->statement = std::move(statement);
return scopedNode;

View File

@@ -34,7 +34,7 @@ namespace Nz::ShaderLang
public:
inline Error(SourceLocation sourceLocation, ErrorCategory errorCategory, unsigned int errorType) noexcept;
Error(const Error&) = delete;
Error(Error&&) = delete;
Error(Error&&) noexcept = default;
~Error() = default;
inline ErrorCategory GetErrorCategory() const;
@@ -45,7 +45,7 @@ namespace Nz::ShaderLang
const char* what() const noexcept override;
Error& operator=(const Error&) = delete;
Error& operator=(Error&&) = delete;
Error& operator=(Error&&) noexcept = default;
protected:
virtual std::string BuildErrorMessage() const = 0;
@@ -82,7 +82,7 @@ namespace Nz::ShaderLang
};
#define NAZARA_SHADERLANG_NEWERRORTYPE(Prefix, BaseClass, ErrorType, ErrorName, ErrorString, ...) \
class Prefix ## ErrorName ## Error : public BaseClass \
class Prefix ## ErrorName ## Error final : public BaseClass \
{ \
public: \
template<typename... Args> Prefix ## ErrorName ## Error(SourceLocation sourceLocation, Args&&... args) : \

View File

@@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderLangSourceLocation.hpp>
#include <memory>
#include <stdexcept>
#include <string>
@@ -26,10 +27,8 @@ namespace Nz::ShaderLang
struct Token
{
unsigned int column;
unsigned int line;
SourceLocation location;
TokenType type;
std::shared_ptr<const std::string> file;
std::variant<double, long long, std::string> data;
};

View File

@@ -25,6 +25,13 @@ namespace Nz::ShaderLang
ShaderAst::ModulePtr Parse(const std::vector<Token>& tokens);
private:
struct Attribute
{
ShaderAst::AttributeType type;
ShaderAst::ExpressionPtr args;
SourceLocation sourceLocation;
};
// Flow control
const Token& Advance();
void Consume(std::size_t count = 1);
@@ -33,9 +40,9 @@ namespace Nz::ShaderLang
const Token& Expect(TokenType type);
const Token& Peek(std::size_t advance = 0);
std::vector<ShaderAst::ExprValue> ParseAttributes();
void ParseModuleStatement(std::vector<ShaderAst::ExprValue> attributes);
void ParseVariableDeclaration(std::string& name, ShaderAst::ExpressionValue<ShaderAst::ExpressionType>& type, ShaderAst::ExpressionPtr& initialValue);
std::vector<Attribute> ParseAttributes();
void ParseModuleStatement(std::vector<Attribute> attributes);
void ParseVariableDeclaration(std::string& name, ShaderAst::ExpressionValue<ShaderAst::ExpressionType>& type, ShaderAst::ExpressionPtr& initialValue, SourceLocation& sourceLocation);
ShaderAst::ExpressionPtr BuildIdentifierAccess(ShaderAst::ExpressionPtr lhs, ShaderAst::ExpressionPtr rhs);
ShaderAst::ExpressionPtr BuildIndexAccess(ShaderAst::ExpressionPtr lhs, ShaderAst::ExpressionPtr rhs);
@@ -46,27 +53,26 @@ namespace Nz::ShaderLang
ShaderAst::StatementPtr ParseBranchStatement();
ShaderAst::StatementPtr ParseConstStatement();
ShaderAst::StatementPtr ParseDiscardStatement();
ShaderAst::StatementPtr ParseExternalBlock(std::vector<ShaderAst::ExprValue> attributes = {});
ShaderAst::StatementPtr ParseForDeclaration(std::vector<ShaderAst::ExprValue> attributes = {});
std::vector<ShaderAst::StatementPtr> ParseFunctionBody();
ShaderAst::StatementPtr ParseFunctionDeclaration(std::vector<ShaderAst::ExprValue> attributes = {});
ShaderAst::StatementPtr ParseExternalBlock(std::vector<Attribute> attributes = {});
ShaderAst::StatementPtr ParseForDeclaration(std::vector<Attribute> attributes = {});
ShaderAst::StatementPtr ParseFunctionDeclaration(std::vector<Attribute> attributes = {});
ShaderAst::DeclareFunctionStatement::Parameter ParseFunctionParameter();
ShaderAst::StatementPtr ParseImportStatement();
ShaderAst::StatementPtr ParseOptionDeclaration();
ShaderAst::StatementPtr ParseReturnStatement();
ShaderAst::StatementPtr ParseRootStatement(std::vector<ShaderAst::ExprValue> attributes = {});
ShaderAst::StatementPtr ParseRootStatement(std::vector<Attribute> attributes = {});
ShaderAst::StatementPtr ParseSingleStatement();
ShaderAst::StatementPtr ParseStatement();
std::vector<ShaderAst::StatementPtr> ParseStatementList();
ShaderAst::StatementPtr ParseStructDeclaration(std::vector<ShaderAst::ExprValue> attributes = {});
std::vector<ShaderAst::StatementPtr> ParseStatementList(SourceLocation* sourceLocation);
ShaderAst::StatementPtr ParseStructDeclaration(std::vector<Attribute> attributes = {});
ShaderAst::StatementPtr ParseVariableDeclaration();
ShaderAst::StatementPtr ParseWhileStatement(std::vector<ShaderAst::ExprValue> attributes);
ShaderAst::StatementPtr ParseWhileStatement(std::vector<Attribute> attributes);
// Expressions
ShaderAst::ExpressionPtr ParseBinOpRhs(int exprPrecedence, ShaderAst::ExpressionPtr lhs);
ShaderAst::ExpressionPtr ParseConstSelectExpression();
ShaderAst::ExpressionPtr ParseExpression();
std::vector<ShaderAst::ExpressionPtr> ParseExpressionList(TokenType terminationToken);
std::vector<ShaderAst::ExpressionPtr> ParseExpressionList(TokenType terminationToken, SourceLocation* terminationLocation);
ShaderAst::ExpressionPtr ParseFloatingPointExpression();
ShaderAst::ExpressionPtr ParseIdentifier();
ShaderAst::ExpressionPtr ParseIntegerExpression();
@@ -75,8 +81,7 @@ namespace Nz::ShaderLang
ShaderAst::ExpressionPtr ParseStringExpression();
ShaderAst::ExpressionPtr ParseVariableAssignation();
ShaderAst::AttributeType ParseIdentifierAsAttributeType();
const std::string& ParseIdentifierAsName();
const std::string& ParseIdentifierAsName(SourceLocation* sourceLocation);
std::string ParseModuleName();
ShaderAst::ExpressionPtr ParseType();

View File

@@ -21,8 +21,13 @@ namespace Nz::ShaderLang
inline SourceLocation(unsigned int line, unsigned int startColumn, unsigned int endColumn, std::shared_ptr<const std::string> file);
inline SourceLocation(unsigned int startLine, unsigned int endLine, unsigned int startColumn, unsigned int endColumn, std::shared_ptr<const std::string> file);
inline void ExtendToLeft(const SourceLocation& leftLocation);
inline void ExtendToRight(const SourceLocation& rightLocation);
inline bool IsValid() const;
static inline SourceLocation BuildFromTo(const SourceLocation& leftSource, const SourceLocation& rightSource);
std::shared_ptr<const std::string> file; //< Since the same file will be used for every node, prevent holding X time the same path
UInt32 endColumn;
UInt32 endLine;

View File

@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/ShaderLangSourceLocation.hpp>
#include <cassert>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderLang
@@ -42,6 +43,40 @@ namespace Nz::ShaderLang
{
}
inline void SourceLocation::ExtendToLeft(const SourceLocation& leftLocation)
{
assert(file == leftLocation.file);
assert(leftLocation.startLine <= endLine);
startLine = leftLocation.startLine;
assert(leftLocation.startLine < endLine || leftLocation.startColumn <= endColumn);
startColumn = leftLocation.startColumn;
}
inline void SourceLocation::ExtendToRight(const SourceLocation& rightLocation)
{
assert(file == rightLocation.file);
assert(rightLocation.endLine >= startLine);
endLine = rightLocation.endLine;
assert(rightLocation.endLine > startLine || rightLocation.endColumn >= startColumn);
endColumn = endColumn;
}
inline SourceLocation SourceLocation::BuildFromTo(const SourceLocation& leftSource, const SourceLocation& rightSource)
{
assert(leftSource.file == rightSource.file);
assert(leftSource.startLine <= rightSource.endLine);
assert(leftSource.startLine < rightSource.endLine || leftSource.startColumn <= rightSource.endColumn);
SourceLocation sourceLoc;
sourceLoc.file = leftSource.file;
sourceLoc.startLine = leftSource.startLine;
sourceLoc.startColumn = leftSource.startColumn;
sourceLoc.endLine = rightSource.endLine;
sourceLoc.endColumn = rightSource.endColumn;
return sourceLoc;
}
inline bool SourceLocation::IsValid() const
{
return startLine != 0 && endLine != 0 && endColumn != 0 && startColumn != 0;