Blender V5.0
shader_parser.hh File Reference
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cstdint>
#include <functional>
#include <iostream>
#include <stack>
#include <string>
#include <vector>

Go to the source code of this file.

Classes

struct  blender::gpu::shader::parser::IndexRange
struct  blender::gpu::shader::parser::OffsetIndices
struct  blender::gpu::shader::parser::ParserData
struct  blender::gpu::shader::parser::Token
struct  blender::gpu::shader::parser::Scope
struct  blender::gpu::shader::parser::Parser

Namespaces

namespace  blender
namespace  blender::gpu
namespace  blender::gpu::shader
namespace  blender::gpu::shader::parser

Enumerations

enum  blender::gpu::shader::parser::TokenType : char {
  blender::gpu::shader::parser::Invalid = 0 , blender::gpu::shader::parser::Word = 'w' , blender::gpu::shader::parser::NewLine = '\n' , blender::gpu::shader::parser::Space = ' ' ,
  blender::gpu::shader::parser::Dot = '.' , blender::gpu::shader::parser::Hash = '#' , blender::gpu::shader::parser::Ampersand = '&' , blender::gpu::shader::parser::Number = '0' ,
  blender::gpu::shader::parser::String = '_' , blender::gpu::shader::parser::ParOpen = '(' , blender::gpu::shader::parser::ParClose = ')' , blender::gpu::shader::parser::BracketOpen = '{' ,
  blender::gpu::shader::parser::BracketClose = '}' , blender::gpu::shader::parser::SquareOpen = '[' , blender::gpu::shader::parser::SquareClose = ']' , blender::gpu::shader::parser::AngleOpen = '<' ,
  blender::gpu::shader::parser::AngleClose = '>' , blender::gpu::shader::parser::Assign = '=' , blender::gpu::shader::parser::SemiColon = ';' , blender::gpu::shader::parser::Question = '?' ,
  blender::gpu::shader::parser::Not = '!' , blender::gpu::shader::parser::Colon = ':' , blender::gpu::shader::parser::Comma = ',' , blender::gpu::shader::parser::Star = '*' ,
  blender::gpu::shader::parser::Plus = '+' , blender::gpu::shader::parser::Minus = '-' , blender::gpu::shader::parser::Divide = '/' , blender::gpu::shader::parser::Tilde = '~' ,
  blender::gpu::shader::parser::Backslash = '\\' , blender::gpu::shader::parser::Break = 'b' , blender::gpu::shader::parser::Const = 'c' , blender::gpu::shader::parser::Constexpr = 'C' ,
  blender::gpu::shader::parser::Decrement = 'D' , blender::gpu::shader::parser::Deref = 'D' , blender::gpu::shader::parser::Do = 'd' , blender::gpu::shader::parser::Equal = 'E' ,
  blender::gpu::shader::parser::NotEqual = 'e' , blender::gpu::shader::parser::For = 'f' , blender::gpu::shader::parser::While = 'F' , blender::gpu::shader::parser::GEqual = 'G' ,
  blender::gpu::shader::parser::Case = 'H' , blender::gpu::shader::parser::Switch = 'h' , blender::gpu::shader::parser::Else = 'I' , blender::gpu::shader::parser::If = 'i' ,
  blender::gpu::shader::parser::LEqual = 'L' , blender::gpu::shader::parser::Enum = 'M' , blender::gpu::shader::parser::Static = 'm' , blender::gpu::shader::parser::Namespace = 'n' ,
  blender::gpu::shader::parser::PreprocessorNewline = 'N' , blender::gpu::shader::parser::Continue = 'O' , blender::gpu::shader::parser::Increment = 'P' , blender::gpu::shader::parser::Return = 'r' ,
  blender::gpu::shader::parser::Class = 'S' , blender::gpu::shader::parser::Struct = 's' , blender::gpu::shader::parser::Template = 't' , blender::gpu::shader::parser::This = 'T' ,
  blender::gpu::shader::parser::Using = 'u' , blender::gpu::shader::parser::Private = 'v' , blender::gpu::shader::parser::Public = 'V'
}
enum class  blender::gpu::shader::parser::ScopeType : char {
  blender::gpu::shader::parser::Global = 'G' , blender::gpu::shader::parser::Namespace = 'N' , blender::gpu::shader::parser::Struct = 'S' , blender::gpu::shader::parser::Function = 'F' ,
  blender::gpu::shader::parser::LoopArgs = 'l' , blender::gpu::shader::parser::LoopBody = 'p' , blender::gpu::shader::parser::SwitchArg = 'w' , blender::gpu::shader::parser::SwitchBody = 'W' ,
  blender::gpu::shader::parser::FunctionArgs = 'f' , blender::gpu::shader::parser::FunctionCall = 'c' , blender::gpu::shader::parser::Template = 'T' , blender::gpu::shader::parser::TemplateArg = 't' ,
  blender::gpu::shader::parser::Subscript = 'A' , blender::gpu::shader::parser::Preprocessor = 'P' , blender::gpu::shader::parser::Assignment = 'a' , blender::gpu::shader::parser::Local = 'L' ,
  blender::gpu::shader::parser::FunctionArg = 'g' , blender::gpu::shader::parser::LoopArg = 'r'
}

Detailed Description

Very simple parsing of our shader file that are a subset of C++. It allows to traverse the semantic using tokens and scopes instead of trying to match string patterns throughout the whole input string.

The goal of this representation is to output code that doesn't modify the style of the input string and keep the same line numbers (to match compilation error with input source).

The Parser class contain a copy of the given string to apply string substitutions (called Mutation). It is usually faster to record all of them and apply them all at once after scanning through the whole semantic representation. In the rare case where mutation need to overlap (recursive processing), it is better to do them in passes until there is no mutation to do.

Token and Scope are read only interfaces to the data stored inside the ParserData. The data is stored as SoA (Structure of Arrays) for fast traversal. The types of token and scopes are defined as readable chars to easily create sequences of token type.

The Parser object needs to be fed a well formed source (without preprocessor directive, see below), otherwise a crash can occur. The Parser doesn't apply any preprocessor. All preprocessor directive are parsed as Preprocessor scope but they are not expanded.

By default, whitespaces are merged with the previous token. Only a handful of processing requires access to whitespaces as individual tokens.

Definition in file shader_parser.hh.