//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany /// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is ArangoDB GmbH, Cologne, Germany /// /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_AQL_PARSER_H #define ARANGOD_AQL_PARSER_H 1 #include "Basics/Common.h" #include "Aql/Ast.h" #include "Aql/Query.h" namespace arangodb { namespace aql { struct AstNode; class Query; struct QueryResult; class Parser; } } //////////////////////////////////////////////////////////////////////////////// /// @brief forwards for the parse function provided by the parser (.y) //////////////////////////////////////////////////////////////////////////////// int Aqlparse(arangodb::aql::Parser*); //////////////////////////////////////////////////////////////////////////////// /// @brief forward for the init function provided by the lexer (.l) //////////////////////////////////////////////////////////////////////////////// int Aqllex_init(void**); //////////////////////////////////////////////////////////////////////////////// /// @brief forward for the shutdown function provided by the lexer (.l) //////////////////////////////////////////////////////////////////////////////// int Aqllex_destroy(void*); //////////////////////////////////////////////////////////////////////////////// /// @brief forward for the context function provided by the lexer (.l) //////////////////////////////////////////////////////////////////////////////// void Aqlset_extra(arangodb::aql::Parser*, void*); namespace arangodb { namespace aql { //////////////////////////////////////////////////////////////////////////////// /// @brief the parser //////////////////////////////////////////////////////////////////////////////// class Parser { public: ////////////////////////////////////////////////////////////////////////////// /// @brief create the parser ////////////////////////////////////////////////////////////////////////////// Parser(Query*); ////////////////////////////////////////////////////////////////////////////// /// @brief destroy the parser ////////////////////////////////////////////////////////////////////////////// ~Parser(); public: ////////////////////////////////////////////////////////////////////////////// /// @brief return the ast during parsing ////////////////////////////////////////////////////////////////////////////// inline Ast* ast() { return _ast; } ////////////////////////////////////////////////////////////////////////////// /// @brief return the query during parsing ////////////////////////////////////////////////////////////////////////////// inline Query* query() { return _query; } ////////////////////////////////////////////////////////////////////////////// /// @brief return the scanner ////////////////////////////////////////////////////////////////////////////// inline void* scanner() const { return _scanner; } ////////////////////////////////////////////////////////////////////////////// /// @brief a pointer to the start of the query string ////////////////////////////////////////////////////////////////////////////// inline char const* queryString() const { return _query->queryString(); } ////////////////////////////////////////////////////////////////////////////// /// @brief return the remaining length of the query string to process ////////////////////////////////////////////////////////////////////////////// inline size_t remainingLength() const { return _remainingLength; } ////////////////////////////////////////////////////////////////////////////// /// @brief return the current marker position ////////////////////////////////////////////////////////////////////////////// inline char const* marker() const { return _marker; } ////////////////////////////////////////////////////////////////////////////// /// @brief set the current marker position ////////////////////////////////////////////////////////////////////////////// inline void marker(char const* marker) { _marker = marker; } ////////////////////////////////////////////////////////////////////////////// /// @brief return the current parse position ////////////////////////////////////////////////////////////////////////////// inline size_t offset() const { return _offset; } ////////////////////////////////////////////////////////////////////////////// /// @brief adjust the current parse position ////////////////////////////////////////////////////////////////////////////// inline void increaseOffset(int offset) { _offset += static_cast(offset); } ////////////////////////////////////////////////////////////////////////////// /// @brief adjust the current parse position ////////////////////////////////////////////////////////////////////////////// inline void increaseOffset(size_t offset) { _offset += offset; } ////////////////////////////////////////////////////////////////////////////// /// @brief fill the output buffer with a fragment of the query ////////////////////////////////////////////////////////////////////////////// void fillBuffer(char* result, size_t length) { memcpy(result, _buffer, length); _buffer += length; _remainingLength -= length; } ////////////////////////////////////////////////////////////////////////////// /// @brief set data for write queries ////////////////////////////////////////////////////////////////////////////// bool configureWriteQuery(AstNode const*, AstNode* optionNode); ////////////////////////////////////////////////////////////////////////////// /// @brief whether or not the query is a data-modification query ////////////////////////////////////////////////////////////////////////////// bool isModificationQuery() const { return _isModificationQuery; } ////////////////////////////////////////////////////////////////////////////// /// @brief parse the query ////////////////////////////////////////////////////////////////////////////// QueryResult parse(bool); ////////////////////////////////////////////////////////////////////////////// /// @brief register a parse error, position is specified as line / column ////////////////////////////////////////////////////////////////////////////// void registerParseError(int, char const*, char const*, int, int); ////////////////////////////////////////////////////////////////////////////// /// @brief register a parse error, position is specified as line / column ////////////////////////////////////////////////////////////////////////////// void registerParseError(int, char const*, int, int); ////////////////////////////////////////////////////////////////////////////// /// @brief register a non-parse error ////////////////////////////////////////////////////////////////////////////// void registerError(int, char const* = nullptr); ////////////////////////////////////////////////////////////////////////////// /// @brief register a warning ////////////////////////////////////////////////////////////////////////////// void registerWarning(int, char const*, int, int); ////////////////////////////////////////////////////////////////////////////// /// @brief push an AstNode into the array element on top of the stack ////////////////////////////////////////////////////////////////////////////// void pushArrayElement(AstNode*); ////////////////////////////////////////////////////////////////////////////// /// @brief push an AstNode into the object element on top of the stack ////////////////////////////////////////////////////////////////////////////// void pushObjectElement(char const*, size_t, AstNode*); ////////////////////////////////////////////////////////////////////////////// /// @brief push an AstNode into the object element on top of the stack ////////////////////////////////////////////////////////////////////////////// void pushObjectElement(AstNode*, AstNode*); ////////////////////////////////////////////////////////////////////////////// /// @brief push a temporary value on the parser's stack ////////////////////////////////////////////////////////////////////////////// void pushStack(void*); ////////////////////////////////////////////////////////////////////////////// /// @brief pop a temporary value from the parser's stack ////////////////////////////////////////////////////////////////////////////// void* popStack(); ////////////////////////////////////////////////////////////////////////////// /// @brief peek at a temporary value from the parser's stack ////////////////////////////////////////////////////////////////////////////// void* peekStack(); private: ////////////////////////////////////////////////////////////////////////////// /// @brief the query ////////////////////////////////////////////////////////////////////////////// Query* _query; ////////////////////////////////////////////////////////////////////////////// /// @brief abstract syntax tree for the query, build during parsing ////////////////////////////////////////////////////////////////////////////// Ast* _ast; ////////////////////////////////////////////////////////////////////////////// /// @brief lexer / scanner used when parsing the query (Aql/tokens.ll) ////////////////////////////////////////////////////////////////////////////// void* _scanner; ////////////////////////////////////////////////////////////////////////////// /// @brief currently processed part of the query string ////////////////////////////////////////////////////////////////////////////// char const* _buffer; ////////////////////////////////////////////////////////////////////////////// /// @brief remaining length of the query string, used during parsing ////////////////////////////////////////////////////////////////////////////// size_t _remainingLength; ////////////////////////////////////////////////////////////////////////////// /// @brief current offset into query string, used during parsing ////////////////////////////////////////////////////////////////////////////// size_t _offset; ////////////////////////////////////////////////////////////////////////////// /// @brief pointer into query string, used temporarily during parsing ////////////////////////////////////////////////////////////////////////////// char const* _marker; ////////////////////////////////////////////////////////////////////////////// /// @brief a stack of things, used temporarily during parsing ////////////////////////////////////////////////////////////////////////////// std::vector _stack; ////////////////////////////////////////////////////////////////////////////// /// @brief whether or not the query is a modification query ////////////////////////////////////////////////////////////////////////////// bool _isModificationQuery; }; } } #endif