/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SKSL_PARSER #define SKSL_PARSER #include #include #include #include #include "SkSLErrorReporter.h" #include "ir/SkSLLayout.h" #include "SkSLLexer.h" struct yy_buffer_state; #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; namespace SkSL { struct ASTBlock; struct ASTBreakStatement; struct ASTContinueStatement; struct ASTDeclaration; struct ASTDiscardStatement; struct ASTDoStatement; struct ASTExpression; struct ASTExpressionStatement; struct ASTForStatement; struct ASTIfStatement; struct ASTInterfaceBlock; struct ASTParameter; struct ASTPrecision; struct ASTReturnStatement; struct ASTStatement; struct ASTSuffix; struct ASTSwitchCase; struct ASTSwitchStatement; struct ASTType; struct ASTWhileStatement; struct ASTVarDeclarations; struct Modifiers; class SymbolTable; /** * Consumes .sksl text and produces an abstract syntax tree describing the contents. */ class Parser { public: enum class LayoutToken { LOCATION, OFFSET, BINDING, INDEX, SET, BUILTIN, INPUT_ATTACHMENT_INDEX, ORIGIN_UPPER_LEFT, OVERRIDE_COVERAGE, BLEND_SUPPORT_ALL_EQUATIONS, BLEND_SUPPORT_MULTIPLY, BLEND_SUPPORT_SCREEN, BLEND_SUPPORT_OVERLAY, BLEND_SUPPORT_DARKEN, BLEND_SUPPORT_LIGHTEN, BLEND_SUPPORT_COLORDODGE, BLEND_SUPPORT_COLORBURN, BLEND_SUPPORT_HARDLIGHT, BLEND_SUPPORT_SOFTLIGHT, BLEND_SUPPORT_DIFFERENCE, BLEND_SUPPORT_EXCLUSION, BLEND_SUPPORT_HSL_HUE, BLEND_SUPPORT_HSL_SATURATION, BLEND_SUPPORT_HSL_COLOR, BLEND_SUPPORT_HSL_LUMINOSITY, PUSH_CONSTANT, POINTS, LINES, LINE_STRIP, LINES_ADJACENCY, TRIANGLES, TRIANGLE_STRIP, TRIANGLES_ADJACENCY, MAX_VERTICES, INVOCATIONS, WHEN, KEY, CTYPE }; Parser(const char* text, size_t length, SymbolTable& types, ErrorReporter& errors); /** * Consumes a complete .sksl file and produces a list of declarations. Errors are reported via * the ErrorReporter; the return value may contain some declarations even when errors have * occurred. */ std::vector> file(); StringFragment text(Token token); Position position(Token token); private: static void InitLayoutMap(); /** * Return the next token, including whitespace tokens, from the parse stream. */ Token nextRawToken(); /** * Return the next non-whitespace token from the parse stream. */ Token nextToken(); /** * Push a token back onto the parse stream, so that it is the next one read. Only a single level * of pushback is supported (that is, it is an error to call pushback() twice in a row without * an intervening nextToken()). */ void pushback(Token t); /** * Returns the next non-whitespace token without consuming it from the stream. */ Token peek(); /** * Checks to see if the next token is of the specified type. If so, stores it in result (if * result is non-null) and returns true. Otherwise, pushes it back and returns false. */ bool checkNext(Token::Kind kind, Token* result = nullptr); /** * Reads the next non-whitespace token and generates an error if it is not the expected type. * The 'expected' string is part of the error message, which reads: * * "expected , but found ''" * * If 'result' is non-null, it is set to point to the token that was read. * Returns true if the read token was as expected, false otherwise. */ bool expect(Token::Kind kind, const char* expected, Token* result = nullptr); bool expect(Token::Kind kind, String expected, Token* result = nullptr); void error(Token token, String msg); void error(int offset, String msg); /** * Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will * always return true. */ bool isType(StringFragment name); // these functions parse individual grammar rules from the current parse position; you probably // don't need to call any of these outside of the parser. The function declarations in the .cpp // file have comments describing the grammar rules. std::unique_ptr precision(); std::unique_ptr directive(); std::unique_ptr section(); std::unique_ptr enumDeclaration(); std::unique_ptr declaration(); std::unique_ptr varDeclarations(); std::unique_ptr structDeclaration(); std::unique_ptr structVarDeclaration(Modifiers modifiers); std::unique_ptr varDeclarationEnd(Modifiers modifiers, std::unique_ptr type, StringFragment name); std::unique_ptr parameter(); int layoutInt(); StringFragment layoutIdentifier(); String layoutCode(); Layout::Key layoutKey(); Layout layout(); Modifiers modifiers(); Modifiers modifiersWithDefaults(int defaultFlags); std::unique_ptr statement(); std::unique_ptr type(); std::unique_ptr interfaceBlock(Modifiers mods); std::unique_ptr ifStatement(); std::unique_ptr doStatement(); std::unique_ptr whileStatement(); std::unique_ptr forStatement(); std::unique_ptr switchCase(); std::unique_ptr switchStatement(); std::unique_ptr returnStatement(); std::unique_ptr breakStatement(); std::unique_ptr continueStatement(); std::unique_ptr discardStatement(); std::unique_ptr block(); std::unique_ptr expressionStatement(); std::unique_ptr expression(); std::unique_ptr commaExpression(); std::unique_ptr assignmentExpression(); std::unique_ptr ternaryExpression(); std::unique_ptr logicalOrExpression(); std::unique_ptr logicalXorExpression(); std::unique_ptr logicalAndExpression(); std::unique_ptr bitwiseOrExpression(); std::unique_ptr bitwiseXorExpression(); std::unique_ptr bitwiseAndExpression(); std::unique_ptr equalityExpression(); std::unique_ptr relationalExpression(); std::unique_ptr shiftExpression(); std::unique_ptr additiveExpression(); std::unique_ptr multiplicativeExpression(); std::unique_ptr unaryExpression(); std::unique_ptr postfixExpression(); std::unique_ptr suffix(); std::unique_ptr term(); bool intLiteral(int64_t* dest); bool floatLiteral(double* dest); bool boolLiteral(bool* dest); bool identifier(StringFragment* dest); static std::unordered_map* layoutTokens; const char* fText; Lexer fLexer; YY_BUFFER_STATE fBuffer; // current parse depth, used to enforce a recursion limit to try to keep us from overflowing the // stack on pathological inputs int fDepth = 0; Token fPushback; SymbolTable& fTypes; ErrorReporter& fErrors; friend class AutoDepth; friend class HCodeGenerator; }; } // namespace #endif