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 #include "stdio.h"
9 #include "SkSLParser.h"
10 #include "SkSLToken.h"
11
12 #define register
13 #include "disable_flex_warnings.h"
14 #include "lex.sksl.c"
15 static_assert(YY_FLEX_MAJOR_VERSION * 10000 + YY_FLEX_MINOR_VERSION * 100 +
16 YY_FLEX_SUBMINOR_VERSION >= 20601,
17 "we require Flex 2.6.1 or better for security reasons");
18 #undef register
19 #ifdef __clang__
20 #pragma clang diagnostic pop
21 #endif
22 #ifdef __GNUC__
23 #pragma GCC diagnostic pop
24 #endif
25 #ifdef _MSC_VER
26 #pragma warning(pop)
27 #endif
28
29 #include "lex.layout.h"
30 #include "ast/SkSLASTBinaryExpression.h"
31 #include "ast/SkSLASTBlock.h"
32 #include "ast/SkSLASTBoolLiteral.h"
33 #include "ast/SkSLASTBreakStatement.h"
34 #include "ast/SkSLASTCallSuffix.h"
35 #include "ast/SkSLASTContinueStatement.h"
36 #include "ast/SkSLASTDiscardStatement.h"
37 #include "ast/SkSLASTDoStatement.h"
38 #include "ast/SkSLASTExpression.h"
39 #include "ast/SkSLASTExpressionStatement.h"
40 #include "ast/SkSLASTExtension.h"
41 #include "ast/SkSLASTFieldSuffix.h"
42 #include "ast/SkSLASTFloatLiteral.h"
43 #include "ast/SkSLASTForStatement.h"
44 #include "ast/SkSLASTFunction.h"
45 #include "ast/SkSLASTIdentifier.h"
46 #include "ast/SkSLASTIfStatement.h"
47 #include "ast/SkSLASTIndexSuffix.h"
48 #include "ast/SkSLASTInterfaceBlock.h"
49 #include "ast/SkSLASTIntLiteral.h"
50 #include "ast/SkSLASTModifiersDeclaration.h"
51 #include "ast/SkSLASTParameter.h"
52 #include "ast/SkSLASTPrecision.h"
53 #include "ast/SkSLASTPrefixExpression.h"
54 #include "ast/SkSLASTReturnStatement.h"
55 #include "ast/SkSLASTSection.h"
56 #include "ast/SkSLASTStatement.h"
57 #include "ast/SkSLASTSuffixExpression.h"
58 #include "ast/SkSLASTSwitchCase.h"
59 #include "ast/SkSLASTSwitchStatement.h"
60 #include "ast/SkSLASTTernaryExpression.h"
61 #include "ast/SkSLASTType.h"
62 #include "ast/SkSLASTVarDeclaration.h"
63 #include "ast/SkSLASTVarDeclarationStatement.h"
64 #include "ast/SkSLASTWhileStatement.h"
65 #include "ir/SkSLSymbolTable.h"
66 #include "ir/SkSLModifiers.h"
67 #include "ir/SkSLType.h"
68
69 namespace SkSL {
70
71 #define MAX_PARSE_DEPTH 50
72
73 class AutoDepth {
74 public:
AutoDepth(Parser * p)75 AutoDepth(Parser* p)
76 : fParser(p) {
77 fParser->fDepth++;
78 }
79
~AutoDepth()80 ~AutoDepth() {
81 fParser->fDepth--;
82 }
83
checkValid()84 bool checkValid() {
85 if (fParser->fDepth > MAX_PARSE_DEPTH) {
86 fParser->error(fParser->peek().fPosition, String("exceeded max parse depth"));
87 return false;
88 }
89 return true;
90 }
91
92 private:
93 Parser* fParser;
94 };
95
Parser(String text,SymbolTable & types,ErrorReporter & errors)96 Parser::Parser(String text, SymbolTable& types, ErrorReporter& errors)
97 : fPushback(Position(-1, -1), Token::INVALID_TOKEN, String())
98 , fTypes(types)
99 , fErrors(errors) {
100 sksllex_init(&fScanner);
101 layoutlex_init(&fLayoutScanner);
102 fBuffer = sksl_scan_string(text.c_str(), fScanner);
103 skslset_lineno(1, fScanner);
104 }
105
~Parser()106 Parser::~Parser() {
107 sksl_delete_buffer(fBuffer, fScanner);
108 sksllex_destroy(fScanner);
109 layoutlex_destroy(fLayoutScanner);
110 }
111
112 /* (precision | directive | section | declaration)* END_OF_FILE */
file()113 std::vector<std::unique_ptr<ASTDeclaration>> Parser::file() {
114 std::vector<std::unique_ptr<ASTDeclaration>> result;
115 for (;;) {
116 switch (this->peek().fKind) {
117 case Token::END_OF_FILE:
118 return result;
119 case Token::PRECISION: {
120 std::unique_ptr<ASTDeclaration> precision = this->precision();
121 if (precision) {
122 result.push_back(std::move(precision));
123 }
124 break;
125 }
126 case Token::DIRECTIVE: {
127 std::unique_ptr<ASTDeclaration> decl = this->directive();
128 if (decl) {
129 result.push_back(std::move(decl));
130 }
131 break;
132 }
133 case Token::SECTION: {
134 std::unique_ptr<ASTDeclaration> section = this->section();
135 if (section) {
136 result.push_back(std::move(section));
137 }
138 break;
139 }
140 default: {
141 std::unique_ptr<ASTDeclaration> decl = this->declaration();
142 if (!decl) {
143 continue;
144 }
145 result.push_back(std::move(decl));
146 }
147 }
148 }
149 }
150
nextRawToken()151 Token Parser::nextRawToken() {
152 if (fPushback.fKind != Token::INVALID_TOKEN) {
153 Token result = fPushback;
154 fPushback.fKind = Token::INVALID_TOKEN;
155 fPushback.fText = "";
156 return result;
157 }
158 int token = sksllex(fScanner);
159 return Token(Position(skslget_lineno(fScanner), -1), (Token::Kind) token,
160 String(skslget_text(fScanner)));
161 }
162
nextToken()163 Token Parser::nextToken() {
164 Token token;
165 do {
166 token = this->nextRawToken();
167 } while (token.fKind == Token::WHITESPACE);
168 return token;
169 }
170
pushback(Token t)171 void Parser::pushback(Token t) {
172 ASSERT(fPushback.fKind == Token::INVALID_TOKEN);
173 fPushback = t;
174 }
175
peek()176 Token Parser::peek() {
177 fPushback = this->nextToken();
178 return fPushback;
179 }
180
checkNext(Token::Kind kind,Token * result)181 bool Parser::checkNext(Token::Kind kind, Token* result) {
182 Token next = this->nextToken();
183 if (next.fKind == kind) {
184 if (result) {
185 *result = next;
186 }
187 return true;
188 }
189 this->pushback(next);
190 return false;
191 }
192
expect(Token::Kind kind,const char * expected,Token * result)193 bool Parser::expect(Token::Kind kind, const char* expected, Token* result) {
194 return this->expect(kind, String(expected), result);
195 }
196
expect(Token::Kind kind,String expected,Token * result)197 bool Parser::expect(Token::Kind kind, String expected, Token* result) {
198 Token next = this->nextToken();
199 if (next.fKind == kind) {
200 if (result) {
201 *result = next;
202 }
203 return true;
204 } else {
205 if (next.fText.size()) {
206 this->error(next.fPosition, "expected " + expected + ", but found '" + next.fText +
207 "'");
208 } else {
209 this->error(next.fPosition, "parse error, recompile in debug mode for details");
210 }
211 return false;
212 }
213 }
214
error(Position p,const char * msg)215 void Parser::error(Position p, const char* msg) {
216 this->error(p, String(msg));
217 }
218
error(Position p,String msg)219 void Parser::error(Position p, String msg) {
220 fErrors.error(p, msg);
221 }
222
isType(String name)223 bool Parser::isType(String name) {
224 return nullptr != fTypes[name];
225 }
226
227 /* PRECISION (LOWP | MEDIUMP | HIGHP) type SEMICOLON */
precision()228 std::unique_ptr<ASTDeclaration> Parser::precision() {
229 if (!this->expect(Token::PRECISION, "'precision'")) {
230 return nullptr;
231 }
232 Modifiers::Flag result;
233 Token p = this->nextToken();
234 switch (p.fKind) {
235 case Token::LOWP:
236 result = Modifiers::kLowp_Flag;
237 break;
238 case Token::MEDIUMP:
239 result = Modifiers::kMediump_Flag;
240 break;
241 case Token::HIGHP:
242 result = Modifiers::kHighp_Flag;
243 break;
244 default:
245 this->error(p.fPosition, "expected 'lowp', 'mediump', or 'highp', but found '" +
246 p.fText + "'");
247 return nullptr;
248 }
249 // FIXME handle the type
250 if (!this->type()) {
251 return nullptr;
252 }
253 this->expect(Token::SEMICOLON, "';'");
254 return std::unique_ptr<ASTDeclaration>(new ASTPrecision(p.fPosition, result));
255 }
256
257 /* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? |
258 DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */
directive()259 std::unique_ptr<ASTDeclaration> Parser::directive() {
260 Token start;
261 if (!this->expect(Token::DIRECTIVE, "a directive", &start)) {
262 return nullptr;
263 }
264 if (start.fText == "#version") {
265 this->expect(Token::INT_LITERAL, "a version number");
266 Token next = this->peek();
267 if (next.fText == "es" || next.fText == "compatibility") {
268 this->nextToken();
269 }
270 // version is ignored for now; it will eventually become an error when we stop pretending
271 // to be GLSL
272 return nullptr;
273 } else if (start.fText == "#extension") {
274 Token name;
275 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
276 return nullptr;
277 }
278 if (!this->expect(Token::COLON, "':'")) {
279 return nullptr;
280 }
281 // FIXME: need to start paying attention to this token
282 if (!this->expect(Token::IDENTIFIER, "an identifier")) {
283 return nullptr;
284 }
285 return std::unique_ptr<ASTDeclaration>(new ASTExtension(start.fPosition,
286 std::move(name.fText)));
287 } else {
288 this->error(start.fPosition, "unsupported directive '" + start.fText + "'");
289 return nullptr;
290 }
291 }
292
293 /* SECTION LBRACE (LPAREN IDENTIFIER RPAREN)? <any sequence of tokens with balanced braces>
294 RBRACE */
section()295 std::unique_ptr<ASTDeclaration> Parser::section() {
296 Token start;
297 if (!this->expect(Token::SECTION, "a section token", &start)) {
298 return nullptr;
299 }
300 String argument;
301 if (this->peek().fKind == Token::LPAREN) {
302 this->nextToken();
303 Token argToken;
304 if (!this->expect(Token::IDENTIFIER, "an identifier", &argToken)) {
305 return nullptr;
306 }
307 argument = argToken.fText;
308 if (!this->expect(Token::RPAREN, "')'")) {
309 return nullptr;
310 }
311 }
312 if (!this->expect(Token::LBRACE, "'{'")) {
313 return nullptr;
314 }
315 String text;
316 int level = 1;
317 for (;;) {
318 Token next = this->nextRawToken();
319 switch (next.fKind) {
320 case Token::LBRACE:
321 ++level;
322 break;
323 case Token::RBRACE:
324 --level;
325 break;
326 case Token::END_OF_FILE:
327 this->error(start.fPosition, "reached end of file while parsing section");
328 return nullptr;
329 default:
330 break;
331 }
332 if (!level) {
333 break;
334 }
335 text += next.fText;
336 }
337 return std::unique_ptr<ASTDeclaration>(new ASTSection(start.fPosition,
338 String(start.fText.c_str() + 1),
339 argument,
340 text));
341 }
342
343 /* modifiers (structVarDeclaration | type IDENTIFIER ((LPAREN parameter
344 (COMMA parameter)* RPAREN (block | SEMICOLON)) | SEMICOLON) | interfaceBlock) */
declaration()345 std::unique_ptr<ASTDeclaration> Parser::declaration() {
346 Modifiers modifiers = this->modifiers();
347 Token lookahead = this->peek();
348 if (lookahead.fKind == Token::IDENTIFIER && !this->isType(lookahead.fText)) {
349 // we have an identifier that's not a type, could be the start of an interface block
350 return this->interfaceBlock(modifiers);
351 }
352 if (lookahead.fKind == Token::STRUCT) {
353 return this->structVarDeclaration(modifiers);
354 }
355 if (lookahead.fKind == Token::SEMICOLON) {
356 this->nextToken();
357 return std::unique_ptr<ASTDeclaration>(new ASTModifiersDeclaration(modifiers));
358 }
359 std::unique_ptr<ASTType> type(this->type());
360 if (!type) {
361 return nullptr;
362 }
363 if (type->fKind == ASTType::kStruct_Kind && this->checkNext(Token::SEMICOLON)) {
364 return nullptr;
365 }
366 Token name;
367 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
368 return nullptr;
369 }
370 if (this->checkNext(Token::LPAREN)) {
371 std::vector<std::unique_ptr<ASTParameter>> parameters;
372 while (this->peek().fKind != Token::RPAREN) {
373 if (parameters.size() > 0) {
374 if (!this->expect(Token::COMMA, "','")) {
375 return nullptr;
376 }
377 }
378 std::unique_ptr<ASTParameter> parameter = this->parameter();
379 if (!parameter) {
380 return nullptr;
381 }
382 parameters.push_back(std::move(parameter));
383 }
384 this->nextToken();
385 std::unique_ptr<ASTBlock> body;
386 if (!this->checkNext(Token::SEMICOLON)) {
387 body = this->block();
388 if (!body) {
389 return nullptr;
390 }
391 }
392 return std::unique_ptr<ASTDeclaration>(new ASTFunction(name.fPosition,
393 modifiers,
394 std::move(type),
395 std::move(name.fText),
396 std::move(parameters),
397 std::move(body)));
398 } else {
399 return this->varDeclarationEnd(modifiers, std::move(type), name.fText);
400 }
401 }
402
403 /* modifiers type IDENTIFIER varDeclarationEnd */
varDeclarations()404 std::unique_ptr<ASTVarDeclarations> Parser::varDeclarations() {
405 Modifiers modifiers = this->modifiers();
406 std::unique_ptr<ASTType> type(this->type());
407 if (!type) {
408 return nullptr;
409 }
410 Token name;
411 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
412 return nullptr;
413 }
414 return this->varDeclarationEnd(modifiers, std::move(type), std::move(name.fText));
415 }
416
417 /* STRUCT IDENTIFIER LBRACE varDeclaration* RBRACE */
structDeclaration()418 std::unique_ptr<ASTType> Parser::structDeclaration() {
419 if (!this->expect(Token::STRUCT, "'struct'")) {
420 return nullptr;
421 }
422 Token name;
423 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
424 return nullptr;
425 }
426 if (!this->expect(Token::LBRACE, "'{'")) {
427 return nullptr;
428 }
429 std::vector<Type::Field> fields;
430 while (this->peek().fKind != Token::RBRACE) {
431 std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
432 if (!decl) {
433 return nullptr;
434 }
435 for (const auto& var : decl->fVars) {
436 auto type = (const Type*) fTypes[decl->fType->fName];
437 for (int i = (int) var.fSizes.size() - 1; i >= 0; i--) {
438 if (!var.fSizes[i] || var.fSizes[i]->fKind != ASTExpression::kInt_Kind) {
439 this->error(decl->fPosition, "array size in struct field must be a constant");
440 return nullptr;
441 }
442 uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue;
443 String name = type->name() + "[" + to_string(columns) + "]";
444 type = new Type(name, Type::kArray_Kind, *type, (int) columns);
445 fTypes.takeOwnership((Type*) type);
446 }
447 fields.push_back(Type::Field(decl->fModifiers, var.fName, type));
448 if (var.fValue) {
449 this->error(decl->fPosition, "initializers are not permitted on struct fields");
450 }
451 }
452 }
453 if (!this->expect(Token::RBRACE, "'}'")) {
454 return nullptr;
455 }
456 fTypes.add(name.fText, std::unique_ptr<Type>(new Type(name.fPosition, name.fText, fields)));
457 return std::unique_ptr<ASTType>(new ASTType(name.fPosition, name.fText,
458 ASTType::kStruct_Kind, std::vector<int>()));
459 }
460
461 /* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */
structVarDeclaration(Modifiers modifiers)462 std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(Modifiers modifiers) {
463 std::unique_ptr<ASTType> type = this->structDeclaration();
464 if (!type) {
465 return nullptr;
466 }
467 Token name;
468 if (this->checkNext(Token::IDENTIFIER, &name)) {
469 std::unique_ptr<ASTVarDeclarations> result = this->varDeclarationEnd(modifiers,
470 std::move(type),
471 std::move(name.fText));
472 if (result) {
473 for (const auto& var : result->fVars) {
474 if (var.fValue) {
475 this->error(var.fValue->fPosition,
476 "struct variables cannot be initialized");
477 }
478 }
479 }
480 return result;
481 }
482 this->expect(Token::SEMICOLON, "';'");
483 return nullptr;
484 }
485
486 /* (LBRACKET expression? RBRACKET)* (EQ assignmentExpression)? (COMMA IDENTIFER
487 (LBRACKET expression? RBRACKET)* (EQ assignmentExpression)?)* SEMICOLON */
varDeclarationEnd(Modifiers mods,std::unique_ptr<ASTType> type,String name)488 std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(Modifiers mods,
489 std::unique_ptr<ASTType> type,
490 String name) {
491 std::vector<ASTVarDeclaration> vars;
492 std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
493 while (this->checkNext(Token::LBRACKET)) {
494 if (this->checkNext(Token::RBRACKET)) {
495 currentVarSizes.push_back(nullptr);
496 } else {
497 std::unique_ptr<ASTExpression> size(this->expression());
498 if (!size) {
499 return nullptr;
500 }
501 currentVarSizes.push_back(std::move(size));
502 if (!this->expect(Token::RBRACKET, "']'")) {
503 return nullptr;
504 }
505 }
506 }
507 std::unique_ptr<ASTExpression> value;
508 if (this->checkNext(Token::EQ)) {
509 value = this->assignmentExpression();
510 if (!value) {
511 return nullptr;
512 }
513 }
514 vars.emplace_back(std::move(name), std::move(currentVarSizes), std::move(value));
515 while (this->checkNext(Token::COMMA)) {
516 Token name;
517 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
518 return nullptr;
519 }
520 currentVarSizes.clear();
521 value.reset();
522 while (this->checkNext(Token::LBRACKET)) {
523 if (this->checkNext(Token::RBRACKET)) {
524 currentVarSizes.push_back(nullptr);
525 } else {
526 std::unique_ptr<ASTExpression> size(this->expression());
527 if (!size) {
528 return nullptr;
529 }
530 currentVarSizes.push_back(std::move(size));
531 if (!this->expect(Token::RBRACKET, "']'")) {
532 return nullptr;
533 }
534 }
535 }
536 if (this->checkNext(Token::EQ)) {
537 value = this->assignmentExpression();
538 if (!value) {
539 return nullptr;
540 }
541 }
542 vars.emplace_back(std::move(name.fText), std::move(currentVarSizes), std::move(value));
543 }
544 if (!this->expect(Token::SEMICOLON, "';'")) {
545 return nullptr;
546 }
547 return std::unique_ptr<ASTVarDeclarations>(new ASTVarDeclarations(std::move(mods),
548 std::move(type),
549 std::move(vars)));
550 }
551
552 /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */
parameter()553 std::unique_ptr<ASTParameter> Parser::parameter() {
554 Modifiers modifiers = this->modifiersWithDefaults(0);
555 std::unique_ptr<ASTType> type = this->type();
556 if (!type) {
557 return nullptr;
558 }
559 Token name;
560 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
561 return nullptr;
562 }
563 std::vector<int> sizes;
564 while (this->checkNext(Token::LBRACKET)) {
565 Token sizeToken;
566 if (!this->expect(Token::INT_LITERAL, "a positive integer", &sizeToken)) {
567 return nullptr;
568 }
569 sizes.push_back(SkSL::stoi(sizeToken.fText));
570 if (!this->expect(Token::RBRACKET, "']'")) {
571 return nullptr;
572 }
573 }
574 return std::unique_ptr<ASTParameter>(new ASTParameter(name.fPosition, modifiers,
575 std::move(type), name.fText,
576 std::move(sizes)));
577 }
578
579 /** (EQ INT_LITERAL)? */
layoutInt()580 int Parser::layoutInt() {
581 if (!this->expect(Token::EQ, "'='")) {
582 return -1;
583 }
584 Token resultToken;
585 if (this->expect(Token::INT_LITERAL, "a non-negative integer", &resultToken)) {
586 return SkSL::stoi(resultToken.fText);
587 }
588 return -1;
589 }
590
591 /** EQ <any sequence of tokens with balanced parentheses and no top-level comma> */
layoutCode()592 String Parser::layoutCode() {
593 if (!this->expect(Token::EQ, "'='")) {
594 return "";
595 }
596 Token start = this->peek();
597 String code;
598 int level = 1;
599 bool done = false;
600 while (!done) {
601 Token next = this->peek();
602 switch (next.fKind) {
603 case Token::LPAREN:
604 ++level;
605 break;
606 case Token::RPAREN:
607 --level;
608 break;
609 case Token::COMMA:
610 if (level == 1) {
611 done = true;
612 }
613 break;
614 case Token::END_OF_FILE:
615 this->error(start.fPosition, "reached end of file while parsing layout");
616 return nullptr;
617 default:
618 break;
619 }
620 if (!level) {
621 done = true;
622 }
623 if (!done) {
624 code += this->nextRawToken().fText;
625 }
626 }
627 return code;
628 }
629
630 /** (EQ IDENTIFIER('identity'))? */
layoutKey()631 Layout::Key Parser::layoutKey() {
632 if (this->peek().fKind == Token::EQ) {
633 this->expect(Token::EQ, "'='");
634 Token key;
635 if (this->expect(Token::IDENTIFIER, "an identifer", &key)) {
636 if (key.fText == "identity") {
637 return Layout::kIdentity_Key;
638 } else {
639 this->error(key.fPosition, "unsupported layout key");
640 }
641 }
642 }
643 return Layout::kKey_Key;
644 }
645
646 /* LAYOUT LPAREN IDENTIFIER (EQ INT_LITERAL)? (COMMA IDENTIFIER (EQ INT_LITERAL)?)* RPAREN */
layout()647 Layout Parser::layout() {
648 int location = -1;
649 int offset = -1;
650 int binding = -1;
651 int index = -1;
652 int set = -1;
653 int builtin = -1;
654 int inputAttachmentIndex = -1;
655 bool originUpperLeft = false;
656 bool overrideCoverage = false;
657 bool blendSupportAllEquations = false;
658 Layout::Format format = Layout::Format::kUnspecified;
659 bool pushConstant = false;
660 Layout::Primitive primitive = Layout::kUnspecified_Primitive;
661 int maxVertices = -1;
662 int invocations = -1;
663 String when;
664 Layout::Key key = Layout::kNo_Key;
665 if (this->checkNext(Token::LAYOUT)) {
666 if (!this->expect(Token::LPAREN, "'('")) {
667 return Layout(location, offset, binding, index, set, builtin, inputAttachmentIndex,
668 originUpperLeft, overrideCoverage, blendSupportAllEquations, format,
669 pushConstant, primitive, maxVertices, invocations, when, key);
670 }
671 for (;;) {
672 Token t = this->nextToken();
673 YY_BUFFER_STATE buffer;
674 buffer = layout_scan_string(t.fText.c_str(), fLayoutScanner);
675 int token = layoutlex(fLayoutScanner);
676 layout_delete_buffer(buffer, fLayoutScanner);
677 if (token != Token::INVALID_TOKEN) {
678 switch (token) {
679 case Token::LOCATION:
680 location = this->layoutInt();
681 break;
682 case Token::OFFSET:
683 offset = this->layoutInt();
684 break;
685 case Token::BINDING:
686 binding = this->layoutInt();
687 break;
688 case Token::INDEX:
689 index = this->layoutInt();
690 break;
691 case Token::SET:
692 set = this->layoutInt();
693 break;
694 case Token::BUILTIN:
695 builtin = this->layoutInt();
696 break;
697 case Token::INPUT_ATTACHMENT_INDEX:
698 inputAttachmentIndex = this->layoutInt();
699 break;
700 case Token::ORIGIN_UPPER_LEFT:
701 originUpperLeft = true;
702 break;
703 case Token::OVERRIDE_COVERAGE:
704 overrideCoverage = true;
705 break;
706 case Token::BLEND_SUPPORT_ALL_EQUATIONS:
707 blendSupportAllEquations = true;
708 break;
709 case Token::PUSH_CONSTANT:
710 pushConstant = true;
711 break;
712 case Token::POINTS:
713 primitive = Layout::kPoints_Primitive;
714 break;
715 case Token::LINES:
716 primitive = Layout::kLines_Primitive;
717 break;
718 case Token::LINE_STRIP:
719 primitive = Layout::kLineStrip_Primitive;
720 break;
721 case Token::LINES_ADJACENCY:
722 primitive = Layout::kLinesAdjacency_Primitive;
723 break;
724 case Token::TRIANGLES:
725 primitive = Layout::kTriangles_Primitive;
726 break;
727 case Token::TRIANGLE_STRIP:
728 primitive = Layout::kTriangleStrip_Primitive;
729 break;
730 case Token::TRIANGLES_ADJACENCY:
731 primitive = Layout::kTrianglesAdjacency_Primitive;
732 break;
733 case Token::MAX_VERTICES:
734 maxVertices = this->layoutInt();
735 break;
736 case Token::INVOCATIONS:
737 invocations = this->layoutInt();
738 break;
739 case Token::WHEN:
740 when = this->layoutCode();
741 break;
742 case Token::KEY:
743 key = this->layoutKey();
744 break;
745 }
746 } else if (Layout::ReadFormat(t.fText, &format)) {
747 // AST::ReadFormat stored the result in 'format'.
748 } else {
749 this->error(t.fPosition, ("'" + t.fText +
750 "' is not a valid layout qualifier").c_str());
751 }
752 if (this->checkNext(Token::RPAREN)) {
753 break;
754 }
755 if (!this->expect(Token::COMMA, "','")) {
756 break;
757 }
758 }
759 }
760 return Layout(location, offset, binding, index, set, builtin, inputAttachmentIndex,
761 originUpperLeft, overrideCoverage, blendSupportAllEquations, format,
762 pushConstant, primitive, maxVertices, invocations, when, key);
763 }
764
765 /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE |
766 READONLY | WRITEONLY | COHERENT | VOLATILE | RESTRICT | BUFFER)* */
modifiers()767 Modifiers Parser::modifiers() {
768 Layout layout = this->layout();
769 int flags = 0;
770 for (;;) {
771 // TODO: handle duplicate / incompatible flags
772 switch (peek().fKind) {
773 case Token::UNIFORM:
774 this->nextToken();
775 flags |= Modifiers::kUniform_Flag;
776 break;
777 case Token::CONST:
778 this->nextToken();
779 flags |= Modifiers::kConst_Flag;
780 break;
781 case Token::IN:
782 this->nextToken();
783 flags |= Modifiers::kIn_Flag;
784 break;
785 case Token::OUT:
786 this->nextToken();
787 flags |= Modifiers::kOut_Flag;
788 break;
789 case Token::INOUT:
790 this->nextToken();
791 flags |= Modifiers::kIn_Flag;
792 flags |= Modifiers::kOut_Flag;
793 break;
794 case Token::LOWP:
795 this->nextToken();
796 flags |= Modifiers::kLowp_Flag;
797 break;
798 case Token::MEDIUMP:
799 this->nextToken();
800 flags |= Modifiers::kMediump_Flag;
801 break;
802 case Token::HIGHP:
803 this->nextToken();
804 flags |= Modifiers::kHighp_Flag;
805 break;
806 case Token::FLAT:
807 this->nextToken();
808 flags |= Modifiers::kFlat_Flag;
809 break;
810 case Token::NOPERSPECTIVE:
811 this->nextToken();
812 flags |= Modifiers::kNoPerspective_Flag;
813 break;
814 case Token::READONLY:
815 this->nextToken();
816 flags |= Modifiers::kReadOnly_Flag;
817 break;
818 case Token::WRITEONLY:
819 this->nextToken();
820 flags |= Modifiers::kWriteOnly_Flag;
821 break;
822 case Token::COHERENT:
823 this->nextToken();
824 flags |= Modifiers::kCoherent_Flag;
825 break;
826 case Token::VOLATILE:
827 this->nextToken();
828 flags |= Modifiers::kVolatile_Flag;
829 break;
830 case Token::RESTRICT:
831 this->nextToken();
832 flags |= Modifiers::kRestrict_Flag;
833 break;
834 case Token::BUFFER:
835 this->nextToken();
836 flags |= Modifiers::kBuffer_Flag;
837 break;
838 case Token::HASSIDEEFFECTS:
839 this->nextToken();
840 flags |= Modifiers::kHasSideEffects_Flag;
841 break;
842 default:
843 return Modifiers(layout, flags);
844 }
845 }
846 }
847
modifiersWithDefaults(int defaultFlags)848 Modifiers Parser::modifiersWithDefaults(int defaultFlags) {
849 Modifiers result = this->modifiers();
850 if (!result.fFlags) {
851 return Modifiers(result.fLayout, defaultFlags);
852 }
853 return result;
854 }
855
856 /* ifStatement | forStatement | doStatement | whileStatement | block | expression */
statement()857 std::unique_ptr<ASTStatement> Parser::statement() {
858 Token start = this->peek();
859 switch (start.fKind) {
860 case Token::IF: // fall through
861 case Token::STATIC_IF:
862 return this->ifStatement();
863 case Token::FOR:
864 return this->forStatement();
865 case Token::DO:
866 return this->doStatement();
867 case Token::WHILE:
868 return this->whileStatement();
869 case Token::SWITCH: // fall through
870 case Token::STATIC_SWITCH:
871 return this->switchStatement();
872 case Token::RETURN:
873 return this->returnStatement();
874 case Token::BREAK:
875 return this->breakStatement();
876 case Token::CONTINUE:
877 return this->continueStatement();
878 case Token::DISCARD:
879 return this->discardStatement();
880 case Token::LBRACE:
881 return this->block();
882 case Token::SEMICOLON:
883 this->nextToken();
884 return std::unique_ptr<ASTStatement>(new ASTBlock(start.fPosition,
885 std::vector<std::unique_ptr<ASTStatement>>()));
886 case Token::CONST: // fall through
887 case Token::HIGHP: // fall through
888 case Token::MEDIUMP: // fall through
889 case Token::LOWP: {
890 auto decl = this->varDeclarations();
891 if (!decl) {
892 return nullptr;
893 }
894 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(std::move(decl)));
895 }
896 case Token::IDENTIFIER:
897 if (this->isType(start.fText)) {
898 auto decl = this->varDeclarations();
899 if (!decl) {
900 return nullptr;
901 }
902 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
903 std::move(decl)));
904 }
905 // fall through
906 default:
907 return this->expressionStatement();
908 }
909 }
910
911 /* IDENTIFIER(type) (LBRACKET intLiteral? RBRACKET)* */
type()912 std::unique_ptr<ASTType> Parser::type() {
913 Token type;
914 if (!this->expect(Token::IDENTIFIER, "a type", &type)) {
915 return nullptr;
916 }
917 if (!this->isType(type.fText)) {
918 this->error(type.fPosition, ("no type named '" + type.fText + "'").c_str());
919 return nullptr;
920 }
921 std::vector<int> sizes;
922 while (this->checkNext(Token::LBRACKET)) {
923 if (this->peek().fKind != Token::RBRACKET) {
924 int64_t i;
925 if (this->intLiteral(&i)) {
926 sizes.push_back(i);
927 } else {
928 return nullptr;
929 }
930 } else {
931 sizes.push_back(-1);
932 }
933 this->expect(Token::RBRACKET, "']'");
934 }
935 return std::unique_ptr<ASTType>(new ASTType(type.fPosition, std::move(type.fText),
936 ASTType::kIdentifier_Kind, sizes));
937 }
938
939 /* IDENTIFIER LBRACE varDeclaration* RBRACE (IDENTIFIER (LBRACKET expression? RBRACKET)*)? */
interfaceBlock(Modifiers mods)940 std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(Modifiers mods) {
941 Token name;
942 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
943 return nullptr;
944 }
945 if (peek().fKind != Token::LBRACE) {
946 // we only get into interfaceBlock if we found a top-level identifier which was not a type.
947 // 99% of the time, the user was not actually intending to create an interface block, so
948 // it's better to report it as an unknown type
949 this->error(name.fPosition, "no type named '" + name.fText + "'");
950 return nullptr;
951 }
952 this->nextToken();
953 std::vector<std::unique_ptr<ASTVarDeclarations>> decls;
954 while (this->peek().fKind != Token::RBRACE) {
955 std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
956 if (!decl) {
957 return nullptr;
958 }
959 decls.push_back(std::move(decl));
960 }
961 this->nextToken();
962 std::vector<std::unique_ptr<ASTExpression>> sizes;
963 Token instanceName;
964 if (this->checkNext(Token::IDENTIFIER, &instanceName)) {
965 while (this->checkNext(Token::LBRACKET)) {
966 if (this->peek().fKind != Token::RBRACKET) {
967 std::unique_ptr<ASTExpression> size = this->expression();
968 if (!size) {
969 return nullptr;
970 }
971 sizes.push_back(std::move(size));
972 } else {
973 sizes.push_back(nullptr);
974 }
975 this->expect(Token::RBRACKET, "']'");
976 }
977 }
978 this->expect(Token::SEMICOLON, "';'");
979 return std::unique_ptr<ASTDeclaration>(new ASTInterfaceBlock(name.fPosition, mods,
980 name.fText, std::move(decls),
981 std::move(instanceName.fText),
982 std::move(sizes)));
983 }
984
985 /* IF LPAREN expression RPAREN statement (ELSE statement)? */
ifStatement()986 std::unique_ptr<ASTIfStatement> Parser::ifStatement() {
987 Token start;
988 bool isStatic = this->checkNext(Token::STATIC_IF, &start);
989 if (!isStatic && !this->expect(Token::IF, "'if'", &start)) {
990 return nullptr;
991 }
992 if (!this->expect(Token::LPAREN, "'('")) {
993 return nullptr;
994 }
995 std::unique_ptr<ASTExpression> test(this->expression());
996 if (!test) {
997 return nullptr;
998 }
999 if (!this->expect(Token::RPAREN, "')'")) {
1000 return nullptr;
1001 }
1002 std::unique_ptr<ASTStatement> ifTrue(this->statement());
1003 if (!ifTrue) {
1004 return nullptr;
1005 }
1006 std::unique_ptr<ASTStatement> ifFalse;
1007 if (this->checkNext(Token::ELSE)) {
1008 ifFalse = this->statement();
1009 if (!ifFalse) {
1010 return nullptr;
1011 }
1012 }
1013 return std::unique_ptr<ASTIfStatement>(new ASTIfStatement(start.fPosition,
1014 isStatic,
1015 std::move(test),
1016 std::move(ifTrue),
1017 std::move(ifFalse)));
1018 }
1019
1020 /* DO statement WHILE LPAREN expression RPAREN SEMICOLON */
doStatement()1021 std::unique_ptr<ASTDoStatement> Parser::doStatement() {
1022 Token start;
1023 if (!this->expect(Token::DO, "'do'", &start)) {
1024 return nullptr;
1025 }
1026 std::unique_ptr<ASTStatement> statement(this->statement());
1027 if (!statement) {
1028 return nullptr;
1029 }
1030 if (!this->expect(Token::WHILE, "'while'")) {
1031 return nullptr;
1032 }
1033 if (!this->expect(Token::LPAREN, "'('")) {
1034 return nullptr;
1035 }
1036 std::unique_ptr<ASTExpression> test(this->expression());
1037 if (!test) {
1038 return nullptr;
1039 }
1040 if (!this->expect(Token::RPAREN, "')'")) {
1041 return nullptr;
1042 }
1043 if (!this->expect(Token::SEMICOLON, "';'")) {
1044 return nullptr;
1045 }
1046 return std::unique_ptr<ASTDoStatement>(new ASTDoStatement(start.fPosition,
1047 std::move(statement),
1048 std::move(test)));
1049 }
1050
1051 /* WHILE LPAREN expression RPAREN STATEMENT */
whileStatement()1052 std::unique_ptr<ASTWhileStatement> Parser::whileStatement() {
1053 Token start;
1054 if (!this->expect(Token::WHILE, "'while'", &start)) {
1055 return nullptr;
1056 }
1057 if (!this->expect(Token::LPAREN, "'('")) {
1058 return nullptr;
1059 }
1060 std::unique_ptr<ASTExpression> test(this->expression());
1061 if (!test) {
1062 return nullptr;
1063 }
1064 if (!this->expect(Token::RPAREN, "')'")) {
1065 return nullptr;
1066 }
1067 std::unique_ptr<ASTStatement> statement(this->statement());
1068 if (!statement) {
1069 return nullptr;
1070 }
1071 return std::unique_ptr<ASTWhileStatement>(new ASTWhileStatement(start.fPosition,
1072 std::move(test),
1073 std::move(statement)));
1074 }
1075
1076 /* CASE expression COLON statement* */
switchCase()1077 std::unique_ptr<ASTSwitchCase> Parser::switchCase() {
1078 Token start;
1079 if (!this->expect(Token::CASE, "'case'", &start)) {
1080 return nullptr;
1081 }
1082 std::unique_ptr<ASTExpression> value = this->expression();
1083 if (!value) {
1084 return nullptr;
1085 }
1086 if (!this->expect(Token::COLON, "':'")) {
1087 return nullptr;
1088 }
1089 std::vector<std::unique_ptr<ASTStatement>> statements;
1090 while (this->peek().fKind != Token::RBRACE && this->peek().fKind != Token::CASE &&
1091 this->peek().fKind != Token::DEFAULT) {
1092 std::unique_ptr<ASTStatement> s = this->statement();
1093 if (!s) {
1094 return nullptr;
1095 }
1096 statements.push_back(std::move(s));
1097 }
1098 return std::unique_ptr<ASTSwitchCase>(new ASTSwitchCase(start.fPosition, std::move(value),
1099 std::move(statements)));
1100 }
1101
1102 /* SWITCH LPAREN expression RPAREN LBRACE switchCase* (DEFAULT COLON statement*)? RBRACE */
switchStatement()1103 std::unique_ptr<ASTStatement> Parser::switchStatement() {
1104 Token start;
1105 bool isStatic = this->checkNext(Token::STATIC_SWITCH, &start);
1106 if (!isStatic && !this->expect(Token::SWITCH, "'switch'", &start)) {
1107 return nullptr;
1108 }
1109 if (!this->expect(Token::LPAREN, "'('")) {
1110 return nullptr;
1111 }
1112 std::unique_ptr<ASTExpression> value(this->expression());
1113 if (!value) {
1114 return nullptr;
1115 }
1116 if (!this->expect(Token::RPAREN, "')'")) {
1117 return nullptr;
1118 }
1119 if (!this->expect(Token::LBRACE, "'{'")) {
1120 return nullptr;
1121 }
1122 std::vector<std::unique_ptr<ASTSwitchCase>> cases;
1123 while (this->peek().fKind == Token::CASE) {
1124 std::unique_ptr<ASTSwitchCase> c = this->switchCase();
1125 if (!c) {
1126 return nullptr;
1127 }
1128 cases.push_back(std::move(c));
1129 }
1130 // Requiring default: to be last (in defiance of C and GLSL) was a deliberate decision. Other
1131 // parts of the compiler may rely upon this assumption.
1132 if (this->peek().fKind == Token::DEFAULT) {
1133 Token defaultStart;
1134 ASSERT_RESULT(this->expect(Token::DEFAULT, "'default'", &defaultStart));
1135 if (!this->expect(Token::COLON, "':'")) {
1136 return nullptr;
1137 }
1138 std::vector<std::unique_ptr<ASTStatement>> statements;
1139 while (this->peek().fKind != Token::RBRACE) {
1140 std::unique_ptr<ASTStatement> s = this->statement();
1141 if (!s) {
1142 return nullptr;
1143 }
1144 statements.push_back(std::move(s));
1145 }
1146 cases.emplace_back(new ASTSwitchCase(defaultStart.fPosition, nullptr,
1147 std::move(statements)));
1148 }
1149 if (!this->expect(Token::RBRACE, "'}'")) {
1150 return nullptr;
1151 }
1152 return std::unique_ptr<ASTStatement>(new ASTSwitchStatement(start.fPosition,
1153 isStatic,
1154 std::move(value),
1155 std::move(cases)));
1156 }
1157
1158 /* FOR LPAREN (declaration | expression)? SEMICOLON expression? SEMICOLON expression? RPAREN
1159 STATEMENT */
forStatement()1160 std::unique_ptr<ASTForStatement> Parser::forStatement() {
1161 Token start;
1162 if (!this->expect(Token::FOR, "'for'", &start)) {
1163 return nullptr;
1164 }
1165 if (!this->expect(Token::LPAREN, "'('")) {
1166 return nullptr;
1167 }
1168 std::unique_ptr<ASTStatement> initializer;
1169 Token nextToken = this->peek();
1170 switch (nextToken.fKind) {
1171 case Token::SEMICOLON:
1172 this->nextToken();
1173 break;
1174 case Token::CONST: {
1175 std::unique_ptr<ASTVarDeclarations> vd = this->varDeclarations();
1176 if (!vd) {
1177 return nullptr;
1178 }
1179 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
1180 std::move(vd)));
1181 break;
1182 }
1183 case Token::IDENTIFIER: {
1184 if (this->isType(nextToken.fText)) {
1185 std::unique_ptr<ASTVarDeclarations> vd = this->varDeclarations();
1186 if (!vd) {
1187 return nullptr;
1188 }
1189 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
1190 std::move(vd)));
1191 break;
1192 }
1193 } // fall through
1194 default:
1195 initializer = this->expressionStatement();
1196 }
1197 std::unique_ptr<ASTExpression> test;
1198 if (this->peek().fKind != Token::SEMICOLON) {
1199 test = this->expression();
1200 if (!test) {
1201 return nullptr;
1202 }
1203 }
1204 if (!this->expect(Token::SEMICOLON, "';'")) {
1205 return nullptr;
1206 }
1207 std::unique_ptr<ASTExpression> next;
1208 if (this->peek().fKind != Token::RPAREN) {
1209 next = this->expression();
1210 if (!next) {
1211 return nullptr;
1212 }
1213 }
1214 if (!this->expect(Token::RPAREN, "')'")) {
1215 return nullptr;
1216 }
1217 std::unique_ptr<ASTStatement> statement(this->statement());
1218 if (!statement) {
1219 return nullptr;
1220 }
1221 return std::unique_ptr<ASTForStatement>(new ASTForStatement(start.fPosition,
1222 std::move(initializer),
1223 std::move(test), std::move(next),
1224 std::move(statement)));
1225 }
1226
1227 /* RETURN expression? SEMICOLON */
returnStatement()1228 std::unique_ptr<ASTReturnStatement> Parser::returnStatement() {
1229 Token start;
1230 if (!this->expect(Token::RETURN, "'return'", &start)) {
1231 return nullptr;
1232 }
1233 std::unique_ptr<ASTExpression> expression;
1234 if (this->peek().fKind != Token::SEMICOLON) {
1235 expression = this->expression();
1236 if (!expression) {
1237 return nullptr;
1238 }
1239 }
1240 if (!this->expect(Token::SEMICOLON, "';'")) {
1241 return nullptr;
1242 }
1243 return std::unique_ptr<ASTReturnStatement>(new ASTReturnStatement(start.fPosition,
1244 std::move(expression)));
1245 }
1246
1247 /* BREAK SEMICOLON */
breakStatement()1248 std::unique_ptr<ASTBreakStatement> Parser::breakStatement() {
1249 Token start;
1250 if (!this->expect(Token::BREAK, "'break'", &start)) {
1251 return nullptr;
1252 }
1253 if (!this->expect(Token::SEMICOLON, "';'")) {
1254 return nullptr;
1255 }
1256 return std::unique_ptr<ASTBreakStatement>(new ASTBreakStatement(start.fPosition));
1257 }
1258
1259 /* CONTINUE SEMICOLON */
continueStatement()1260 std::unique_ptr<ASTContinueStatement> Parser::continueStatement() {
1261 Token start;
1262 if (!this->expect(Token::CONTINUE, "'continue'", &start)) {
1263 return nullptr;
1264 }
1265 if (!this->expect(Token::SEMICOLON, "';'")) {
1266 return nullptr;
1267 }
1268 return std::unique_ptr<ASTContinueStatement>(new ASTContinueStatement(start.fPosition));
1269 }
1270
1271 /* DISCARD SEMICOLON */
discardStatement()1272 std::unique_ptr<ASTDiscardStatement> Parser::discardStatement() {
1273 Token start;
1274 if (!this->expect(Token::DISCARD, "'continue'", &start)) {
1275 return nullptr;
1276 }
1277 if (!this->expect(Token::SEMICOLON, "';'")) {
1278 return nullptr;
1279 }
1280 return std::unique_ptr<ASTDiscardStatement>(new ASTDiscardStatement(start.fPosition));
1281 }
1282
1283 /* LBRACE statement* RBRACE */
block()1284 std::unique_ptr<ASTBlock> Parser::block() {
1285 AutoDepth depth(this);
1286 if (!depth.checkValid()) {
1287 return nullptr;
1288 }
1289 Token start;
1290 if (!this->expect(Token::LBRACE, "'{'", &start)) {
1291 return nullptr;
1292 }
1293 std::vector<std::unique_ptr<ASTStatement>> statements;
1294 for (;;) {
1295 switch (this->peek().fKind) {
1296 case Token::RBRACE:
1297 this->nextToken();
1298 return std::unique_ptr<ASTBlock>(new ASTBlock(start.fPosition,
1299 std::move(statements)));
1300 case Token::END_OF_FILE:
1301 this->error(this->peek().fPosition, "expected '}', but found end of file");
1302 return nullptr;
1303 default: {
1304 std::unique_ptr<ASTStatement> statement = this->statement();
1305 if (!statement) {
1306 return nullptr;
1307 }
1308 statements.push_back(std::move(statement));
1309 }
1310 }
1311 }
1312 }
1313
1314 /* expression SEMICOLON */
expressionStatement()1315 std::unique_ptr<ASTExpressionStatement> Parser::expressionStatement() {
1316 std::unique_ptr<ASTExpression> expr = this->expression();
1317 if (expr) {
1318 if (this->expect(Token::SEMICOLON, "';'")) {
1319 ASTExpressionStatement* result = new ASTExpressionStatement(std::move(expr));
1320 return std::unique_ptr<ASTExpressionStatement>(result);
1321 }
1322 }
1323 return nullptr;
1324 }
1325
1326 /* assignmentExpression */
expression()1327 std::unique_ptr<ASTExpression> Parser::expression() {
1328 AutoDepth depth(this);
1329 if (!depth.checkValid()) {
1330 return nullptr;
1331 }
1332 return this->commaExpression();
1333 }
1334
1335 /* assignmentExpression (COMMA assignmentExpression)* */
commaExpression()1336 std::unique_ptr<ASTExpression> Parser::commaExpression() {
1337 std::unique_ptr<ASTExpression> result = this->assignmentExpression();
1338 if (!result) {
1339 return nullptr;
1340 }
1341 Token t;
1342 while (this->checkNext(Token::COMMA, &t)) {
1343 std::unique_ptr<ASTExpression> right = this->commaExpression();
1344 if (!right) {
1345 return nullptr;
1346 }
1347 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1348 }
1349 return result;
1350 }
1351
1352 /* ternaryExpression ((EQEQ | STAREQ | SLASHEQ | PERCENTEQ | PLUSEQ | MINUSEQ | SHLEQ | SHREQ |
1353 BITWISEANDEQ | BITWISEXOREQ | BITWISEOREQ | LOGICALANDEQ | LOGICALXOREQ | LOGICALOREQ)
1354 assignmentExpression)*
1355 */
assignmentExpression()1356 std::unique_ptr<ASTExpression> Parser::assignmentExpression() {
1357 std::unique_ptr<ASTExpression> result = this->ternaryExpression();
1358 if (!result) {
1359 return nullptr;
1360 }
1361 for (;;) {
1362 switch (this->peek().fKind) {
1363 case Token::EQ: // fall through
1364 case Token::STAREQ: // fall through
1365 case Token::SLASHEQ: // fall through
1366 case Token::PERCENTEQ: // fall through
1367 case Token::PLUSEQ: // fall through
1368 case Token::MINUSEQ: // fall through
1369 case Token::SHLEQ: // fall through
1370 case Token::SHREQ: // fall through
1371 case Token::BITWISEANDEQ: // fall through
1372 case Token::BITWISEXOREQ: // fall through
1373 case Token::BITWISEOREQ: // fall through
1374 case Token::LOGICALANDEQ: // fall through
1375 case Token::LOGICALXOREQ: // fall through
1376 case Token::LOGICALOREQ: {
1377 Token t = this->nextToken();
1378 std::unique_ptr<ASTExpression> right = this->assignmentExpression();
1379 if (!right) {
1380 return nullptr;
1381 }
1382 result = std::unique_ptr<ASTExpression>(new ASTBinaryExpression(std::move(result),
1383 t,
1384 std::move(right)));
1385 }
1386 default:
1387 return result;
1388 }
1389 }
1390 }
1391
1392 /* logicalOrExpression ('?' expression ':' assignmentExpression)? */
ternaryExpression()1393 std::unique_ptr<ASTExpression> Parser::ternaryExpression() {
1394 std::unique_ptr<ASTExpression> result = this->logicalOrExpression();
1395 if (!result) {
1396 return nullptr;
1397 }
1398 if (this->checkNext(Token::QUESTION)) {
1399 std::unique_ptr<ASTExpression> trueExpr = this->expression();
1400 if (!trueExpr) {
1401 return nullptr;
1402 }
1403 if (this->expect(Token::COLON, "':'")) {
1404 std::unique_ptr<ASTExpression> falseExpr = this->assignmentExpression();
1405 return std::unique_ptr<ASTExpression>(new ASTTernaryExpression(std::move(result),
1406 std::move(trueExpr),
1407 std::move(falseExpr)));
1408 }
1409 return nullptr;
1410 }
1411 return result;
1412 }
1413
1414 /* logicalXorExpression (LOGICALOR logicalXorExpression)* */
logicalOrExpression()1415 std::unique_ptr<ASTExpression> Parser::logicalOrExpression() {
1416 std::unique_ptr<ASTExpression> result = this->logicalXorExpression();
1417 if (!result) {
1418 return nullptr;
1419 }
1420 Token t;
1421 while (this->checkNext(Token::LOGICALOR, &t)) {
1422 std::unique_ptr<ASTExpression> right = this->logicalXorExpression();
1423 if (!right) {
1424 return nullptr;
1425 }
1426 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1427 }
1428 return result;
1429 }
1430
1431 /* logicalAndExpression (LOGICALXOR logicalAndExpression)* */
logicalXorExpression()1432 std::unique_ptr<ASTExpression> Parser::logicalXorExpression() {
1433 std::unique_ptr<ASTExpression> result = this->logicalAndExpression();
1434 if (!result) {
1435 return nullptr;
1436 }
1437 Token t;
1438 while (this->checkNext(Token::LOGICALXOR, &t)) {
1439 std::unique_ptr<ASTExpression> right = this->logicalAndExpression();
1440 if (!right) {
1441 return nullptr;
1442 }
1443 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1444 }
1445 return result;
1446 }
1447
1448 /* bitwiseOrExpression (LOGICALAND bitwiseOrExpression)* */
logicalAndExpression()1449 std::unique_ptr<ASTExpression> Parser::logicalAndExpression() {
1450 std::unique_ptr<ASTExpression> result = this->bitwiseOrExpression();
1451 if (!result) {
1452 return nullptr;
1453 }
1454 Token t;
1455 while (this->checkNext(Token::LOGICALAND, &t)) {
1456 std::unique_ptr<ASTExpression> right = this->bitwiseOrExpression();
1457 if (!right) {
1458 return nullptr;
1459 }
1460 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1461 }
1462 return result;
1463 }
1464
1465 /* bitwiseXorExpression (BITWISEOR bitwiseXorExpression)* */
bitwiseOrExpression()1466 std::unique_ptr<ASTExpression> Parser::bitwiseOrExpression() {
1467 std::unique_ptr<ASTExpression> result = this->bitwiseXorExpression();
1468 if (!result) {
1469 return nullptr;
1470 }
1471 Token t;
1472 while (this->checkNext(Token::BITWISEOR, &t)) {
1473 std::unique_ptr<ASTExpression> right = this->bitwiseXorExpression();
1474 if (!right) {
1475 return nullptr;
1476 }
1477 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1478 }
1479 return result;
1480 }
1481
1482 /* bitwiseAndExpression (BITWISEXOR bitwiseAndExpression)* */
bitwiseXorExpression()1483 std::unique_ptr<ASTExpression> Parser::bitwiseXorExpression() {
1484 std::unique_ptr<ASTExpression> result = this->bitwiseAndExpression();
1485 if (!result) {
1486 return nullptr;
1487 }
1488 Token t;
1489 while (this->checkNext(Token::BITWISEXOR, &t)) {
1490 std::unique_ptr<ASTExpression> right = this->bitwiseAndExpression();
1491 if (!right) {
1492 return nullptr;
1493 }
1494 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1495 }
1496 return result;
1497 }
1498
1499 /* equalityExpression (BITWISEAND equalityExpression)* */
bitwiseAndExpression()1500 std::unique_ptr<ASTExpression> Parser::bitwiseAndExpression() {
1501 std::unique_ptr<ASTExpression> result = this->equalityExpression();
1502 if (!result) {
1503 return nullptr;
1504 }
1505 Token t;
1506 while (this->checkNext(Token::BITWISEAND, &t)) {
1507 std::unique_ptr<ASTExpression> right = this->equalityExpression();
1508 if (!right) {
1509 return nullptr;
1510 }
1511 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1512 }
1513 return result;
1514 }
1515
1516 /* relationalExpression ((EQEQ | NEQ) relationalExpression)* */
equalityExpression()1517 std::unique_ptr<ASTExpression> Parser::equalityExpression() {
1518 std::unique_ptr<ASTExpression> result = this->relationalExpression();
1519 if (!result) {
1520 return nullptr;
1521 }
1522 for (;;) {
1523 switch (this->peek().fKind) {
1524 case Token::EQEQ: // fall through
1525 case Token::NEQ: {
1526 Token t = this->nextToken();
1527 std::unique_ptr<ASTExpression> right = this->relationalExpression();
1528 if (!right) {
1529 return nullptr;
1530 }
1531 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1532 break;
1533 }
1534 default:
1535 return result;
1536 }
1537 }
1538 }
1539
1540 /* shiftExpression ((LT | GT | LTEQ | GTEQ) shiftExpression)* */
relationalExpression()1541 std::unique_ptr<ASTExpression> Parser::relationalExpression() {
1542 std::unique_ptr<ASTExpression> result = this->shiftExpression();
1543 if (!result) {
1544 return nullptr;
1545 }
1546 for (;;) {
1547 switch (this->peek().fKind) {
1548 case Token::LT: // fall through
1549 case Token::GT: // fall through
1550 case Token::LTEQ: // fall through
1551 case Token::GTEQ: {
1552 Token t = this->nextToken();
1553 std::unique_ptr<ASTExpression> right = this->shiftExpression();
1554 if (!right) {
1555 return nullptr;
1556 }
1557 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1558 break;
1559 }
1560 default:
1561 return result;
1562 }
1563 }
1564 }
1565
1566 /* additiveExpression ((SHL | SHR) additiveExpression)* */
shiftExpression()1567 std::unique_ptr<ASTExpression> Parser::shiftExpression() {
1568 std::unique_ptr<ASTExpression> result = this->additiveExpression();
1569 if (!result) {
1570 return nullptr;
1571 }
1572 for (;;) {
1573 switch (this->peek().fKind) {
1574 case Token::SHL: // fall through
1575 case Token::SHR: {
1576 Token t = this->nextToken();
1577 std::unique_ptr<ASTExpression> right = this->additiveExpression();
1578 if (!right) {
1579 return nullptr;
1580 }
1581 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1582 break;
1583 }
1584 default:
1585 return result;
1586 }
1587 }
1588 }
1589
1590 /* multiplicativeExpression ((PLUS | MINUS) multiplicativeExpression)* */
additiveExpression()1591 std::unique_ptr<ASTExpression> Parser::additiveExpression() {
1592 std::unique_ptr<ASTExpression> result = this->multiplicativeExpression();
1593 if (!result) {
1594 return nullptr;
1595 }
1596 for (;;) {
1597 switch (this->peek().fKind) {
1598 case Token::PLUS: // fall through
1599 case Token::MINUS: {
1600 Token t = this->nextToken();
1601 std::unique_ptr<ASTExpression> right = this->multiplicativeExpression();
1602 if (!right) {
1603 return nullptr;
1604 }
1605 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1606 break;
1607 }
1608 default:
1609 return result;
1610 }
1611 }
1612 }
1613
1614 /* unaryExpression ((STAR | SLASH | PERCENT) unaryExpression)* */
multiplicativeExpression()1615 std::unique_ptr<ASTExpression> Parser::multiplicativeExpression() {
1616 std::unique_ptr<ASTExpression> result = this->unaryExpression();
1617 if (!result) {
1618 return nullptr;
1619 }
1620 for (;;) {
1621 switch (this->peek().fKind) {
1622 case Token::STAR: // fall through
1623 case Token::SLASH: // fall through
1624 case Token::PERCENT: {
1625 Token t = this->nextToken();
1626 std::unique_ptr<ASTExpression> right = this->unaryExpression();
1627 if (!right) {
1628 return nullptr;
1629 }
1630 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1631 break;
1632 }
1633 default:
1634 return result;
1635 }
1636 }
1637 }
1638
1639 /* postfixExpression | (PLUS | MINUS | NOT | PLUSPLUS | MINUSMINUS) unaryExpression */
unaryExpression()1640 std::unique_ptr<ASTExpression> Parser::unaryExpression() {
1641 switch (this->peek().fKind) {
1642 case Token::PLUS: // fall through
1643 case Token::MINUS: // fall through
1644 case Token::LOGICALNOT: // fall through
1645 case Token::BITWISENOT: // fall through
1646 case Token::PLUSPLUS: // fall through
1647 case Token::MINUSMINUS: {
1648 Token t = this->nextToken();
1649 std::unique_ptr<ASTExpression> expr = this->unaryExpression();
1650 if (!expr) {
1651 return nullptr;
1652 }
1653 return std::unique_ptr<ASTExpression>(new ASTPrefixExpression(t, std::move(expr)));
1654 }
1655 default:
1656 return this->postfixExpression();
1657 }
1658 }
1659
1660 /* term suffix* */
postfixExpression()1661 std::unique_ptr<ASTExpression> Parser::postfixExpression() {
1662 std::unique_ptr<ASTExpression> result = this->term();
1663 if (!result) {
1664 return nullptr;
1665 }
1666 for (;;) {
1667 switch (this->peek().fKind) {
1668 case Token::LBRACKET: // fall through
1669 case Token::DOT: // fall through
1670 case Token::LPAREN: // fall through
1671 case Token::PLUSPLUS: // fall through
1672 case Token::MINUSMINUS: {
1673 std::unique_ptr<ASTSuffix> s = this->suffix();
1674 if (!s) {
1675 return nullptr;
1676 }
1677 result.reset(new ASTSuffixExpression(std::move(result), std::move(s)));
1678 break;
1679 }
1680 default:
1681 return result;
1682 }
1683 }
1684 }
1685
1686 /* LBRACKET expression? RBRACKET | DOT IDENTIFIER | LPAREN parameters RPAREN |
1687 PLUSPLUS | MINUSMINUS */
suffix()1688 std::unique_ptr<ASTSuffix> Parser::suffix() {
1689 Token next = this->nextToken();
1690 switch (next.fKind) {
1691 case Token::LBRACKET: {
1692 if (this->checkNext(Token::RBRACKET)) {
1693 return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(next.fPosition));
1694 }
1695 std::unique_ptr<ASTExpression> e = this->expression();
1696 if (!e) {
1697 return nullptr;
1698 }
1699 this->expect(Token::RBRACKET, "']' to complete array access expression");
1700 return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(std::move(e)));
1701 }
1702 case Token::DOT: {
1703 Position pos = this->peek().fPosition;
1704 String text;
1705 if (this->identifier(&text)) {
1706 return std::unique_ptr<ASTSuffix>(new ASTFieldSuffix(pos, std::move(text)));
1707 }
1708 return nullptr;
1709 }
1710 case Token::LPAREN: {
1711 std::vector<std::unique_ptr<ASTExpression>> parameters;
1712 if (this->peek().fKind != Token::RPAREN) {
1713 for (;;) {
1714 std::unique_ptr<ASTExpression> expr = this->assignmentExpression();
1715 if (!expr) {
1716 return nullptr;
1717 }
1718 parameters.push_back(std::move(expr));
1719 if (!this->checkNext(Token::COMMA)) {
1720 break;
1721 }
1722 }
1723 }
1724 this->expect(Token::RPAREN, "')' to complete function parameters");
1725 return std::unique_ptr<ASTSuffix>(new ASTCallSuffix(next.fPosition,
1726 std::move(parameters)));
1727 }
1728 case Token::PLUSPLUS:
1729 return std::unique_ptr<ASTSuffix>(new ASTSuffix(next.fPosition,
1730 ASTSuffix::kPostIncrement_Kind));
1731 case Token::MINUSMINUS:
1732 return std::unique_ptr<ASTSuffix>(new ASTSuffix(next.fPosition,
1733 ASTSuffix::kPostDecrement_Kind));
1734 default: {
1735 this->error(next.fPosition, "expected expression suffix, but found '" + next.fText +
1736 "'\n");
1737 return nullptr;
1738 }
1739 }
1740 }
1741
1742 /* IDENTIFIER | intLiteral | floatLiteral | boolLiteral | '(' expression ')' */
term()1743 std::unique_ptr<ASTExpression> Parser::term() {
1744 std::unique_ptr<ASTExpression> result;
1745 Token t = this->peek();
1746 switch (t.fKind) {
1747 case Token::IDENTIFIER: {
1748 String text;
1749 if (this->identifier(&text)) {
1750 result.reset(new ASTIdentifier(t.fPosition, std::move(text)));
1751 }
1752 break;
1753 }
1754 case Token::INT_LITERAL: {
1755 int64_t i;
1756 if (this->intLiteral(&i)) {
1757 result.reset(new ASTIntLiteral(t.fPosition, i));
1758 }
1759 break;
1760 }
1761 case Token::FLOAT_LITERAL: {
1762 double f;
1763 if (this->floatLiteral(&f)) {
1764 result.reset(new ASTFloatLiteral(t.fPosition, f));
1765 }
1766 break;
1767 }
1768 case Token::TRUE_LITERAL: // fall through
1769 case Token::FALSE_LITERAL: {
1770 bool b;
1771 if (this->boolLiteral(&b)) {
1772 result.reset(new ASTBoolLiteral(t.fPosition, b));
1773 }
1774 break;
1775 }
1776 case Token::LPAREN: {
1777 this->nextToken();
1778 result = this->expression();
1779 if (result) {
1780 this->expect(Token::RPAREN, "')' to complete expression");
1781 }
1782 break;
1783 }
1784 default:
1785 this->nextToken();
1786 this->error(t.fPosition, "expected expression, but found '" + t.fText + "'\n");
1787 result = nullptr;
1788 }
1789 return result;
1790 }
1791
1792 /* INT_LITERAL */
intLiteral(int64_t * dest)1793 bool Parser::intLiteral(int64_t* dest) {
1794 Token t;
1795 if (this->expect(Token::INT_LITERAL, "integer literal", &t)) {
1796 *dest = SkSL::stol(t.fText);
1797 return true;
1798 }
1799 return false;
1800 }
1801
1802 /* FLOAT_LITERAL */
floatLiteral(double * dest)1803 bool Parser::floatLiteral(double* dest) {
1804 Token t;
1805 if (this->expect(Token::FLOAT_LITERAL, "float literal", &t)) {
1806 *dest = SkSL::stod(t.fText);
1807 return true;
1808 }
1809 return false;
1810 }
1811
1812 /* TRUE_LITERAL | FALSE_LITERAL */
boolLiteral(bool * dest)1813 bool Parser::boolLiteral(bool* dest) {
1814 Token t = this->nextToken();
1815 switch (t.fKind) {
1816 case Token::TRUE_LITERAL:
1817 *dest = true;
1818 return true;
1819 case Token::FALSE_LITERAL:
1820 *dest = false;
1821 return true;
1822 default:
1823 this->error(t.fPosition, "expected 'true' or 'false', but found '" + t.fText + "'\n");
1824 return false;
1825 }
1826 }
1827
1828 /* IDENTIFIER */
identifier(String * dest)1829 bool Parser::identifier(String* dest) {
1830 Token t;
1831 if (this->expect(Token::IDENTIFIER, "identifier", &t)) {
1832 *dest = t.fText;
1833 return true;
1834 }
1835 return false;
1836 }
1837
1838 } // namespace
1839