【发布时间】:2016-08-04 14:30:32
【问题描述】:
期望的行为:
'#'之后的所有内容都将被忽略(#= 评论)。- 空行不会创建标记。
- '{' 创建一个
BLOCK_OPEN类型的令牌。- '}' 创建
BLOCK_CLOSE类型的令牌。- '=' 创建一个
EQUALS类型的令牌。- 其他所有内容都会创建
LABEL类型的令牌。- 令牌不能有空格
对于大多数输入,我的标记化功能完美无缺。除了一个错误:
show_position = { x=-9 y =78 }
注意没有空格!
返回的向量在"x" 和"-9" 之间缺少"="。
如何修复此错误?我尝试调试,但无法弄清楚我搞砸了什么。一双新鲜的眼睛是一种恩惠。
这就是我标记化的方式:
std::vector<Token> tokenizeLine(const std::string str)
{
std::vector<Token> tokens;
std::string::size_type start = 0;
std::string::size_type end = 0;
while (end != std::string::npos)
{
enum POSES
{
EQUALS,
OPEN,
CLOSE,
SPACE,
EOL,
RETURN,
TAB,
COMMENT,
POSES_SIZE
};
std::string::size_type pos[] =
{
str.find('=', start),
str.find('{', start),
str.find('}', start),
str.find(' ', start),
str.find('\n', start),
str.find('\r', start),
str.find('\t', start),
str.find('#', start)
};
end = *std::min_element(pos, &pos[POSES_SIZE]);
switch (str[start])
{
case('=') :
tokens.push_back(Token(Token::EQUALS, "="));
break;
case('{') :
tokens.push_back(Token(Token::BLOCK_OPEN, "{"));
break;
case('}') :
tokens.push_back(Token(Token::BLOCK_CLOSE, "}"));
break;
case(' ') :
case('\n') :
case('\r') :
case('\t'):
break;
case('#') :
return tokens;
break;
default:
if(str.substr(start, end - start).length() > 0)
tokens.push_back(Token(Token::LABEL, str.substr(start, end - start)));
}
// If at end, use start=maxSize. Else use start=end+delimiter.
start = ((end > (std::string::npos - sizeof(char)))
? std::string::npos : end + sizeof(char));
}
return tokens;
}
您可以在家中舒适地跑步:
std::vector<std::string> tokenizeLine(const std::string str)
{
std::vector<std::string> tokens;
std::string::size_type start = 0;
std::string::size_type end = 0;
while (end != std::string::npos)
{
enum POSES // Deliminators
{
EQUALS,
OPEN,
CLOSE,
SPACE,
EOL,
RETURN,
TAB,
COMMENT,
POSES_SIZE
};
std::string::size_type pos[] =
{
str.find('=', start),
str.find('{', start),
str.find('}', start),
str.find(' ', start),
str.find('\n', start),
str.find('\r', start),
str.find('\t', start),
str.find('#', start)
};
end = *std::min_element(pos, &pos[POSES_SIZE]);
switch (str[start])
{
case('=') :
tokens.push_back("=");
break;
case('{') :
tokens.push_back("{");
break;
case('}') :
tokens.push_back("}");
break;
case(' ') :
case('\n') :
case('\r') :
case('\t'):
break;
case('#') :
return tokens;
break;
default:
if(str.substr(start, end - start).length() > 0)
tokens.push_back(str.substr(start, end - start));
}
// If at end, use start=maxSize. Else use start=end+delimiter.
start = ((end > (std::string::npos - sizeof(char)))
? std::string::npos : end + sizeof(char));
}
return tokens;
}
【问题讨论】:
-
@NathanOliver 给定的代码没有按预期运行,因此在代码审查中会偏离主题。
-
抱歉不清楚。我编辑了问题以澄清问题。
-
@IvanRubinson 第二个代码运行良好:ideone.com/i1tRr8 请提供 MCVE。
-
@alexeykuzmin0 注意空格!省略空格时会发生特定错误。您的粘贴包含我的字符串没有的空格。
标签: c++ string tokenize stdstring lexer