Home | History | Annotate | Download | only in sksl
      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:
     75     AutoDepth(Parser* p)
     76     : fParser(p) {
     77         fParser->fDepth++;
     78     }
     79 
     80     ~AutoDepth() {
     81         fParser->fDepth--;
     82     }
     83 
     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 
     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 
    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 */
    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 
    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 
    163 Token Parser::nextToken() {
    164     Token token;
    165     do {
    166         token = this->nextRawToken();
    167     } while (token.fKind == Token::WHITESPACE);
    168     return token;
    169 }
    170 
    171 void Parser::pushback(Token t) {
    172     ASSERT(fPushback.fKind == Token::INVALID_TOKEN);
    173     fPushback = t;
    174 }
    175 
    176 Token Parser::peek() {
    177     fPushback = this->nextToken();
    178     return fPushback;
    179 }
    180 
    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 
    193 bool Parser::expect(Token::Kind kind, const char* expected, Token* result) {
    194     return this->expect(kind, String(expected), result);
    195 }
    196 
    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 
    215 void Parser::error(Position p, const char* msg) {
    216     this->error(p, String(msg));
    217 }
    218 
    219 void Parser::error(Position p, String msg) {
    220     fErrors.error(p, msg);
    221 }
    222 
    223 bool Parser::isType(String name) {
    224     return nullptr != fTypes[name];
    225 }
    226 
    227 /* PRECISION (LOWP | MEDIUMP | HIGHP) type SEMICOLON */
    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 */
    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 */
    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) */
    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 */
    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 */
    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) */
    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 */
    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)? */
    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)? */
    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> */
    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'))? */
    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 */
    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)* */
    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 
    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 */
    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)* */
    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)*)? */
    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)? */
    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 */
   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 */
   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* */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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)* */
   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  */
   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)? */
   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)* */
   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)* */
   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)* */
   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)* */
   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)* */
   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)* */
   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)* */
   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)* */
   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)* */
   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)* */
   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)* */
   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 */
   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* */
   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 */
   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 ')' */
   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 */
   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 */
   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 */
   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 */
   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