You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/kvirc/kvs/kvi_kvs_parser.h

301 lines
13 KiB

#ifndef _KVI_KVS_PARSER_H_
#define _KVI_KVS_PARSER_H_
//=============================================================================
//
// File : kvi_kvs_parser.h
// Creation date : Thu 25 Sep 2003 05.12 CEST by Szymon Stefanek
//
// This file is part of the KVirc irc client distribution
// Copyright (C) 2003 Szymon Stefanek (pragma at kvirc dot net)
//
// 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; either version 2
// of the License, or (at your opinion) any later version.
//
// 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
#include "kvi_settings.h"
#include "kvi_qstring.h"
#include "kvi_pointerlist.h"
#include "kvi_pointerhashtable.h"
class KviKvsTreeNode;
class KviKvsTreeNodeInstruction;
class KviKvsTreeNodeInstructionBlock;
class KviKvsTreeNodeCommand;
class KviKvsTreeNodeDataList;
class KviKvsTreeNodeData;
class KviKvsTreeNodeVariable;
class KviKvsTreeNodeVariableReference;
class KviKvsTreeNodeConstantData;
class KviKvsTreeNodeSwitchList;
class KviKvsTreeNodeSpecialCommand;
class KviKvsTreeNodeExpression;
class KviKvsTreeNodeExpressionBinaryOperator;
class KviKvsTreeNodeFunctionCall;
class KviKvsTreeNodeOperation;
class KviKvsTreeNodeSpecialCommandDefpopupLabelPopup;
class KviKvsScript;
class KviKvsKernel;
class KviWindow;
// This is an ONE-TIME parser used by KviKvsScript
class KVIRC_API KviKvsParser
{
friend class KviKvsKernel;
public:
KviKvsParser(KviKvsScript * pScript,KviWindow * pOutputWindow);
~KviKvsParser();
private:
const TQChar * m_pBuffer; // the local pointer to the beginning of the buffer
const TQChar * m_ptr; // the parsing pointer
// parsing state
KviPointerHashTable<TQString,TQString> * m_pGlobals; // the dict of the vars declared with global in this script
int m_iFlags; // the current parsing flags
bool m_bError; // error(..) was called ?
// this stuff is used only for reporting errors and warnings
KviKvsScript * m_pScript; // parent script
KviWindow * m_pWindow; // output window
public: // public interface
enum Flags { AssumeLocals = 1, Pedantic = 2 };
// was there an error ?
bool error() const { return m_bError; };
// parses the buffer pointed by pBuffer and returns
// a syntax tree or 0 in case of failure
// if the parsing fails, the error code can be retrieved by calling error()
KviKvsTreeNodeInstruction * parse(const TQChar * pBuffer,int iFlags = 0);
KviKvsTreeNodeInstruction * parseAsExpression(const TQChar * pBuffer,int iFlags = 0);
KviKvsTreeNodeInstruction * parseAsParameter(const TQChar * pBuffer,int iFlags = 0);
private: // parsing helpers
// generic
void skipSpaces(); // skips only spaces and tabs (eventually with \)
bool skipSpacesAndNewlines(); // skips space and newlines
void skipToNextLine(); // skips up to a new line
// dedicated
void skipToEndOfCStyleComment();
// dedicated to parseSpecialCommandFor() : in kvi_kvs_parser_specialcommands.cpp
bool skipToEndOfForControlBlock();
// error handlers
void error(const TQChar * pLocation,const TQString &szMsgFmt,...);
void warning(const TQChar * pLocation,const TQString &szMsgFmt,...);
void errorBadChar(const TQChar * pLocation,char cExpected,const char * szCommandName);
protected:
// this is called by KviKvsKernel to register the parsing routines
static void init();
private:
// returns 0 only in case of error
// starts on the first char of a buffer
// stops at the first null char encountered
KviKvsTreeNodeInstruction * parseInstructionList();
// may return 0 (empty instruction), check error() for error conditions
// starts on the first character of an instruction
// if the first char is ';' '\n' or null it just returns 0 without error
// stops after the ending char of the instruction
KviKvsTreeNodeInstruction * parseInstruction();
// may return 0 (empty block), check error() for error conditions
// starts at the leading '{' of the block
// stops after the trailing '}' of the block
KviKvsTreeNodeInstruction * parseInstructionBlock();
// returns 0 only in case of error
// starts on the first character of the parameters
// ends after the end of the command
KviKvsTreeNodeDataList * parseCommandParameterList();
// returns 0 only in case of error
// starts on the leading '(' or a ',' in the middle of the list
// ends after the trailing ')'
// if started in the middle of the list returns only the remaining
// parameters.
KviKvsTreeNodeDataList * parseCommaSeparatedParameterList();
KviPointerList<TQString> * parseCommaSeparatedParameterListNoTree();
// returns 0 in case of error or if it starts on a terminating character (null parameter)
// check error() to see if there was an error condition (unless you already know that
// there was a valid first character)
// start on the first character of the parameter
// ends after the first character not included in the param (';','\n','\0',' ')
// If bPreferNumeric is true then when a single literal parameter
// is extracted an attempt to convert it to a numeric format is made.
// This optimizes assignments, self-sums etc...
KviKvsTreeNodeData * parseCommandParameter(bool bPreferNumeric = false);
// returns 0 only in case of error
// start on the first character of the parameter
// ends after the first character not included in the param (')','\n','\0',',')
KviKvsTreeNodeData * parseCommaSeparatedParameter();
// returns 0 only in case of error
// start on the first character of the parameter
// ends after the first character not included in the param (')','\n','\0')
KviKvsTreeNodeData * parseSingleParameterInParenthesis();
// never returns 0
KviKvsTreeNodeConstantData * parseCommandLiteralParameter();
// never returns 0
KviKvsTreeNodeConstantData * parseCommaSeparatedLiteralParameter();
// never returns 0
KviKvsTreeNodeConstantData * parseSingleLiteralParameterInParenthesis();
// returns 0 only in case of error
// starts at the leading '"'
// ends after the trailing '"'
KviKvsTreeNodeData * parseStringParameter();
// never returns 0
KviKvsTreeNodeConstantData * parseStringLiteralParameter();
// returns 0 in case of error or of an empty switch list (check the error code!)
// starts at the leading '-' of the first switch
// ends after the last switch
KviKvsTreeNodeSwitchList * parseCommandSwitchList();
// returns 0 only in case of error
// starts at '%' or '$'
// and ends after the end of the data reference
// or just after the '%' or '$' if this was only a ConstandData (not a var or func)
KviKvsTreeNodeData * parseParameterPercentOrDollar();
// returns 0 only in case of error
// starts at '%' or '$'
// ends after the end of the complete data reference (including scope operators!)
KviKvsTreeNodeData * parsePercentOrDollar(bool bInObjScope = false);
// returns 0 only in case of error
// starts at '%'
// ends after the end of the structured data
KviKvsTreeNodeVariable * parsePercent(bool bInObjectScope = false);
// returns 0 only in case of error
KviKvsTreeNodeData * parseHashKey();
// never returns 0
KviKvsTreeNodeConstantData * parseHashKeyLiteralParameter();
//
// kvi_kvs_parser_specialcommands.cpp
//
// return 0 only in case of error
// starts at the leading '(' of the if command (after the switches)
// and stops after the end of the else block
// if the first character is not '(' then this function fails with an error
KviKvsTreeNodeCommand * parseSpecialCommandIf();
// always returns 0
// check error() for error conditions
// starts after the switches of the "global" keyword
// and stops at the end of the command
// if the first character is not '%' of a variable then this function fails with an error
KviKvsTreeNodeCommand * parseSpecialCommandGlobal();
// returns 0 only in case of error
// starts at the leading '(' of the while command (after the switches)
// and stops after the end of the command block
// if the first character is not '(' then this function fails with an error
KviKvsTreeNodeCommand * parseSpecialCommandWhile();
// returns 0 only in case of error
// starts at the leading '(' of the while command (after the switches)
// and stops after the end of the command block
// if the first character is not '(' then this function fails with an error
KviKvsTreeNodeCommand * parseSpecialCommandDo();
// returns 0 only in case of error
// and stops after the end of the break command
KviKvsTreeNodeCommand * parseSpecialCommandBreak();
// returns 0 only in case of error
// and stops after the end of the for command block
KviKvsTreeNodeCommand * parseSpecialCommandFor();
// returns 0 only in case of error
// and stops after the end of the foreach command block
KviKvsTreeNodeCommand * parseSpecialCommandForeach();
// returns 0 only in case of error
// and stops after the end of the switch command block
KviKvsTreeNodeCommand * parseSpecialCommandSwitch();
// returns 0 only in case of error
// and stops after the end of the defpopup command block
KviKvsTreeNodeCommand * parseSpecialCommandUnset();
// returns 0 only in case of error
// and stops after the end of the defpopup command block
KviKvsTreeNodeCommand * parseSpecialCommandDefpopup();
KviKvsTreeNodeSpecialCommandDefpopupLabelPopup * parseSpecialCommandDefpopupLabelPopup();
// returns 0 only in case of error
// stops after the class command block
KviKvsTreeNodeCommand * parseSpecialCommandClass();
// returns 0 only in case of error
// stops after the perl.end statement
KviKvsTreeNodeCommand * parseSpecialCommandPerlBegin();
// returns 0 only in case of error
// and stops after the end of the help command
KviKvsTreeNodeCommand * parseSpecialCommandHelp();
//
// kvi_kvs_parser_command.cpp
//
// may return 0 (empty command), check error() for error conditions
// starts at the beginning of a command (can be non valid)
// ends after the ending char of the command
KviKvsTreeNodeCommand * parseCommand();
//
// kvi_kvs_parser_comment.cpp
//
// always returns 0, and it CAN be an error!
// starts at the beginning of a comment (must be '#' or '/')
// ends after the ending char of the comment
KviKvsTreeNode * parseComment();
//
// kvi_kvs_parser_dollar.cpp
//
// returns 0 only in case of error
// starts at '$'
// ends after the end of the function call
KviKvsTreeNodeData * parseDollar(bool bInObjScope = false);
// returns 0 only in case of error
// starts at '@'
// ends after the end of the function call
KviKvsTreeNodeData * parseAt(bool bInObjScope = false);
//
// kvi_kvs_parser_lside.cpp
//
// returns 0 only in case of error
// returns after the command terminator
KviKvsTreeNodeInstruction * parseVoidFunctionCallOrOperation();
// returns 0 only in case of error
// returns after the command terminator
KviKvsTreeNodeOperation * parseOperation();
// returns 0 only in case of error
// returns after the command terminator
// If bPreferNumeric is propagated to parseCommandParameter() function
KviKvsTreeNodeData * parseOperationRightSide(bool bPreferNumeric = false);
// return 0 only in case of error
// returns after the command terminator
KviKvsTreeNodeOperation * parseBindingOperation();
KviKvsTreeNodeConstantData * parseBindingOperationLiteralParameter();
KviKvsTreeNodeData * parseBindingOperationParameter();
//
// kvi_kvs_parser_expression.cpp
//
// returns 0 only in case of error
// starts AFTER the leading char of the expression
// ends afer the first terminator found
KviKvsTreeNodeExpression * parseExpression(char terminator);
KviKvsTreeNodeExpressionBinaryOperator * parseExpressionBinaryOperator();
KviKvsTreeNodeExpression * parseExpressionOperand(char terminator);
KviKvsTreeNodeExpression * parseExpressionOperandCore(char terminator);
bool parseExpressionMightPointToOperator();
void report(bool bError,const TQChar * pLocation,const TQString &szMsgFmt,kvi_va_list va);
};
#endif //!_KVI_KVS_PARSER_H_