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

Acceptable use of a label and 'goto'?

本文关键字:可接受 goto 标签      更新时间:2023-10-16

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

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

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

一般来说,当我们想一次打破几个作用域时,意味着我们可以制作子函数;类似于:

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

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

我唯一一次在C++中发现goto的一个稍微令人反感的例子是在一个复杂的状态机中,开发人员非常小心地避免破坏本地状态。

一般来说,解析器(或者更具体地说,标记化器(是我最不愿意使用意大利面条编码的地方——如果有什么不同的话,这需要以更实用的方式使用C++。

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

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