blob: a9eaa4936a51ed9033806a833a5805f18716217d [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 */
Ethan Nicholas11d53972016-11-28 11:23:23 -05007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_PARSER
9#define SKSL_PARSER
10
ethannicholasb3058bd2016-07-01 08:22:01 -070011#include <vector>
12#include <memory>
Ethan Nicholas3614d9a2017-02-15 12:33:30 -050013#include <unordered_map>
ethannicholasb3058bd2016-07-01 08:22:01 -070014#include <unordered_set>
Ethan Nicholasfc994162019-06-06 10:04:27 -040015#include "src/sksl/SkSLASTFile.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/sksl/SkSLErrorReporter.h"
17#include "src/sksl/SkSLLexer.h"
Ethan Nicholasfc994162019-06-06 10:04:27 -040018#include "src/sksl/SkSLASTNode.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "src/sksl/ir/SkSLLayout.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070020
21struct yy_buffer_state;
22#define YY_TYPEDEF_YY_BUFFER_STATE
23typedef struct yy_buffer_state *YY_BUFFER_STATE;
24
25namespace SkSL {
26
Ethan Nicholas11d53972016-11-28 11:23:23 -050027struct Modifiers;
ethannicholasb3058bd2016-07-01 08:22:01 -070028class SymbolTable;
29
30/**
31 * Consumes .sksl text and produces an abstract syntax tree describing the contents.
32 */
33class Parser {
34public:
Ethan Nicholasb93af7e2018-07-24 11:28:52 -040035 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,
Ethan Nicholas78aceb22018-08-31 16:13:58 -040073 TRACKED,
Michael Ludwiga4275592018-08-31 10:52:47 -040074 CTYPE,
Brian Osmanf28e55d2018-10-03 16:35:54 -040075 SKPMCOLOR4F,
Brian Salomoneca66b32019-06-01 11:18:15 -040076 SKVECTOR4,
Ethan Nicholas78aceb22018-08-31 16:13:58 -040077 SKRECT,
78 SKIRECT,
79 SKPMCOLOR,
Ethan Nicholas65e49ba2019-05-30 14:50:08 -040080 SKMATRIX44,
Ethan Nicholasc1c686b2019-04-02 17:30:23 -040081 BOOL,
82 INT,
83 FLOAT,
Ethan Nicholasb93af7e2018-07-24 11:28:52 -040084 };
85
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070086 Parser(const char* text, size_t length, SymbolTable& types, ErrorReporter& errors);
ethannicholasb3058bd2016-07-01 08:22:01 -070087
88 /**
Ethan Nicholasfc994162019-06-06 10:04:27 -040089 * 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.
ethannicholasb3058bd2016-07-01 08:22:01 -070091 */
Ethan Nicholasfc994162019-06-06 10:04:27 -040092 std::unique_ptr<ASTFile> file();
ethannicholasb3058bd2016-07-01 08:22:01 -070093
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070094 StringFragment text(Token token);
95
96 Position position(Token token);
97
ethannicholasb3058bd2016-07-01 08:22:01 -070098private:
Ethan Nicholasb93af7e2018-07-24 11:28:52 -040099 static void InitLayoutMap();
100
ethannicholasb3058bd2016-07-01 08:22:01 -0700101 /**
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700102 * Return the next token, including whitespace tokens, from the parse stream.
Ethan Nicholas762466e2017-06-29 10:03:38 -0400103 */
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700104 Token nextRawToken();
Ethan Nicholas762466e2017-06-29 10:03:38 -0400105
106 /**
107 * Return the next non-whitespace token from the parse stream.
ethannicholasb3058bd2016-07-01 08:22:01 -0700108 */
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 /**
Ethan Nicholas762466e2017-06-29 10:03:38 -0400119 * Returns the next non-whitespace token without consuming it from the stream.
ethannicholasb3058bd2016-07-01 08:22:01 -0700120 */
121 Token peek();
122
123 /**
Ethan Nicholas0c9d13b2017-05-08 16:18:19 -0400124 * 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 /**
Ethan Nicholas762466e2017-06-29 10:03:38 -0400130 * 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:
ethannicholasb3058bd2016-07-01 08:22:01 -0700132 *
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 */
Ethan Nicholas9e1138d2016-11-21 10:39:35 -0500138 bool expect(Token::Kind kind, const char* expected, Token* result = nullptr);
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700139 bool expect(Token::Kind kind, String expected, Token* result = nullptr);
ethannicholasb3058bd2016-07-01 08:22:01 -0700140
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700141 void error(Token token, String msg);
142 void error(int offset, String msg);
ethannicholasb3058bd2016-07-01 08:22:01 -0700143 /**
144 * Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will
145 * always return true.
146 */
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700147 bool isType(StringFragment name);
ethannicholasb3058bd2016-07-01 08:22:01 -0700148
Ethan Nicholasfc994162019-06-06 10:04:27 -0400149 // The pointer to the node may be invalidated by modifying the fNodes vector
150 ASTNode& getNode(ASTNode::ID id) {
151 return fFile->fNodes[id.fValue];
152 }
153
ethannicholasb3058bd2016-07-01 08:22:01 -0700154 // these functions parse individual grammar rules from the current parse position; you probably
155 // don't need to call any of these outside of the parser. The function declarations in the .cpp
156 // file have comments describing the grammar rules.
157
Ethan Nicholasfc994162019-06-06 10:04:27 -0400158 ASTNode::ID precision();
ethannicholasb3058bd2016-07-01 08:22:01 -0700159
Ethan Nicholasfc994162019-06-06 10:04:27 -0400160 ASTNode::ID directive();
ethannicholasb3058bd2016-07-01 08:22:01 -0700161
Ethan Nicholasfc994162019-06-06 10:04:27 -0400162 ASTNode::ID section();
Ethan Nicholas762466e2017-06-29 10:03:38 -0400163
Ethan Nicholasfc994162019-06-06 10:04:27 -0400164 ASTNode::ID enumDeclaration();
Ethan Nicholasaae47c82017-11-10 15:34:03 -0500165
Ethan Nicholasfc994162019-06-06 10:04:27 -0400166 ASTNode::ID declaration();
ethannicholasb3058bd2016-07-01 08:22:01 -0700167
Ethan Nicholasfc994162019-06-06 10:04:27 -0400168 ASTNode::ID varDeclarations();
ethannicholasb3058bd2016-07-01 08:22:01 -0700169
Ethan Nicholasfc994162019-06-06 10:04:27 -0400170 ASTNode::ID structDeclaration();
ethannicholasb3058bd2016-07-01 08:22:01 -0700171
Ethan Nicholasfc994162019-06-06 10:04:27 -0400172 ASTNode::ID structVarDeclaration(Modifiers modifiers);
ethannicholasb3058bd2016-07-01 08:22:01 -0700173
Ethan Nicholasfc994162019-06-06 10:04:27 -0400174 ASTNode::ID varDeclarationEnd(Modifiers modifiers, ASTNode::ID type, StringFragment name);
ethannicholasb3058bd2016-07-01 08:22:01 -0700175
Ethan Nicholasfc994162019-06-06 10:04:27 -0400176 ASTNode::ID parameter();
ethannicholasb3058bd2016-07-01 08:22:01 -0700177
178 int layoutInt();
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400179
Ethan Nicholasd608c092017-10-26 09:30:08 -0400180 StringFragment layoutIdentifier();
181
Ethan Nicholasfc994162019-06-06 10:04:27 -0400182 StringFragment layoutCode();
Ethan Nicholas762466e2017-06-29 10:03:38 -0400183
184 Layout::Key layoutKey();
185
Ethan Nicholas78aceb22018-08-31 16:13:58 -0400186 Layout::CType layoutCType();
187
Ethan Nicholas11d53972016-11-28 11:23:23 -0500188 Layout layout();
ethannicholasb3058bd2016-07-01 08:22:01 -0700189
Ethan Nicholas11d53972016-11-28 11:23:23 -0500190 Modifiers modifiers();
ethannicholasb3058bd2016-07-01 08:22:01 -0700191
Ethan Nicholas11d53972016-11-28 11:23:23 -0500192 Modifiers modifiersWithDefaults(int defaultFlags);
ethannicholasb3058bd2016-07-01 08:22:01 -0700193
Ethan Nicholasfc994162019-06-06 10:04:27 -0400194 ASTNode::ID statement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700195
Ethan Nicholasfc994162019-06-06 10:04:27 -0400196 ASTNode::ID type();
ethannicholasb3058bd2016-07-01 08:22:01 -0700197
Ethan Nicholasfc994162019-06-06 10:04:27 -0400198 ASTNode::ID interfaceBlock(Modifiers mods);
ethannicholasb3058bd2016-07-01 08:22:01 -0700199
Ethan Nicholasfc994162019-06-06 10:04:27 -0400200 ASTNode::ID ifStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700201
Ethan Nicholasfc994162019-06-06 10:04:27 -0400202 ASTNode::ID doStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700203
Ethan Nicholasfc994162019-06-06 10:04:27 -0400204 ASTNode::ID whileStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700205
Ethan Nicholasfc994162019-06-06 10:04:27 -0400206 ASTNode::ID forStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700207
Ethan Nicholasfc994162019-06-06 10:04:27 -0400208 ASTNode::ID switchCase();
Ethan Nicholasaf197692017-02-27 13:26:45 -0500209
Ethan Nicholasfc994162019-06-06 10:04:27 -0400210 ASTNode::ID switchStatement();
Ethan Nicholasaf197692017-02-27 13:26:45 -0500211
Ethan Nicholasfc994162019-06-06 10:04:27 -0400212 ASTNode::ID returnStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700213
Ethan Nicholasfc994162019-06-06 10:04:27 -0400214 ASTNode::ID breakStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700215
Ethan Nicholasfc994162019-06-06 10:04:27 -0400216 ASTNode::ID continueStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700217
Ethan Nicholasfc994162019-06-06 10:04:27 -0400218 ASTNode::ID discardStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700219
Ethan Nicholasfc994162019-06-06 10:04:27 -0400220 ASTNode::ID block();
ethannicholasb3058bd2016-07-01 08:22:01 -0700221
Ethan Nicholasfc994162019-06-06 10:04:27 -0400222 ASTNode::ID expressionStatement();
ethannicholasb3058bd2016-07-01 08:22:01 -0700223
Ethan Nicholasfc994162019-06-06 10:04:27 -0400224 ASTNode::ID expression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700225
Ethan Nicholasfc994162019-06-06 10:04:27 -0400226 ASTNode::ID assignmentExpression();
Ethan Nicholas4b330df2017-05-17 10:52:55 -0400227
Ethan Nicholasfc994162019-06-06 10:04:27 -0400228 ASTNode::ID ternaryExpression();
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400229
Ethan Nicholasfc994162019-06-06 10:04:27 -0400230 ASTNode::ID logicalOrExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700231
Ethan Nicholasfc994162019-06-06 10:04:27 -0400232 ASTNode::ID logicalXorExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700233
Ethan Nicholasfc994162019-06-06 10:04:27 -0400234 ASTNode::ID logicalAndExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700235
Ethan Nicholasfc994162019-06-06 10:04:27 -0400236 ASTNode::ID bitwiseOrExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700237
Ethan Nicholasfc994162019-06-06 10:04:27 -0400238 ASTNode::ID bitwiseXorExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700239
Ethan Nicholasfc994162019-06-06 10:04:27 -0400240 ASTNode::ID bitwiseAndExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700241
Ethan Nicholasfc994162019-06-06 10:04:27 -0400242 ASTNode::ID equalityExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700243
Ethan Nicholasfc994162019-06-06 10:04:27 -0400244 ASTNode::ID relationalExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700245
Ethan Nicholasfc994162019-06-06 10:04:27 -0400246 ASTNode::ID shiftExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700247
Ethan Nicholasfc994162019-06-06 10:04:27 -0400248 ASTNode::ID additiveExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700249
Ethan Nicholasfc994162019-06-06 10:04:27 -0400250 ASTNode::ID multiplicativeExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700251
Ethan Nicholasfc994162019-06-06 10:04:27 -0400252 ASTNode::ID unaryExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700253
Ethan Nicholasfc994162019-06-06 10:04:27 -0400254 ASTNode::ID postfixExpression();
ethannicholasb3058bd2016-07-01 08:22:01 -0700255
Ethan Nicholasfc994162019-06-06 10:04:27 -0400256 ASTNode::ID suffix(ASTNode::ID base);
ethannicholasb3058bd2016-07-01 08:22:01 -0700257
Ethan Nicholasfc994162019-06-06 10:04:27 -0400258 ASTNode::ID term();
ethannicholasb3058bd2016-07-01 08:22:01 -0700259
Ethan Nicholasfc994162019-06-06 10:04:27 -0400260 bool intLiteral(SKSL_INT* dest);
ethannicholasb3058bd2016-07-01 08:22:01 -0700261
Ethan Nicholasfc994162019-06-06 10:04:27 -0400262 bool floatLiteral(SKSL_FLOAT* dest);
ethannicholasb3058bd2016-07-01 08:22:01 -0700263
264 bool boolLiteral(bool* dest);
265
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700266 bool identifier(StringFragment* dest);
ethannicholasb3058bd2016-07-01 08:22:01 -0700267
Brian Salomon140f3da2018-08-23 13:51:27 +0000268 static std::unordered_map<String, LayoutToken>* layoutTokens;
Ethan Nicholasb93af7e2018-07-24 11:28:52 -0400269
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700270 const char* fText;
271 Lexer fLexer;
ethannicholasb3058bd2016-07-01 08:22:01 -0700272 YY_BUFFER_STATE fBuffer;
ethannicholascad64162016-10-27 10:54:02 -0700273 // current parse depth, used to enforce a recursion limit to try to keep us from overflowing the
274 // stack on pathological inputs
275 int fDepth = 0;
ethannicholasb3058bd2016-07-01 08:22:01 -0700276 Token fPushback;
277 SymbolTable& fTypes;
278 ErrorReporter& fErrors;
ethannicholascad64162016-10-27 10:54:02 -0700279
Ethan Nicholasfc994162019-06-06 10:04:27 -0400280 std::unique_ptr<ASTFile> fFile;
281
ethannicholascad64162016-10-27 10:54:02 -0700282 friend class AutoDepth;
Ethan Nicholas130fb3f2018-02-01 12:14:34 -0500283 friend class HCodeGenerator;
ethannicholasb3058bd2016-07-01 08:22:01 -0700284};
285
286} // namespace
287
288#endif