CBotToken docs

dev-time-step
krzys-h 2015-12-23 17:28:21 +01:00
parent 6ef14617a0
commit 6482001b9b
5 changed files with 154 additions and 155 deletions

View File

@ -55,7 +55,7 @@ CBotInstr* CBotExprNum::Compile(CBotToken* &p, CBotCStack* pStack)
inst->m_numtype = CBotTypInt; inst->m_numtype = CBotTypInt;
if (p->GetType() == TokenTypDef) if (p->GetType() == TokenTypDef)
{ {
inst->m_valint = p->GetIdKey(); inst->m_valint = p->GetKeywordId();
} }
else else
{ {

View File

@ -439,7 +439,7 @@ void CBotProgram::Init()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotProgram::Free() void CBotProgram::Free()
{ {
CBotToken::Free() ; CBotToken::ClearDefineNum() ;
CBotCall ::Free() ; CBotCall ::Free() ;
CBotClass::Free() ; CBotClass::Free() ;
} }

View File

@ -270,10 +270,8 @@ public:
CBotTypResult rCompile(CBotVar*& pVar, void* pUser)); CBotTypResult rCompile(CBotVar*& pVar, void* pUser));
/** /**
* \brief Define a new constant * \copydoc CBotToken::DefineNum()
* \param name Name of the constant * \see CBotToken::DefineNum()
* \param val Value of the constant
* \return true on success, false if unable to define (e.g. already defined)
*/ */
static bool DefineNum(const std::string& name, long val); static bool DefineNum(const std::string& name, long val);

View File

