Hi, all.
Today, I'm thinking how to refactor the replacement function in
In Tokenizer.cpp GetToken() function
inline const wxString& ThisOrReplacement(const wxString& str) const
{
ConfigManagerContainer::StringToStringMap::const_iterator it = s_Replacements.find(str);
if (it != s_Replacements.end())
return it->second;
return str;
}
I think this function is some kind too simple. At least, it can do a search, then a replacement.
(I have exam the code in
ctags and its manual, especially in it's code to do Macro replacement)
Here
http://ctags.sourceforge.net/ctags.html#OPERATIONAL%20DETAILS−I identifier−list
Specifies a list of identifiers which are to be specially handled while parsing C and C++ source files. This option is specifically provided to handle special cases arising through the use of preprocessor macros.
When the identifiers listed are simple identifiers, these identifiers will be ignored during parsing of the source files.
If an identifier is suffixed with a ’+’ character, ctags will also ignore any parenthesis-enclosed argument list which may immediately follow the identifier in the source files.
If two identifiers are separated with the ’=’ character, the first identifiers is replaced by the second identifiers for parsing purposes.
So, at least, we can do the same thing like in Ctags.
In the option.c of Ctags source code, there are the related codes to doing identifier replacement.
/* Determines whether or not "name" should be ignored, per the ignore list.
*/
extern boolean isIgnoreToken (
const char *const name, boolean *const pIgnoreParens,
const char **const replacement)
{
boolean result = FALSE;
if (Option.ignore != NULL)
{
const size_t nameLen = strlen (name);
unsigned int i;
if (pIgnoreParens != NULL)
*pIgnoreParens = FALSE;
for (i = 0 ; i < stringListCount (Option.ignore) ; ++i)
{
vString *token = stringListItem (Option.ignore, i);
if (strncmp (vStringValue (token), name, nameLen) == 0)
{
const size_t tokenLen = vStringLength (token);
if (nameLen == tokenLen)
{
result = TRUE;
break;
}
else if (tokenLen == nameLen + 1 &&
vStringChar (token, tokenLen - 1) == '+')
{
result = TRUE;
if (pIgnoreParens != NULL)
*pIgnoreParens = TRUE;
break;
}
else if (vStringChar (token, nameLen) == '=')
{
if (replacement != NULL)
*replacement = vStringValue (token) + nameLen + 1;
break;
}
}
}
}
return result;
}
Here is what we can do in our Code completion code:
inline const wxString& ThisOrReplacement(const wxString& str) const
{
ConfigManagerContainer::StringToStringMap::const_iterator it = s_Replacements.find(str);
if (it != s_Replacements.end()){
//Here we should example the "it->second"
// if it is a "=new_token" string, the current_token should be replaced by "new_token"
// if it is a "-" , the current string should be ignored, then we should return next token
// if it is a "+", the next "parenthesis-enclosed argument list" should be ignored
// if it match any other pre-defined string grama, we will do other thing , eg, expand the current token to two tokens...
//......
//return it->second;
}
return str;
}
Any Comments?