1 /* 2 * Copyright 2016 Google Inc. 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 <vector> 12 #include <memory> 13 #include <unordered_map> 14 #include <unordered_set> 15 #include "src/sksl/SkSLASTFile.h" 16 #include "src/sksl/SkSLASTNode.h" 17 #include "src/sksl/SkSLErrorReporter.h" 18 #include "src/sksl/SkSLLexer.h" 19 #include "src/sksl/ir/SkSLLayout.h" 20 21 struct yy_buffer_state; 22 #define YY_TYPEDEF_YY_BUFFER_STATE 23 typedef struct yy_buffer_state *YY_BUFFER_STATE; 24 25 namespace SkSL { 26 27 struct Modifiers; 28 class SymbolTable; 29 30 /** 31 * Consumes .sksl text and produces an abstract syntax tree describing the contents. 32 */ 33 class Parser { 34 public: 35 enum class LayoutToken { 36 LOCATION, 37 OFFSET, 38 BINDING, 39 INDEX, 40 SET, 41 BUILTIN, 42 INPUT_ATTACHMENT_INDEX, 43 ORIGIN_UPPER_LEFT, 44 OVERRIDE_COVERAGE, 45 BLEND_SUPPORT_ALL_EQUATIONS, 46 BLEND_SUPPORT_MULTIPLY, 47 BLEND_SUPPORT_SCREEN, 48 BLEND_SUPPORT_OVERLAY, 49 BLEND_SUPPORT_DARKEN, 50 BLEND_SUPPORT_LIGHTEN, 51 BLEND_SUPPORT_COLORDODGE, 52 BLEND_SUPPORT_COLORBURN, 53 BLEND_SUPPORT_HARDLIGHT, 54 BLEND_SUPPORT_SOFTLIGHT, 55 BLEND_SUPPORT_DIFFERENCE, 56 BLEND_SUPPORT_EXCLUSION, 57 BLEND_SUPPORT_HSL_HUE, 58 BLEND_SUPPORT_HSL_SATURATION, 59 BLEND_SUPPORT_HSL_COLOR, 60 BLEND_SUPPORT_HSL_LUMINOSITY, 61 PUSH_CONSTANT, 62 POINTS, 63 LINES, 64 LINE_STRIP, 65 LINES_ADJACENCY, 66 TRIANGLES, 67 TRIANGLE_STRIP, 68 TRIANGLES_ADJACENCY, 69 MAX_VERTICES, 70 INVOCATIONS, 71 WHEN, 72 KEY, 73 TRACKED, 74 CTYPE, 75 SKPMCOLOR4F, 76 SKVECTOR4, 77 SKRECT, 78 SKIRECT, 79 SKPMCOLOR, 80 SKMATRIX44, 81 BOOL, 82 INT, 83 FLOAT, 84 }; 85 86 Parser(const char* text, size_t length, SymbolTable& types, ErrorReporter& errors); 87 88 /** 89 * Consumes a complete .sksl file and returns the parse tree. Errors are reported via the 90 * ErrorReporter; the return value may contain some declarations even when errors have occurred. 91 */ 92 std::unique_ptr<ASTFile> file(); 93 94 StringFragment text(Token token); 95 96 Position position(Token token); 97 98 private: 99 static void InitLayoutMap(); 100 101 /** 102 * Return the next token, including whitespace tokens, from the parse stream. 103 */ 104 Token nextRawToken(); 105 106 /** 107 * Return the next non-whitespace token from the parse stream. 108 */ 109 Token nextToken(); 110 111 /** 112 * Push a token back onto the parse stream, so that it is the next one read. Only a single level 113 * of pushback is supported (that is, it is an error to call pushback() twice in a row without 114 * an intervening nextToken()). 115 */ 116 void pushback(Token t); 117 118 /** 119 * Returns the next non-whitespace token without consuming it from the stream. 120 */ 121 Token peek(); 122 123 /** 124 * Checks to see if the next token is of the specified type. If so, stores it in result (if 125 * result is non-null) and returns true. Otherwise, pushes it back and returns false. 126 */ 127 bool checkNext(Token::Kind kind, Token* result = nullptr); 128 129 /** 130 * Reads the next non-whitespace token and generates an error if it is not the expected type. 131 * The 'expected' string is part of the error message, which reads: 132 * 133 * "expected <expected>, but found '<actual text>'" 134 * 135 * If 'result' is non-null, it is set to point to the token that was read. 136 * Returns true if the read token was as expected, false otherwise. 137 */ 138 bool expect(Token::Kind kind, const char* expected, Token* result = nullptr); 139 bool expect(Token::Kind kind, String expected, Token* result = nullptr); 140 141 void error(Token token, String msg); 142 void error(int offset, String msg); 143 /** 144 * Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will 145 * always return true. 146 */ 147 bool isType(StringFragment name); 148 149 // The pointer to the node may be invalidated by modifying the fNodes vector getNode(ASTNode::ID id)150 ASTNode& getNode(ASTNode::ID id) { 151 SkASSERT(id.fValue >= 0 && id.fValue < (int) fFile->fNodes.size()); 152 return fFile->fNodes[id.fValue]; 153 } 154 155 // these functions parse individual grammar rules from the current parse position; you probably 156 // don't need to call any of these outside of the parser. The function declarations in the .cpp 157 // file have comments describing the grammar rules. 158 159 ASTNode::ID precision(); 160 161 ASTNode::ID directive(); 162 163 ASTNode::ID section(); 164 165 ASTNode::ID enumDeclaration(); 166 167 ASTNode::ID declaration(); 168 169 ASTNode::ID varDeclarations(); 170 171 ASTNode::ID structDeclaration(); 172 173 ASTNode::ID structVarDeclaration(Modifiers modifiers); 174 175 ASTNode::ID varDeclarationEnd(Modifiers modifiers, ASTNode::ID type, StringFragment name); 176 177 ASTNode::ID parameter(); 178 179 int layoutInt(); 180 181 StringFragment layoutIdentifier(); 182 183 StringFragment layoutCode(); 184 185 Layout::Key layoutKey(); 186 187 Layout::CType layoutCType(); 188 189 Layout layout(); 190 191 Modifiers modifiers(); 192 193 Modifiers modifiersWithDefaults(int defaultFlags); 194 195 ASTNode::ID statement(); 196 197 ASTNode::ID type(); 198 199 ASTNode::ID interfaceBlock(Modifiers mods); 200 201 ASTNode::ID ifStatement(); 202 203 ASTNode::ID doStatement(); 204 205 ASTNode::ID whileStatement(); 206 207 ASTNode::ID forStatement(); 208 209 ASTNode::ID switchCase(); 210 211 ASTNode::ID switchStatement(); 212 213 ASTNode::ID returnStatement(); 214 215 ASTNode::ID breakStatement(); 216 217 ASTNode::ID continueStatement(); 218 219 ASTNode::ID discardStatement(); 220 221 ASTNode::ID block(); 222 223 ASTNode::ID expressionStatement(); 224 225 ASTNode::ID expression(); 226 227 ASTNode::ID assignmentExpression(); 228 229 ASTNode::ID ternaryExpression(); 230 231 ASTNode::ID logicalOrExpression(); 232 233 ASTNode::ID logicalXorExpression(); 234 235 ASTNode::ID logicalAndExpression(); 236 237 ASTNode::ID bitwiseOrExpression(); 238 239 ASTNode::ID bitwiseXorExpression(); 240 241 ASTNode::ID bitwiseAndExpression(); 242 243 ASTNode::ID equalityExpression(); 244 245 ASTNode::ID relationalExpression(); 246 247 ASTNode::ID shiftExpression(); 248 249 ASTNode::ID additiveExpression(); 250 251 ASTNode::ID multiplicativeExpression(); 252 253 ASTNode::ID unaryExpression(); 254 255 ASTNode::ID postfixExpression(); 256 257 ASTNode::ID suffix(ASTNode::ID base); 258 259 ASTNode::ID term(); 260 261 bool intLiteral(SKSL_INT* dest); 262 263 bool floatLiteral(SKSL_FLOAT* dest); 264 265 bool boolLiteral(bool* dest); 266 267 bool identifier(StringFragment* dest); 268 269 static std::unordered_map<String, LayoutToken>* layoutTokens; 270 271 const char* fText; 272 Lexer fLexer; 273 YY_BUFFER_STATE fBuffer; 274 // current parse depth, used to enforce a recursion limit to try to keep us from overflowing the 275 // stack on pathological inputs 276 int fDepth = 0; 277 Token fPushback; 278 SymbolTable& fTypes; 279 ErrorReporter& fErrors; 280 281 std::unique_ptr<ASTFile> fFile; 282 283 friend class AutoDepth; 284 friend class HCodeGenerator; 285 }; 286 287 } // namespace 288 289 #endif 290