@ -20,6 +20,7 @@
#include "CBot/CBotToken.h" #include "CBot/CBotToken.h"
#include <cstdarg> #include <cstdarg>
#include <cassert>
//! \brief Keeps the string corresponding to keyword ID //! \brief Keeps the string corresponding to keyword ID
//! Map is filled with id-string pars that are needed for CBot language parsing //! Map is filled with id-string pars that are needed for CBot language parsing
@ -136,20 +137,20 @@ CBotToken::CBotToken()
m_next = nullptr; m_next = nullptr;
m_prev = nullptr; m_prev = nullptr;
m_type = TokenTypVar; // at the beginning a default variable type m_type = TokenTypVar; // at the beginning a default variable type
m_IdKeyWord = -1; m_keywordId = -1;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotToken::CBotToken(const CBotToken* pSrc) CBotToken::CBotToken(const CBotToken& pSrc)
{ {
m_next = nullptr; m_next = nullptr;
m_prev = nullptr; m_prev = nullptr;
m_Text.clear(); m_text.clear();
m_Sep.clear(); m_sep.clear();
m_type = TokenTypNone; m_type = TokenTypNone;
m_IdKeyWord = 0; m_keywordId = 0;
m_start = 0; m_start = 0;
m_end = 0; m_end = 0;
@ -158,10 +159,10 @@ CBotToken::CBotToken(const CBotToken* pSrc)
{ {
m_type = pSrc->m_type; m_type = pSrc->m_type;
m_IdKeyWord = pSrc->m_IdKeyWord; m_keywordId = pSrc->m_IdKeyWord;
m_Text = pSrc->m_Text; m_text = pSrc->m_Text;
m_Sep = pSrc->m_Sep; m_sep = pSrc->m_Sep;
m_start = pSrc->m_start; m_start = pSrc->m_start;
m_end = pSrc->m_end; m_end = pSrc->m_end;
@ -169,28 +170,35 @@ CBotToken::CBotToken(const CBotToken* pSrc)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotToken::CBotToken(const std::string& mot, const std::string& sep, int start, int end) CBotToken::CBotToken(const std::string& text, const std::string& sep, int start, int end)
{ {
m_Text = mot; // word (mot) found as token m_text = text; // word (mot) found as token
m_Sep = sep; // separator m_sep = sep; // separator
m_next = nullptr; m_next = nullptr;
m_prev = nullptr; m_prev = nullptr;
m_start = start; m_start = start;
m_end = end; m_end = end;
m_type = TokenTypVar; // at the beginning a default variable type m_type = TokenTypVar; // at the beginning a default variable type
m_IdKeyWord = -1; m_keywordId = -1;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotToken::~CBotToken() CBotToken::~CBotToken()
{ {
assert(m_prev == nullptr);
if (m_next != nullptr)
{
m_next->m_prev = nullptr;
delete m_next; // recursive delete m_next; // recursive
m_next = nullptr; m_next = nullptr;
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotToken::Free() void CBotToken::ClearDefineNum()
{ {
m_defineNum.clear(); m_defineNum.clear();
} }
@ -202,11 +210,11 @@ const CBotToken& CBotToken::operator=(const CBotToken& src)
m_next = nullptr; m_next = nullptr;
m_prev = nullptr; m_prev = nullptr;
m_Text = src.m_Text; m_text = src.m_text;
m_Sep = src.m_Sep; m_sep = src.m_sep;
m_type = src.m_type; m_type = src.m_type;
m_IdKeyWord = src.m_IdKeyWord; m_keywordId = src.m_keywordId;
m_start = src.m_start; m_start = src.m_start;
m_end = src.m_end; m_end = src.m_end;
@ -217,14 +225,14 @@ const CBotToken& CBotToken::operator=(const CBotToken& src)
int CBotToken::GetType() int CBotToken::GetType()
{ {
if (this == nullptr) return 0; if (this == nullptr) return 0;
if (m_type == TokenTypKeyWord) return m_IdKeyWord; if (m_type == TokenTypKeyWord) return m_keywordId;
return m_type; return m_type;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
long CBotToken::GetIdKey() long CBotToken::GetKeywordId()
{ {
return m_IdKeyWord; return m_keywordId;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -244,19 +252,13 @@ CBotToken* CBotToken::GetPrev()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string CBotToken::GetString() std::string CBotToken::GetString()
{ {
return m_Text; return m_text;
}
////////////////////////////////////////////////////////////////////////////////
std::string CBotToken::GetSep()
{
return m_Sep;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotToken::SetString(const std::string& name) void CBotToken::SetString(const std::string& name)
{ {
m_Text = name; m_text = name;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -435,9 +437,9 @@ bis:
if (token[0] == '\"') t->m_type = TokenTypString; if (token[0] == '\"') t->m_type = TokenTypString;
if (first) t->m_type = TokenTypNone; if (first) t->m_type = TokenTypNone;
t->m_IdKeyWord = GetKeyWord(token); t->m_keywordId = GetKeyWord(token);
if (t->m_IdKeyWord > 0) t->m_type = TokenTypKeyWord; if (t->m_keywordId > 0) t->m_type = TokenTypKeyWord;
else GetKeyDefNum(token, t) ; // treats DefineNum else GetDefineNum(token, t) ; // treats DefineNum
return t; return t;
} }
@ -459,9 +461,9 @@ std::unique_ptr<CBotToken> CBotToken::CompileTokens(const std::string& program)
if (tokenbase == nullptr) return nullptr; if (tokenbase == nullptr) return nullptr;
tokenbase->m_start = pos; tokenbase->m_start = pos;
pos += tokenbase->m_Text.length(); pos += tokenbase->m_text.length();
tokenbase->m_end = pos; tokenbase->m_end = pos;
pos += tokenbase->m_Sep.length(); pos += tokenbase->m_sep.length();
const char* pp = p; const char* pp = p;
while (nullptr != (nxt = NextToken(p, false))) while (nullptr != (nxt = NextToken(p, false)))
@ -472,7 +474,7 @@ std::unique_ptr<CBotToken> CBotToken::CompileTokens(const std::string& program)
nxt->m_start = pos; nxt->m_start = pos;
pos += (p - pp); // total size pos += (p - pp); // total size
nxt->m_end = pos - nxt->m_Sep.length(); nxt->m_end = pos - nxt->m_sep.length();
pp = p; pp = p;
} }
@ -491,13 +493,13 @@ int CBotToken::GetKeyWord(const std::string& w)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool CBotToken::GetKeyDefNum(const std::string& name, CBotToken* token) bool CBotToken::GetDefineNum(const std::string& name, CBotToken* token)
{ {
if (m_defineNum.count(name) == 0) if (m_defineNum.count(name) == 0)
return false; return false;
token->m_type = TokenTypDef; token->m_type = TokenTypDef;
token->m_IdKeyWord = m_defineNum[name]; token->m_keywordId = m_defineNum[name];
return true; return true;
} }

View File

@ -31,7 +31,7 @@
* *
* A CBot program starts as a text string. This string is first transformed into a list of tokens. * A CBot program starts as a text string. This string is first transformed into a list of tokens.
* *
* \section Example Example * \section Tokens Example tokens
* This code: * This code:
* \code * \code
* int var = 3 * ( pos.y + x ); * int var = 3 * ( pos.y + x );
@ -59,169 +59,172 @@
* "Hello world" * "Hello world"
* ; * ;
* \endcode * \endcode
*
* \section Usage Example usage
* \code
* std::unique_ptr<CBotToken> tokens = CBotToken::CompileTokens(program);
* CBotToken* token = tokens.get();
* while(token != nullptr)
* {
* printf("%s\n", token->GetString());
*
* token = token->GetNext();
* }
* \endcode
*/ */
class CBotToken class CBotToken
{ {
public: public:
/**
/*! * \brief Default constructor
* \brief CBotToken Default Constructor.
*/ */
CBotToken(); CBotToken();
CBotToken(const CBotToken* pSrc); /**
CBotToken(const std::string& mot, * \brief Copy constructor
*/
CBotToken(const CBotToken& pSrc);
/**
* \brief Constructor
*
* \param token The string this token represents
* \param sep All separators that appeared after this token
* \param start Beginning location in the source code of this token
* \param end Ending location in the source code of this token
*/
CBotToken(const std::string& text,
const std::string& sep = "", const std::string& sep = "",
int start=0, int start = 0,
int end=0); int end = 0);
/*! /**
* \brief ~CBotToken Destructor. Be careful when you delete a CBotToken that * \brief Destructor
* is in a linked list all the following CBotToken will be deleted too. *
* Be careful! This destroys the whole linked list of tokens
*
* Never call in the middle of the sequence - always on the first token in the list
*/ */
~CBotToken(); ~CBotToken();
/*! /**
* \brief GetType Return the token type or the keyword id. * \brief Return the token type or the keyword id
* \return The token type or the keyword id. * \return A value from ::TokenType. For ::TokenTypKeyWord, returns the keyword ID instead.
*/ */
int GetType(); int GetType();
/*! /**
* \brief GetString Return the token string. * \brief Return the token string
* \return The token string if a string has been set. An empty string * \return The string associated with this token
* otherwise.
*/ */
std::string GetString(); std::string GetString();
/*! /**
* \brief SetString Set the token string. * \brief Set the token string
* \param [in] name The new string to set. * \param The new string to set
*/ */
void SetString(const std::string& name); void SetString(const std::string& name);
/*! /**
* \brief GetSep Return the token separator. * \brief Return the beginning location of this token in the original program string
* \return The token separator a separator has been set. An empty separator
* otherwise.
*/
std::string GetSep();
/*!
* \brief GetStart Return the start position of the string token in the
* original CBotProgram.
* \return The start position of the string token or -1 if no string has
* been set.
*/ */
int GetStart(); int GetStart();
/*! /**
* \brief GetEnd Return the end position of the string token in the * \brief Return the ending location of this token in the original program string
* original CBotProgram.
* \return The start position of the string token or -1 if no string has
* been set.
*/ */
int GetEnd(); int GetEnd();
/*! /**
* \brief GetNext Gives the next CBotToken in the list. * \brief Return the next token in the linked list
* \return The next CBotToken if set nullptr otherwise. * \return The next CBotToken in the list, of nullptr if this is the last one
*/ */
CBotToken* GetNext(); CBotToken* GetNext();
/*! /**
* \brief GetPrev Gives the previous CBotToken in the list. * \brief Return the previous token in the linked list
* \return The previous CBotToken if set nullptr otherwise. * \return The previous CBotToken in the list, of nullptr if this is the first one
*/ */
CBotToken* GetPrev(); CBotToken* GetPrev();
/*! /**
* \brief SetPos Set the token position in the CBot program. * \brief SetPos Set the token position in the CBot program
* \param [in] start The start position of the token. * \param start The start position of the token
* \param [in] end The end position of the token. * \param end The end position of the token
*/ */
void SetPos(int start, int end); void SetPos(int start, int end);
/*! /**
* \brief GetIdKey Get the token id key. * \brief Get the keyword id
* \return The id key. * \return The keyword id, see ::CBotTokenId
*/ */
long GetIdKey(); long GetKeywordId();
/*! /**
* \brief operator = * \brief Copy operator
* \param [in] src The CBotToken to copy.
* \return The CBotToken with the copied value.
*/ */
const CBotToken& operator=(const CBotToken& src); const CBotToken& operator=(const CBotToken& src);
/*! /**
* \brief CompileTokens This function will transform the entire CBot program * \brief Transforms a CBot program from a string to a list of tokens
* in CBotToken. If an error occured during the processing an error number * \param prog The program string
* will be set. Each CBotToken will be linked with the previous one and the * \return The first token in the linked list
* next one.
* \param [in] p The program string.
* \param [out] error The error code.
* \return The first token of the linked liste.
* \todo Replace the error code by an enum.
*/ */
static std::unique_ptr<CBotToken> CompileTokens(const std::string& p); static std::unique_ptr<CBotToken> CompileTokens(const std::string& prog);
/*! /**
* \brief DefineNum This function define a language keyword with an associated * \brief Define a new constant
* number. * \param name Name of the constant
* \param [in] name The new word to define. * \param val Value of the constant
* \param [in] val The number associated with the keyword. * \return true on success, false if already defined
* \return Ture if the number is available false oterhwise.
*/ */
static bool DefineNum(const std::string& name, long val); static bool DefineNum(const std::string& name, long val);
/*! /**
* \brief Free Free the array created with DefineNum. * \brief Clear the list of defined constants
* \see DefineNum * \see DefineNum()
*/ */
static void Free(); static void ClearDefineNum();
private: private:
/*! /**
* \brief NextToken Looking for the next token in the string. The string must * \brief Find the next token in the string
* not start with separators. The separator is part of the previous token. *
* \param [in] program The program string. * The string must not start with separators. The separator is part of the previous token.
* \param [out] error The error code. *
* \param [in] first True if this is the first call false othewise. * \param [in, out] program The program string, modified to point at the next token
* \return A CBotTOken. * \param first true if this is the first call (beginning of the program string)
* \return A processed CBotToken
*/ */
static CBotToken* NextToken(const char*& program, bool first); static CBotToken* NextToken(const char*& program, bool first);
private: private:
//! The next token in the linked list //! The next token in the linked list
CBotToken* m_next; // following in the list CBotToken* m_next;
//! The previous token in the linked list //! The previous token in the linked list
CBotToken* m_prev; CBotToken* m_prev;
//! The token type //! The token type
TokenType m_type; // type of Token TokenType m_type;
//! The id of the keyword //! The id of the keyword
long m_IdKeyWord; long m_keywordId;
//! The token string //! The token string
std::string m_Text; std::string m_text;
//! The token separator //! The separator that appeared after this token
std::string m_Sep; std::string m_sep;
//! The strat position of the token in the CBotProgram //! The strat position of the token in the CBotProgram
int m_start; int m_start;
//! The end position of the token in the CBotProgram //! The end position of the token in the CBotProgram
int m_end; int m_end;
//! Map of all predefined constants (see DefineNum()) //! Map of all defined constants (see DefineNum())
static std::map<std::string, long> m_defineNum; static std::map<std::string, long> m_defineNum;
/*! /**
* \brief Check if the word is a keyword * \brief Check if the word is a keyword
* \param w The word to check * \param w The word to check
* \return the keyword ID, or -1 if this is not a keyword * \return the keyword ID (::CBotTokenId), or -1 if this is not a keyword
*/ */
static int GetKeyWord(const std::string& w); static int GetKeyWord(const std::string& w);
@ -231,33 +234,29 @@ private:
* \param token Token that we are working on, will be filled with data about found constant * \param token Token that we are working on, will be filled with data about found constant
* \return true if the constant was found, false otherwise * \return true if the constant was found, false otherwise
*/ */
static bool GetKeyDefNum(const std::string& name, CBotToken* token); static bool GetDefineNum(const std::string& name, CBotToken* token);
}; };
/*! /**
* \brief IsOfType This function tell if a token is of a specific type. * \brief Check if this token is of specified type
* \param [in] p The token to compare. * \param p The token to compare
* \param [in] type1 First token type to comapre to the token. * \param type1 First token type to comapre to the token
* \param [in] type2 Second token type to comapre to the token. * \param type2 Second token type to comapre to the token
* \return True if the type of the token match one of a parameter. * \return true if the type of the token matches one of the parameters
*/ */
extern bool IsOfType(CBotToken* &p, int type1, int type2 = -1); extern bool IsOfType(CBotToken* &p, int type1, int type2 = -1);
/*! /**
* \brief IsOfType This function tell if a token is of a specific type. * \brief Check if this token is of specified type
* \param [in] p The token to compare. * \param p The token to compare
* \param [in] type1 The list of token type to comapre to the token. * \param type1 The list of token types to comapre to the token, 0-terminated
* \return True if the type of the token match one of a parameter. * \return true if the type of the tokens matched one of the parameters
*/ */
extern bool IsOfTypeList(CBotToken* &p, int type1, ...); extern bool IsOfTypeList(CBotToken* &p, int type1, ...);
/** /**
* \brief LoadString Maps given ID to its string equivalent. * \brief Maps given ID to its string equivalent
* \param id Provided identifier. * \param id Token type identifier
* \return String if found, else NullString. * \return String if found, empty string otherwise
*/ */
const std::string& LoadString(TokenId id); const std::string& LoadString(TokenId id);