标签和 'goto' 的可接受使用?

Acceptable use of a label and 'goto'?

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

Token token;

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

MakeToken:
    // write the token

这是可以接受的标签使用方式吗?还是有更好的方法?我已经学会将标签视为一种糟糕的做法,但它们肯定有用途(否则它们不会在标准中实现?)。谢谢

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

我唯一一次在 C++ 中发现一个稍微令人反感的 goto 案例是在一个复杂的状态机中,开发人员非常小心不要弄乱本地状态。

通常,解析器(或更具体地说,分词器)是我进行意大利面式编码的最后一个地方——如果有的话,这需要以更实用的方式使用 C++。

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

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

一般情况下,当我们想一次break几个作用域的时候,就意味着我们可以做子函数;类似于:

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() != '[=11=]')
{
   if (HandleChar(nextChar())) {
       break;
   }
}
// ...