Flutter Engine
The Flutter Engine
SkSLParser.h
Go to the documentation of this file.
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
13#include "src/sksl/SkSLLexer.h"
19
20#include <cstdint>
21#include <memory>
22#include <string>
23#include <string_view>
24#include <vector>
25
26namespace SkSL {
27
28class Compiler;
29class ErrorReporter;
30class Expression;
31class FunctionDeclaration;
32struct Module;
33struct Program;
34class ProgramElement;
35enum class ProgramKind : int8_t;
36class Statement;
37class SymbolTable;
38class Type;
39class VarDeclaration;
40class Variable;
41
42/**
43 * Consumes .sksl text and converts it into an IR tree, encapsulated in a Program.
44 */
45class Parser {
46public:
49 ProgramKind kind,
50 std::unique_ptr<std::string> text);
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
61private:
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
180 bool allowUnsizedArrays() {
181 return ProgramConfig::IsCompute(fKind) || ProgramConfig::IsFragment(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,
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
static struct Initializer initializer
const char * fName
int count
Definition: FontMgrTest.cpp:50
SkPoint pos
int64_t SKSL_INT
Definition: SkSLDefines.h:16
float SKSL_FLOAT
Definition: SkSLDefines.h:17
OperatorKind Kind
Definition: SkSLOperator.h:81
Position position(Token token)
Definition: SkSLParser.cpp:380
std::string_view text(Token token)
Definition: SkSLParser.cpp:376
Parser(Compiler *compiler, const ProgramSettings &settings, ProgramKind kind, std::unique_ptr< std::string > text)
Definition: SkSLParser.cpp:218
std::unique_ptr< Program > programInheritingFrom(const Module *module)
Definition: SkSLParser.cpp:407
std::unique_ptr< Module > moduleInheritingFrom(const Module *parentModule)
Definition: SkSLParser.cpp:418
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
skia_private::STArray< 2, std::unique_ptr< Statement > > StatementArray
Definition: SkSLDefines.h:32
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
dest
Definition: zip.py:79
static bool IsVertex(ProgramKind kind)
static bool IsFragment(ProgramKind kind)
static bool IsCompute(ProgramKind kind)