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.
301 lines
13 KiB
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_
|