blob: 9f69ac5843003d9634ce2125d8827a3185344646 [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>
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/sksl/SkSLErrorReporter.h"
16#include "src/sksl/SkSLLexer.h"
17#include "src/sksl/ir/SkSLLayout.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070018
19struct yy_buffer_state;
20#define YY_TYPEDEF_YY_BUFFER_STATE
21typedef struct yy_buffer_state *YY_BUFFER_STATE;
22
23namespace SkSL {
24
25struct ASTBlock;
26struct ASTBreakStatement;
27struct ASTContinueStatement;
28struct ASTDeclaration;
29struct ASTDiscardStatement;
30struct ASTDoStatement;
31struct ASTExpression;
32struct ASTExpressionStatement;
33struct ASTForStatement;
34struct ASTIfStatement;
35struct ASTInterfaceBlock;
ethannicholasb3058bd2016-07-01 08:22:01 -070036struct ASTParameter;
ethannicholas5961bc92016-10-12 06:39:56 -070037struct ASTPrecision;
ethannicholasb3058bd2016-07-01 08:22:01 -070038struct ASTReturnStatement;
39struct ASTStatement;
40struct ASTSuffix;
Ethan Nicholasaf197692017-02-27 13:26:45 -050041struct ASTSwitchCase;
42struct ASTSwitchStatement;
ethannicholasb3058bd2016-07-01 08:22:01 -070043struct ASTType;
44struct ASTWhileStatement;
ethannicholas14fe8cc2016-09-07 13:37:16 -070045struct ASTVarDeclarations;
Ethan Nicholas11d53972016-11-28 11:23:23 -050046struct Modifiers;
ethannicholasb3058bd2016-07-01 08:22:01 -070047class SymbolTable;
48
49/**
50 * Consumes .sksl text and produces an abstract syntax tree describing the contents.
51 */
52class Parser {
53public:
Ethan Nicholasb93af7e2018-07-24 11:28:52 -040054 enum class LayoutToken {
55 LOCATION,
56 OFFSET,
57 BINDING,
58 INDEX,
59 SET,
60 BUILTIN,
61 INPUT_ATTACHMENT_INDEX,
62 ORIGIN_UPPER_LEFT,
63 OVERRIDE_COVERAGE,
64 BLEND_SUPPORT_ALL_EQUATIONS,
65 BLEND_SUPPORT_MULTIPLY,
66 BLEND_SUPPORT_SCREEN,
67 BLEND_SUPPORT_OVERLAY,
68 BLEND_SUPPORT_DARKEN,
69 BLEND_SUPPORT_LIGHTEN,
70 BLEND_SUPPORT_COLORDODGE,
71 BLEND_SUPPORT_COLORBURN,
72 BLEND_SUPPORT_HARDLIGHT,
73 BLEND_SUPPORT_SOFTLIGHT,
74 BLEND_SUPPORT_DIFFERENCE,
75 BLEND_SUPPORT_EXCLUSION,
76 BLEND_SUPPORT_HSL_HUE,
77 BLEND_SUPPORT_HSL_SATURATION,
78 BLEND_SUPPORT_HSL_COLOR,
79 BLEND_SUPPORT_HSL_LUMINOSITY,
80 PUSH_CONSTANT,
81 POINTS,
82 LINES,
83 LINE_STRIP,
84 LINES_ADJACENCY,
85 TRIANGLES,
86 TRIANGLE_STRIP,
87 TRIANGLES_ADJACENCY,
88 MAX_VERTICES,
89 INVOCATIONS,
90 WHEN,
91 KEY,
Ethan Nicholas78aceb22018-08-31 16:13:58 -040092 TRACKED,
Michael Ludwiga4275592018-08-31 10:52:47 -040093 CTYPE,
Brian Osmanf28e55d2018-10-03 16:35:54 -040094 SKPMCOLOR4F,
Brian Salomoneca66b32019-06-01 11:18:15 -040095 SKVECTOR4,
Ethan Nicholas78aceb22018-08-31 16:13:58 -040096 SKRECT,
97 SKIRECT,
98 SKPMCOLOR,
Ethan Nicholas65e49ba2019-05-30 14:50:08 -040099 SKMATRIX44,
Ethan Nicholasc1c686b2019-04-02 17:30:23 -0400100 BOOL,
101 INT,
102 FLOAT,
Ethan Nicholasb93af7e2018-07-24 11:28:52 -0400103 };
104
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700105 Parser(const char* text, size_t length, SymbolTable& types, ErrorReporter& errors);
ethannicholasb3058bd2016-07-01 08:22:01 -0700106
107 /**
108 * Consumes a complete .sksl file and produces a list of declarations. Errors are reported via
109 * the ErrorReporter; the return value may contain some declarations even when errors have
110 * occurred.
111 */
112 std::vector<std::unique_ptr<ASTDeclaration>> file();
113
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700114 StringFragment text(Token token);
115
116 Position position(Token token);
117
ethannicholasb3058bd2016-07-01 08:22:01 -0700118private:
Ethan Nicholasb93af7e2018-07-24 11:28:52 -0400119 static void InitLayoutMap();
120
ethannicholasb3058bd2016-07-01 08:22:01 -0700121 /**
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700122 * Return the next token, including whitespace tokens, from the parse stream.
Ethan Nicholas762466e2017-06-29 10:03:38 -0400123 */
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700124 Token nextRawToken();
Ethan Nicholas762466e2017-06-29 10:03:38 -0400125
126 /**
127 * Return the next non-whitespace token from the parse stream.
ethannicholasb3058bd2016-07-01 08:22:01 -0700128 */
129 Token nextToken();
130
131 /**
132 * Push a token back onto the parse stream, so that it is the next one read. Only a single level
133 * of pushback is supported (that is, it is an error to call pushback() twice in a row without
134 * an intervening nextToken()).
135 */
136 void pushback(Token t);
137
138 /**
Ethan Nicholas762466e2017-06-29 10:03:38 -0400139 * Returns the next non-whitespace token without consuming it from the stream.
ethannicholasb3058bd2016-07-01 08:22:01 -0700140 */
141 Token peek();
142
143 /**
Ethan Nicholas0c9d13b2017-05-08 16:18:19 -0400144 * Checks to see if the next token is of the specified type. If so, stores it in result (if
145 * result is non-null) and returns true. Otherwise, pushes it back and returns false.
146 */
147 bool checkNext(Token::Kind kind, Token* result = nullptr);
148
149 /**
Ethan Nicholas762466e2017-06-29 10:03:38 -0400150 * Reads the next non-whitespace token and generates an error if it is not the expected type.
151 * The 'expected' string is part of the error message, which reads:
ethannicholasb3058bd2016-07-01 08:22:01 -0700152 *
153 * "expected <expected>, but found '<actual text>'"
154 *
155 * If 'result' is non-null, it is set to point to the token that was read.
156 * Returns true if the read token was as expected, false otherwise.
157 */
Ethan Nicholas9e1138d2016-11-21 10:39:35 -0500158 bool expect(Token::Kind kind, const char* expected, Token* result = nullptr);
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700159 bool expect(Token::Kind kind, String expected, Token* result = nullptr);
ethannicholasb3058bd2016-07-01 08:22:01 -0700160
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700161 void error(Token token, String msg);
162 void error(int offset, String msg);
ethannicholasb3058bd2016-07-01 08:22:01 -0700163 /**
164 * Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will
165 * always return true.
166 */
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700167 bool isType(StringFragment name);
ethannicholasb3058bd2016-07-01 08:22:01 -0700168
169 // these functions parse individual grammar rules from the current parse position; you probably
170 // don't need to call any of these outside of the parser. The function declarations in the .cpp
171 // file have comments describing the grammar rules.
172
ethannicholas5961bc92016-10-12 06:39:56 -0700173 std::unique_ptr<ASTDeclaration> precision();
ethannicholasb3058bd2016-07-01 08:22:01 -0700174
175 std::unique_ptr<ASTDeclaration> directive();
176
Ethan Nicholas762466e2017-06-29 10:03:38 -0400177 std::unique_ptr<ASTDeclaration> section();
178
Ethan Nicholasaae47c82017-11-10 15:34:03 -0500179 std::unique_ptr<ASTDeclaration> enumDeclaration();
180
ethannicholasb3058bd2016-07-01 08:22:01 -0700181 std::unique_ptr<ASTDeclaration> declaration();
182
ethannicholas14fe8cc2016-09-07 13:37:16 -0700183 std::unique_ptr<ASTVarDeclarations> varDeclarations();
ethannicholasb3058bd2016-07-01 08:22:01 -0700184
185 std::unique_ptr<ASTType> structDeclaration();
186
Ethan Nicholas11d53972016-11-28 11:23:23 -0500187 std::unique_ptr<ASTVarDeclarations> structVarDeclaration(Modifiers modifiers);
ethannicholasb3058bd2016-07-01 08:22:01 -0700188
Ethan Nicholas11d53972016-11-28 11:23:23 -0500189 std::unique_ptr<ASTVarDeclarations> varDeclarationEnd(Modifiers modifiers,
190 std::unique_ptr<ASTType> type,
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700191 StringFragment name);
ethannicholasb3058bd2016-07-01 08:22:01 -0700192
193 std::unique_ptr<ASTParameter> parameter();
194
195 int layoutInt();
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400196
Ethan Nicholasd608c092017-10-26 09:30:08 -0400197 StringFragment layoutIdentifier();
198
Ethan Nicholas762466e2017-06-29 10:03:38 -0400199 String layoutCode();
200
201 Layout::Key layoutKey();
202
Ethan Nicholas78aceb22018-08-31 16:13:58 -0400203 Layout::CType layoutCType();
204
Ethan Nicholas11d53972016-11-28 11:23:23 -0500205 Layout layout();
ethannicholasb3058bd2016-07-01 08:22:01 -0700206
Ethan Nicholas11d53972016-11-28 11:23:23 -0500207 Modifiers modifiers();
ethannicholasb3058bd2016-07-01 08:22:01 -0700208
Ethan Nicholas11d53972016-11-28 11:23:23 -0500209 Modifiers modifiersWithDefaults(int defaultFlags);
ethannicholasb3058bd2016-07-01 08:22:01 -0700210
211 std::unique_ptr<ASTStatement> statement();
212
213 std::unique_ptr<ASTType> type();
214
Ethan Nicholas11d53972016-11-28 11:23:23 -0500215 std::unique_ptr<ASTDeclaration> interfaceBlock(Modifiers mods);
ethannicholasb3058bd2016-07-01 08:22:01 -0700216
217 std::unique_ptr<ASTIfStatement> ifStatement();
218
219 std::unique_ptr<ASTDoStatement> doStatement();
220
221 std::unique_ptr<ASTWhileStatement> whileStatement();
222
223 std::unique_ptr<ASTForStatement> forStatement();
224
Ethan Nicholasaf197692017-02-27 13:26:45 -0500225 std::unique_ptr<ASTSwitchCase> switchCase();
226
227 std::unique_ptr<ASTStatement> switchStatement();
228
ethannicholasb3058bd2016-07-01 08:22:01 -0700229 std::unique_ptr<ASTReturnStatement> returnStatement();
230
231 std::unique_ptr<ASTBreakStatement> breakStatement();
232
233 std::unique_ptr<ASTContinueStatement> continueStatement();
234
235 std::unique_ptr<ASTDiscardStatement> discardStatement();
236
237 std::unique_ptr<ASTBlock> block();
238
239 std::unique_ptr<ASTExpressionStatement> expressionStatement();
240
241 std::unique_ptr<ASTExpression> expression();
242
Ethan Nicholas4b330df2017-05-17 10:52:55 -0400243 std::unique_ptr<ASTExpression> commaExpression();
244
ethannicholasb3058bd2016-07-01 08:22:01 -0700245 std::unique_ptr<ASTExpression> assignmentExpression();
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400246
ethannicholasb3058bd2016-07-01 08:22:01 -0700247 std::unique_ptr<ASTExpression> ternaryExpression();
248
249 std::unique_ptr<ASTExpression> logicalOrExpression();
250
251 std::unique_ptr<ASTExpression> logicalXorExpression();
252
253 std::unique_ptr<ASTExpression> logicalAndExpression();
254
255 std::unique_ptr<ASTExpression> bitwiseOrExpression();
256
257 std::unique_ptr<ASTExpression> bitwiseXorExpression();
258
259 std::unique_ptr<ASTExpression> bitwiseAndExpression();
260
261 std::unique_ptr<ASTExpression> equalityExpression();
262
263 std::unique_ptr<ASTExpression> relationalExpression();
264
265 std::unique_ptr<ASTExpression> shiftExpression();
266
267 std::unique_ptr<ASTExpression> additiveExpression();
268
269 std::unique_ptr<ASTExpression> multiplicativeExpression();
270
271 std::unique_ptr<ASTExpression> unaryExpression();
272
273 std::unique_ptr<ASTExpression> postfixExpression();
274
275 std::unique_ptr<ASTSuffix> suffix();
276
277 std::unique_ptr<ASTExpression> term();
278
279 bool intLiteral(int64_t* dest);
280
281 bool floatLiteral(double* dest);
282
283 bool boolLiteral(bool* dest);
284
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700285 bool identifier(StringFragment* dest);
ethannicholasb3058bd2016-07-01 08:22:01 -0700286
Brian Salomon140f3da2018-08-23 13:51:27 +0000287 static std::unordered_map<String, LayoutToken>* layoutTokens;
Ethan Nicholasb93af7e2018-07-24 11:28:52 -0400288
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700289 const char* fText;
290 Lexer fLexer;
ethannicholasb3058bd2016-07-01 08:22:01 -0700291 YY_BUFFER_STATE fBuffer;
ethannicholascad64162016-10-27 10:54:02 -0700292 // current parse depth, used to enforce a recursion limit to try to keep us from overflowing the
293 // stack on pathological inputs
294 int fDepth = 0;
ethannicholasb3058bd2016-07-01 08:22:01 -0700295 Token fPushback;
296 SymbolTable& fTypes;
297 ErrorReporter& fErrors;
ethannicholascad64162016-10-27 10:54:02 -0700298
299 friend class AutoDepth;
Ethan Nicholas130fb3f2018-02-01 12:14:34 -0500300 friend class HCodeGenerator;
ethannicholasb3058bd2016-07-01 08:22:01 -0700301};
302
303} // namespace
304
305#endif