|
|
//*************************************************************************** /* * TOra - An Oracle Toolkit for DBA's and developers * Copyright (C) 2003 Quest Software, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; only version 2 of * the License is valid for this program. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * As a special exception, you have permission to link this program * with the Oracle Client libraries and distribute executables, as long * as you follow the requirements of the GNU GPL in regard to all of the * software in the executable aside from Oracle client libraries. * * Specifically you are not permitted to link this program with the * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. * And you are not permitted to distribute binaries compiled against * these libraries without written consent from Quest Software, Inc. * Observe that this does not disallow linking to the Qt Free Edition. * * All trademarks belong to their respective owners. * ****************************************************************************/ #ifndef TOSQLPARSE_H #define TOSQLPARSE_H #include <list> #include <qstring.h> class toMarkedText; class toConnection; /** A bunch of functions to parse and indent SQL text. */ class toSQLParse { public: struct settings { bool ExpandSpaces; bool CommaBefore; bool BlockOpenLine; bool OperatorSpace; bool KeywordUpper; bool RightSeparator; bool EndBlockNewline; int IndentLevel; int CommentColumn; }; /** Structure the statement is parsed into. */ class statement { /** Subtokens to this token. */ std::list<statement> *SubTokens; public: /** Type of this token. */ enum type { /** Start of block. */ Block, /** Start of statement. */ Statement, /** Sub list */ List, /** Parameter of statement. */ Keyword, /** Another token of whatever it is detected in. */ Token, /** Unparsed data */ Raw /** Type of token. */ } Type; /** Was there a comment attached to this token */ QString Comment; /** The actual token. */ QString String; /** The original line of the token (0 is first line) */ int Line; /** Create statement */ statement(type ntype=Token,const QString &token=QString::null,int cline=-1); /** Allocate subtokens if not available and return reference to subtokens */ std::list<statement> &subTokens(); /** Copy constructor */ statement(const statement &); /** Copy operator */ const statement &operator = (const statement &); /** Destroy statement */ ~statement(); }; /** Abstract class to define a source of tokens for the parser. */ class tokenizer { protected: int Offset; int Line; public: /** Create a tokenizer. Optionally specify which line and offset to start at. */ tokenizer(int offset=0,int line=0) { Line=line; Offset=offset; } virtual ~tokenizer() { } /** Get a token from the string. * @param forward Go forward or backwards to get next token. * @param comment Include comments as tokens. */ virtual QString getToken(bool forward=true,bool comment=false) = 0; /** Get the current line of the tokenizer. A line is defined by a \n character */ virtual int line(void) { return Line; } /** Current offset of the tokenizer (Should point to the character after the last token in the specified direction) */ virtual int offset(void) { return Offset; } /** Set a new offset of tokenzer. */ virtual void setOffset(int offset) { Offset=offset; } /** Set new current line of tokenizer. * This will not affect the current position of the tokenizer. */ virtual void setLine(int line) { Line=line; } /** Get the data remaining after the current position. * @param eol If true end of line, otherwise end of tokenizer. */ virtual QString remaining(bool eol) = 0; }; /** Tokenizer class which gets tokens from a string. */ class stringTokenizer : public tokenizer { QString String; public: stringTokenizer(const QString &str,int offset=0,int line=0) : tokenizer(offset,line) { String=str; } /** Get a token from the string. * @param forward Go forward or backwards to get next token. * @param comment Include comments as tokens. */ virtual QString getToken(bool forward=true,bool comment=false); /** Get the data remaining after the current position. * @param eol If true end of line, otherwise end of tokenizer. */ virtual QString remaining(bool eol); }; /** Tokenizer class which gets tokens from an editor. */ class editorTokenizer : public tokenizer { toMarkedText *Editor; public: editorTokenizer(toMarkedText *editor,int offset=0,int line=0) : tokenizer(offset,line) { Editor=editor; } /** Get a token from the string. * @param forward Go forward or backwards to get next token. * @param comment Include comments as tokens. */ virtual QString getToken(bool forward=true,bool comment=false); /** Get the data remaining after the current position. * @param eol If true end of line, otherwise end of tokenizer. */ virtual QString remaining(bool eol); }; /** Parse a string. * @param tokens Tokenizer provider to generate parsed tree from. * @return Parsed statement tree. */ static std::list<statement> parse(tokenizer &tokens); /** Parse a string. * @param tokens Tokenizer provider to generate parsed tree from. * @return Parsed statement tree. */ static std::list<statement> parse(tokenizer &tokens,toConnection &conn); /** Parse a string. * @param str String to parse. * @return Parsed statement tree. */ static std::list<statement> parse(const QString &str) { stringTokenizer tokens(str); return parse(tokens); } /** Parse a string. * @param str String to parse. * @param conn Connection to determine SQL dialect. (For future use) * @return Parsed statement tree. */ static std::list<statement> parse(const QString &str,toConnection &conn); /** Get one statement (or block) from the root of an editor or string. * @param tokens Tokenizer to get tokens from. * @param conn Connection to determine SQL dialog. (For future use) */ static statement parseStatement(tokenizer &tokens); /** Get one statement (or block) from the root of an editor or string. * @param str Tokenizer to get tokens from. * @param conn Connection to determine SQL dialog. (For future use) */ static statement parseStatement(const QString &str) { stringTokenizer tokens(str); return parseStatement(tokens); } /** Get one statement (or block) from the root of an editor or string. * @param tokens Tokenizer to get tokens from. * @param conn Connection to determine SQL dialog. (For future use) */ static statement parseStatement(tokenizer &tokens,toConnection &conn); /** Get one statement (or block) from the root of an editor or string. * @param str Tokenizer to get tokens from. * @param conn Connection to determine SQL dialog. (For future use) */ static statement parseStatement(const QString &str,toConnection &conn) { stringTokenizer tokens(str); return parseStatement(tokens,conn); } /** Indent a string. * @param str String to indent. * @return An indented string. */ static QString indent(const QString &str); /** Indent a parse statement structure into a string. * @param stat Statement to indent. * @param level Initial indentation level to use. * @return A string with the indented statement. */ static QString indentStatement(statement &stat,int level=0); /** Indent a string. * @param str String to indent. * @param conn Connection to determine SQL dialect. (For future use) * @return An indented string. */ static QString indent(const QString &str,toConnection &conn); /** Create an indentation string. * @param level Number of characters to indent. */ static QString indentString(int level); /** Count indentation level of a string. * @param str String to check. * @param chars Position in string. */ static int countIndent(const QString &str,int &chars); private: static settings Settings; static statement parseStatement(tokenizer &tokens, bool declare,bool lst); public: /** Get current settings. */ static settings getSetting(void) { return Settings; } /** Get current settings. */ static void setSetting(const settings &setting) { Settings=setting; } }; #endif