1 /* 2 * Copyright 2021 Google LLC. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SKSL_PARSER 9 #define SKSL_PARSER 10 11 #include "include/core/SkTypes.h" 12 #include "src/sksl/SkSLDefines.h" 13 #include "src/sksl/SkSLLexer.h" 14 #include "src/sksl/SkSLOperator.h" 15 #include "src/sksl/SkSLPosition.h" 16 #include "src/sksl/SkSLProgramSettings.h" 17 #include "src/sksl/ir/SkSLLayout.h" 18 #include "src/sksl/ir/SkSLModifiers.h" 19 20 #include <cstdint> 21 #include <memory> 22 #include <string> 23 #include <string_view> 24 #include <vector> 25 26 namespace SkSL { 27 28 class Compiler; 29 class ErrorReporter; 30 class Expression; 31 class FunctionDeclaration; 32 struct Module; 33 struct Program; 34 class ProgramElement; 35 enum class ProgramKind : int8_t; 36 class Statement; 37 class SymbolTable; 38 class Type; 39 class VarDeclaration; 40 class Variable; 41 42 /** 43 * Consumes .sksl text and converts it into an IR tree, encapsulated in a Program. 44 */ 45 class Parser { 46 public: 47 Parser(Compiler* compiler, 48 const ProgramSettings& settings, 49 ProgramKind kind, 50 std::unique_ptr<std::string> text); 51 ~Parser(); 52 53 std::unique_ptr<Program> programInheritingFrom(const Module* module); 54 55 std::unique_ptr<Module> moduleInheritingFrom(const Module* parentModule); 56 57 std::string_view text(Token token); 58 59 Position position(Token token); 60 61 private: 62 class AutoDepth; 63 class AutoSymbolTable; 64 class Checkpoint; 65 66 /** 67 * Return the next token, including whitespace tokens, from the parse stream. 68 */ 69 Token nextRawToken(); 70 71 /** 72 * Return the next non-whitespace token from the parse stream. 73 */ 74 Token nextToken(); 75 76 /** 77 * Push a token back onto the parse stream, so that it is the next one read. Only a single level 78 * of pushback is supported (that is, it is an error to call pushback() twice in a row without 79 * an intervening nextToken()). 80 */ 81 void pushback(Token t); 82 83 /** 84 * Returns the next non-whitespace token without consuming it from the stream. 85 */ 86 Token peek(); 87 88 /** 89 * Checks to see if the next token is of the specified type. If so, stores it in result (if 90 * result is non-null) and returns true. Otherwise, pushes it back and returns false. 91 */ 92 bool checkNext(Token::Kind kind, Token* result = nullptr); 93 94 /** 95 * Behaves like checkNext(TK_IDENTIFIER), but also verifies that identifier is not a builtin 96 * type. If the token was actually a builtin type, false is returned (the next token is not 97 * considered to be an identifier). 98 */ 99 bool checkIdentifier(Token* result = nullptr); 100 101 /** 102 * Reads the next non-whitespace token and generates an error if it is not the expected type. 103 * The 'expected' string is part of the error message, which reads: 104 * 105 * "expected <expected>, but found '<actual text>'" 106 * 107 * If 'result' is non-null, it is set to point to the token that was read. 108 * Returns true if the read token was as expected, false otherwise. 109 */ 110 bool expect(Token::Kind kind, const char* expected, Token* result = nullptr); 111 bool expect(Token::Kind kind, std::string expected, Token* result = nullptr); 112 113 /** 114 * Behaves like expect(TK_IDENTIFIER), but also verifies that identifier is not a type. 115 * If the token was actually a type, generates an error message of the form: 116 * 117 * "expected an identifier, but found type 'float2'" 118 */ 119 bool expectIdentifier(Token* result); 120 121 /** If the next token is a newline, consumes it and returns true. If not, returns false. */ 122 bool expectNewline(); 123 124 void error(Token token, std::string_view msg); 125 void error(Position position, std::string_view msg); 126 127 // Returns the range from `start` to the current parse position. 128 Position rangeFrom(Position start); 129 Position rangeFrom(Token start); 130 131 // these functions parse individual grammar rules from the current parse position; you probably 132 // don't need to call any of these outside of the parser. The function declarations in the .cpp 133 // file have comments describing the grammar rules. 134 135 void declarations(); 136 137 /** 138 * Parses an expression representing an array size. Reports errors if the array size is not 139 * valid (out of bounds, not a literal integer). Returns true if an expression was 140 * successfully parsed, even if that array size is not actually valid. In the event of a true 141 * return, outResult always contains a valid array size (even if the parsed array size was not 142 * actually valid; invalid array sizes result in a 1 to avoid additional errors downstream). 143 */ 144 bool arraySize(SKSL_INT* outResult); 145 146 void directive(bool allowVersion); 147 148 void extensionDirective(Position start); 149 150 void versionDirective(Position start, bool allowVersion); 151 152 bool declaration(); 153 154 bool functionDeclarationEnd(Position start, 155 Modifiers& modifiers, 156 const Type* returnType, 157 const Token& name); 158 159 bool prototypeFunction(SkSL::FunctionDeclaration* decl); 160 161 bool defineFunction(SkSL::FunctionDeclaration* decl); 162 163 struct VarDeclarationsPrefix { 164 Position fPosition; 165 Modifiers fModifiers; 166 const Type* fType; 167 Token fName; 168 }; 169 170 bool varDeclarationsPrefix(VarDeclarationsPrefix* prefixData); 171 172 std::unique_ptr<Statement> varDeclarationsOrExpressionStatement(); 173 174 std::unique_ptr<Statement> varDeclarations(); 175 176 const Type* structDeclaration(); 177 178 void structVarDeclaration(Position start, const Modifiers& modifiers); 179 allowUnsizedArrays()180 bool allowUnsizedArrays() { 181 return ProgramConfig::IsCompute(fKind) || ProgramConfig::IsFragment(fKind) || 182 ProgramConfig::IsVertex(fKind); 183 } 184 185 const Type* arrayType(const Type* base, int count, Position pos); 186 187 const Type* unsizedArrayType(const Type* base, Position pos); 188 189 bool parseArrayDimensions(Position pos, const Type** type); 190 191 bool parseInitializer(Position pos, std::unique_ptr<Expression>* initializer); 192 193 void addGlobalVarDeclaration(std::unique_ptr<SkSL::VarDeclaration> decl); 194 195 void globalVarDeclarationEnd(Position position, const Modifiers& mods, 196 const Type* baseType, Token name); 197 198 std::unique_ptr<Statement> localVarDeclarationEnd(Position position, 199 const Modifiers& mods, 200 const Type* baseType, 201 Token name); 202 203 bool modifiersDeclarationEnd(const Modifiers& mods); 204 205 bool parameter(std::unique_ptr<SkSL::Variable>* outParam); 206 207 int layoutInt(); 208 209 std::string_view layoutIdentifier(); 210 211 SkSL::Layout layout(); 212 213 Modifiers modifiers(); 214 215 std::unique_ptr<Statement> statementOrNop(Position pos, std::unique_ptr<Statement> stmt); 216 217 std::unique_ptr<Statement> statement(bool bracesIntroduceNewScope = true); 218 219 const Type* findType(Position pos, Modifiers* modifiers, std::string_view name); 220 221 const Type* type(Modifiers* modifiers); 222 223 bool interfaceBlock(const Modifiers& mods); 224 225 std::unique_ptr<Statement> ifStatement(); 226 227 std::unique_ptr<Statement> doStatement(); 228 229 std::unique_ptr<Statement> whileStatement(); 230 231 std::unique_ptr<Statement> forStatement(); 232 233 bool switchCaseBody(ExpressionArray* values, 234 StatementArray* caseBlocks, 235 std::unique_ptr<Expression> value); 236 237 bool switchCase(ExpressionArray* values, StatementArray* caseBlocks); 238 239 std::unique_ptr<Statement> switchStatement(); 240 241 std::unique_ptr<Statement> returnStatement(); 242 243 std::unique_ptr<Statement> breakStatement(); 244 245 std::unique_ptr<Statement> continueStatement(); 246 247 std::unique_ptr<Statement> discardStatement(); 248 249 std::unique_ptr<Statement> block(bool introduceNewScope, 250 std::unique_ptr<SymbolTable>* adoptExistingSymbolTable); 251 252 std::unique_ptr<Statement> expressionStatement(); 253 254 using BinaryParseFn = std::unique_ptr<Expression> (Parser::*)(); 255 [[nodiscard]] bool operatorRight(AutoDepth& depth, 256 Operator::Kind op, 257 BinaryParseFn rightFn, 258 std::unique_ptr<Expression>& expr); 259 260 std::unique_ptr<Expression> poison(Position pos); 261 262 std::unique_ptr<Expression> expressionOrPoison(Position pos, std::unique_ptr<Expression> expr); 263 264 std::unique_ptr<Expression> expression(); 265 266 std::unique_ptr<Expression> assignmentExpression(); 267 268 std::unique_ptr<Expression> ternaryExpression(); 269 270 std::unique_ptr<Expression> logicalOrExpression(); 271 272 std::unique_ptr<Expression> logicalXorExpression(); 273 274 std::unique_ptr<Expression> logicalAndExpression(); 275 276 std::unique_ptr<Expression> bitwiseOrExpression(); 277 278 std::unique_ptr<Expression> bitwiseXorExpression(); 279 280 std::unique_ptr<Expression> bitwiseAndExpression(); 281 282 std::unique_ptr<Expression> equalityExpression(); 283 284 std::unique_ptr<Expression> relationalExpression(); 285 286 std::unique_ptr<Expression> shiftExpression(); 287 288 std::unique_ptr<Expression> additiveExpression(); 289 290 std::unique_ptr<Expression> multiplicativeExpression(); 291 292 std::unique_ptr<Expression> unaryExpression(); 293 294 std::unique_ptr<Expression> postfixExpression(); 295 296 std::unique_ptr<Expression> swizzle(Position pos, 297 std::unique_ptr<Expression> base, 298 std::string_view swizzleMask, 299 Position maskPos); 300 301 std::unique_ptr<Expression> call(Position pos, 302 std::unique_ptr<Expression> base, 303 ExpressionArray args); 304 305 std::unique_ptr<Expression> suffix(std::unique_ptr<Expression> base); 306 307 std::unique_ptr<Expression> term(); 308 309 bool intLiteral(SKSL_INT* dest); 310 311 bool floatLiteral(SKSL_FLOAT* dest); 312 313 bool boolLiteral(bool* dest); 314 315 bool identifier(std::string_view* dest); 316 317 SymbolTable* symbolTable(); 318 319 Compiler& fCompiler; 320 ProgramSettings fSettings; 321 ErrorReporter* fErrorReporter; 322 bool fEncounteredFatalError; 323 ProgramKind fKind; 324 std::unique_ptr<std::string> fText; 325 std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements; 326 Lexer fLexer; 327 // current parse depth, used to enforce a recursion limit to try to keep us from overflowing the 328 // stack on pathological inputs 329 int fDepth = 0; 330 Token fPushback; 331 }; 332 333 } // namespace SkSL 334 335 #endif 336