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;
if (p->GetType() == TokenTypDef)
{
inst->m_valint = p->GetIdKey();
inst->m_valint = p->GetKeywordId();
}
else
{

View File

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

View File

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

View File

@ -20,6 +20,7 @@
#include "CBot/CBotToken.h"
#include <cstdarg>
#include <cassert>
//! \brief Keeps the string corresponding to keyword ID
//! Map is filled with id-string pars that are needed for CBot language parsing
@ -136,20 +137,20 @@ CBotToken::CBotToken()
m_next = nullptr;
m_prev = nullptr;
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_prev = nullptr;
m_Text.clear();
m_Sep.clear();
m_text.clear();
m_sep.clear();
m_type = TokenTypNone;
m_IdKeyWord = 0;
m_keywordId = 0;
m_start = 0;
m_end = 0;
@ -158,10 +159,10 @@ CBotToken::CBotToken(const CBotToken* pSrc)
{
m_type = pSrc->m_type;
m_IdKeyWord = pSrc->m_IdKeyWord;
m_keywordId = pSrc->m_IdKeyWord;
m_Text = pSrc->m_Text;
m_Sep = pSrc->m_Sep;
m_text = pSrc->m_Text;
m_sep = pSrc->m_Sep;
m_start = pSrc->m_start;
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_Sep = sep; // separator
m_text = text; // word (mot) found as token
m_sep = sep; // separator
m_next = nullptr;
m_prev = nullptr;
m_start = start;
m_end = end;
m_type = TokenTypVar; // at the beginning a default variable type
m_IdKeyWord = -1;
m_keywordId = -1;
}
////////////////////////////////////////////////////////////////////////////////
CBotToken::~CBotToken()
{
delete m_next; // recursive
m_next = nullptr;
assert(m_prev == nullptr);
if (m_next != nullptr)
{
m_next->m_prev = nullptr;
delete m_next; // recursive
m_next = nullptr;
}
}
////////////////////////////////////////////////////////////////////////////////
void CBotToken::Free()
void CBotToken::ClearDefineNum()
{
m_defineNum.clear();
}
@ -202,11 +210,11 @@ const CBotToken& CBotToken::operator=(const CBotToken& src)
m_next = nullptr;
m_prev = nullptr;
m_Text = src.m_Text;
m_Sep = src.m_Sep;
m_text = src.m_text;
m_sep = src.m_sep;
m_type = src.m_type;
m_IdKeyWord = src.m_IdKeyWord;
m_keywordId = src.m_keywordId;
m_start = src.m_start;
m_end = src.m_end;
@ -217,14 +225,14 @@ const CBotToken& CBotToken::operator=(const CBotToken& src)
int CBotToken::GetType()
{
if (this == nullptr) return 0;
if (m_type == TokenTypKeyWord) return m_IdKeyWord;
if (m_type == TokenTypKeyWord) return m_keywordId;
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()
{
return m_Text;
}
////////////////////////////////////////////////////////////////////////////////
std::string CBotToken::GetSep()
{
return m_Sep;
return m_text;
}
////////////////////////////////////////////////////////////////////////////////
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 (first) t->m_type = TokenTypNone;
t->m_IdKeyWord = GetKeyWord(token);
if (t->m_IdKeyWord > 0) t->m_type = TokenTypKeyWord;
else GetKeyDefNum(token, t) ; // treats DefineNum
t->m_keywordId = GetKeyWord(token);
if (t->m_keywordId > 0) t->m_type = TokenTypKeyWord;
else GetDefineNum(token, t) ; // treats DefineNum
return t;
}
@ -459,9 +461,9 @@ std::unique_ptr<CBotToken> CBotToken::CompileTokens(const std::string& program)
if (tokenbase == nullptr) return nullptr;
tokenbase->m_start = pos;
pos += tokenbase->m_Text.length();
pos += tokenbase->m_text.length();
tokenbase->m_end = pos;
pos += tokenbase->m_Sep.length();
pos += tokenbase->m_sep.length();
const char* pp = p;
while (nullptr != (nxt = NextToken(p, false)))
@ -472,7 +474,7 @@ std::unique_ptr<CBotToken> CBotToken::CompileTokens(const std::string& program)
nxt->m_start = pos;
pos += (p - pp); // total size
nxt->m_end = pos - nxt->m_Sep.length();
nxt->m_end = pos - nxt->m_sep.length();
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)
return false;
token->m_type = TokenTypDef;
token->m_IdKeyWord = m_defineNum[name];
token->m_keywordId = m_defineNum[name];
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.
*
* \section Example Example
* \section Tokens Example tokens
* This code:
* \code
* int var = 3 * ( pos.y + x );
@ -59,169 +59,172 @@
* "Hello world"
* ;
* \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
{
public:
/*!
* \brief CBotToken Default Constructor.
/**
* \brief Default constructor
*/
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 = "",
int start=0,
int end=0);
int start = 0,
int end = 0);
/*!
* \brief ~CBotToken Destructor. Be careful when you delete a CBotToken that
* is in a linked list all the following CBotToken will be deleted too.
/**
* \brief Destructor
*
* 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();
/*!
* \brief GetType Return the token type or the keyword id.
* \return The token type or the keyword id.
/**
* \brief Return the token type or the keyword id
* \return A value from ::TokenType. For ::TokenTypKeyWord, returns the keyword ID instead.
*/
int GetType();
/*!
* \brief GetString Return the token string.
* \return The token string if a string has been set. An empty string
* otherwise.
/**
* \brief Return the token string
* \return The string associated with this token
*/
std::string GetString();
/*!
* \brief SetString Set the token string.
* \param [in] name The new string to set.
/**
* \brief Set the token string
* \param The new string to set
*/
void SetString(const std::string& name);
/*!
* \brief GetSep Return the token separator.
* \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.
/**
* \brief Return the beginning location of this token in the original program string
*/
int GetStart();
/*!
* \brief GetEnd Return the end 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.
/**
* \brief Return the ending location of this token in the original program string
*/
int GetEnd();
/*!
* \brief GetNext Gives the next CBotToken in the list.
* \return The next CBotToken if set nullptr otherwise.
/**
* \brief Return the next token in the linked list
* \return The next CBotToken in the list, of nullptr if this is the last one
*/
CBotToken* GetNext();
/*!
* \brief GetPrev Gives the previous CBotToken in the list.
* \return The previous CBotToken if set nullptr otherwise.
/**
* \brief Return the previous token in the linked list
* \return The previous CBotToken in the list, of nullptr if this is the first one
*/
CBotToken* GetPrev();
/*!
* \brief SetPos Set the token position in the CBot program.
* \param [in] start The start position of the token.
* \param [in] end The end position of the token.
/**
* \brief SetPos Set the token position in the CBot program
* \param start The start position of the token
* \param end The end position of the token
*/
void SetPos(int start, int end);
/*!
* \brief GetIdKey Get the token id key.
* \return The id key.
/**
* \brief Get the keyword id
* \return The keyword id, see ::CBotTokenId
*/
long GetIdKey();
long GetKeywordId();
/*!
* \brief operator =
* \param [in] src The CBotToken to copy.
* \return The CBotToken with the copied value.
/**
* \brief Copy operator
*/
const CBotToken& operator=(const CBotToken& src);
/*!
* \brief CompileTokens This function will transform the entire CBot program
* in CBotToken. If an error occured during the processing an error number
* will be set. Each CBotToken will be linked with the previous one and the
* 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.
/**
* \brief Transforms a CBot program from a string to a list of tokens
* \param prog The program string
* \return The first token in the linked list
*/
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
* number.
* \param [in] name The new word to define.
* \param [in] val The number associated with the keyword.
* \return Ture if the number is available false oterhwise.
/**
* \brief Define a new constant
* \param name Name of the constant
* \param val Value of the constant
* \return true on success, false if already defined
*/
static bool DefineNum(const std::string& name, long val);
/*!
* \brief Free Free the array created with DefineNum.
* \see DefineNum
/**
* \brief Clear the list of defined constants
* \see DefineNum()
*/
static void Free();
static void ClearDefineNum();
private:
/*!
* \brief NextToken Looking for the next token in the string. The string must
* not start with separators. The separator is part of the previous token.
* \param [in] program The program string.
* \param [out] error The error code.
* \param [in] first True if this is the first call false othewise.
* \return A CBotTOken.
/**
* \brief Find the next token in the string
*
* The string must not start with separators. The separator is part of the previous token.
*
* \param [in, out] program The program string, modified to point at the next token
* \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);
private:
//! The next token in the linked list
CBotToken* m_next; // following in the list
CBotToken* m_next;
//! The previous token in the linked list
CBotToken* m_prev;
//! The token type
TokenType m_type; // type of Token
TokenType m_type;
//! The id of the keyword
long m_IdKeyWord;
long m_keywordId;
//! The token string
std::string m_Text;
//! The token separator
std::string m_Sep;
std::string m_text;
//! The separator that appeared after this token
std::string m_sep;
//! The strat position of the token in the CBotProgram
int m_start;
//! The end position of the token in the CBotProgram
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;
/*!
/**
* \brief Check if the word is a keyword
* \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);
@ -231,33 +234,29 @@ private:
* \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
*/
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.
* \param [in] p The token to compare.
* \param [in] type1 First token type to comapre to the token.
* \param [in] type2 Second token type to comapre to the token.
* \return True if the type of the token match one of a parameter.
/**
* \brief Check if this token is of specified type
* \param p The token to compare
* \param type1 First 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 matches one of the parameters
*/
extern bool IsOfType(CBotToken* &p, int type1, int type2 = -1);
/*!
* \brief IsOfType This function tell if a token is of a specific type.
* \param [in] p The token to compare.
* \param [in] type1 The list of token type to comapre to the token.
* \return True if the type of the token match one of a parameter.
/**
* \brief Check if this token is of specified type
* \param p The token to compare
* \param type1 The list of token types to comapre to the token, 0-terminated
* \return true if the type of the tokens matched one of the parameters
*/
extern bool IsOfTypeList(CBotToken* &p, int type1, ...);
/**
* \brief LoadString Maps given ID to its string equivalent.
* \param id Provided identifier.
* \return String if found, else NullString.
* \brief Maps given ID to its string equivalent
* \param id Token type identifier
* \return String if found, empty string otherwise
*/
const std::string& LoadString(TokenId id);