/* * 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 "SkSLToken.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 ASTLayout; struct ASTModifiers; struct ASTParameter; struct ASTPrecision; struct ASTReturnStatement; struct ASTStatement; struct ASTSuffix; struct ASTType; struct ASTWhileStatement; struct ASTVarDeclarations; class SymbolTable; /** * Consumes .sksl text and produces an abstract syntax tree describing the contents. */ class Parser { public: Parser(std::string text, SymbolTable& types, ErrorReporter& errors); ~Parser(); /** * 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(); private: /** * Return the next 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 token without consuming it from the stream. */ Token peek(); /** * Reads the next 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, std::string expected, Token* result = nullptr); void error(Position p, std::string msg); /** * Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will * always return true. */ bool isType(std::string 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 declaration(); std::unique_ptr varDeclarations(); std::unique_ptr structDeclaration(); std::unique_ptr structVarDeclaration(ASTModifiers modifiers); std::unique_ptr varDeclarationEnd(ASTModifiers modifiers, std::unique_ptr type, std::string name); std::unique_ptr parameter(); int layoutInt(); ASTLayout layout(); ASTModifiers modifiers(); ASTModifiers modifiersWithDefaults(int defaultFlags); std::unique_ptr statement(); std::unique_ptr type(); std::unique_ptr interfaceBlock(ASTModifiers mods); std::unique_ptr ifStatement(); std::unique_ptr doStatement(); std::unique_ptr whileStatement(); std::unique_ptr forStatement(); 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 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(std::string* dest); void* fScanner; YY_BUFFER_STATE fBuffer; Token fPushback; SymbolTable& fTypes; ErrorReporter& fErrors; }; } // namespace #endif