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