我还是 C++ 新手,目前正在阅读 Bjarne Stroustrup:使用 C++ 的原理和实践
我正在为终端计算器编写词法分析器和解析器作为练习。解析器确定表示表达式的字符串中单个字符的类型,并将某种类型值分配给标记。下面是确定类型的函数片段(我没有包含整个函数或所有情况以使代码更短)。
switch(c)
{
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '.':
return 'n'; // 'n' for number
case '*': case '/':
return 'm'; // m for multiplication or division
case '(': case ')':
return 'p'; // p for parenthesis
case ' ': // whitespace
return 'w';
default:
throw std::invalid_argument("Invalid token: A non-valid character was passed to determineKind");
}
我使用字符来表示标记类型的原因是因为我可以稍后使用简单的 switch 语句,而不是使用表示类型的字符串的可读性较差的 if 语句。
但同时“n”、“m”、“p”和“w”是魔术常量,这使得解析器内的代码再次变得不太可读。有没有一种方法可以使用带有“数字”、“空格”和“括号”等全名的 switch 语句来使一切变得更简单?
这是
enum
或更好的 enum class
的主要用例:
enum class TokenType
{
Number,
Multiplication,
Parenthesis,
Whitespace
};
TokenType parse(char c)
{
switch(c)
{
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '.':
return TokenType::Number;
case '*': case '/':
return TokenType::Multiplication;
case '(': case ')':
return TokenType::Parenthesis;
case ' ':
return TokenType::Whitespace;
default:
throw std::invalid_argument("Invalid token: A non-valid character was passed to determineKind");
}
}
通常,您会使用枚举:
enum class Token
{
Invalid,
Number,
Whitespace,
Parenthesis
};