xref: /aosp_15_r20/external/skia/src/sksl/SkSLParser.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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