是否可以使用标签和“转到”?

时间:2015-07-04 10:32:22

标签: c++ label goto

我正在为编译器编写一个tokenizer。我有一个循环遍历字符的while循环,然后是一个检查某些条件的开关。然后我需要退出两个块来写令牌:

Token token;

while (peekChar() != '\0')
{
    switch (c = nextChar())
    {
        case '(':
            token = Token(TOKEN_LEFT_PAREN, currentLine);
            goto MakeToken;
        // ... every other character, some with lots of logic
    }
}

MakeToken:
    // write the token

这是标签的可接受用途,还是有更好的方法?我已经学会了将标签视为可怕的做法,但肯定必须使用它们(或者它们不会在标准中实现?)。感谢。

3 个答案:

答案 0 :(得分:2)

通常,当我们想要一次打破多个范围时,这意味着我们可以创建子功能;类似的东西:

bool HandleChar(char c)
{
    switch (c)
    {
        case '(': {
                Token token = Token(TOKEN_LEFT_PAREN, currentLine);
                return true;
        }
        // ... every other character, some with lots of logic
    }
}

然后:

while (peekChar() != '\0')
{
   if (HandleChar(nextChar())) {
       break;
   }
}
// ...

答案 1 :(得分:1)

您可以在此处使用break实现相同的操作,而无需使用goto

我唯一一次在C ++中发现goto只有轻微令人反感的情况是在一个复杂的状态机中,开发人员非常小心,不要搞乱本地状态。

通常,解析器(或更具体地说,一个标记器)是我去意大利面条编码的最后一个地方 - 如果有的话,这就要求以更实用的方式使用C ++。

答案 2 :(得分:1)

我相信这是goto被接受的极少数例子之一,但你可以使用一个标志:

Token token;
bool flag = true;
while ((peekChar() != '\0') && flag)
{
    switch (c = nextChar())
    {
        case '(':
            token = Token(TOKEN_LEFT_PAREN, currentLine);
            flag = false;
        // ... every other character, some with lots of logic
    }
}