0

所以我在linux中使用了lex工具,陷入了尴尬的境地,我无法摆脱while循环。

例如:我写了;

while(1)
{
 int x = yylex();
 switch(x):
  case(ID):printf("ID");
  case(NUM):printf("NUM");

}

现在我正在使用 yyin 从文件中读取;问题是 while 循环在读取整个文件后并没有失败,并且一直在终端要求更多输入。因此,在调用 while 循环后我无法调用其他函数。我知道我缺少一些基本的东西,如果有人能提供对这个问题的洞察力,那就太好了。

PS#谢谢大家的回答;作业提交日期前的紧张和睡眠不足;顺便说一句-我已经想出了我的答案。

4

4 回答 4

2

我发现 C 代码存在一些问题,与yylex()函数内部发生的情况无关。您将代码引用为:

while(1)
{
  int x = yylex();
  switch(x):
  case(ID):printf("ID");
  case(NUM):printf("NUM");
}

这显然不是您编译的源代码,因为它不能作为 C 语言接受。您需要将第一个冒号(之后switch(x))替换为左大括号{,并且最后需要另一个右大括号},以产生:

while(1)
{   
    int x = yylex();
    switch(x)
    {   
    case(ID):printf("ID");
    case(NUM):printf("NUM");
    }   
}

这是语法上有效的 C 代码,但仍然存在问题:

  1. break;每个之后可能应该有一个case
  2. 可能应该有一个default:子句,它可能用于终止循环(但您不能break在 switch 范围内使用它来执行此操作)。
  3. 语句应该打印一个换行符,printf()以便显示数据。

由于yylex()到达末尾时返回 0,因此您可能应该修改代码,使其更像:

void function(void)
{
    int x;
    while ((x = yylex()) != 0)
    {   
        switch (x)
        {   
        case ID: 
            printf("ID\n");
            break;
        case NUM:
            printf("NUM\n");
            break;
        default:
            printf("Other: %d\n", x); 
            break;
        }   
    }   
}

这至少会向您展示发生了什么,并且没有无限循环,除非您编写了lex分析器以使其无法正确终止。我选择不让默认情况终止循环,因为循环以yylex()返回 0 为界。

当您编写 时while (1),您正在编写一个无限循环。您有责任考虑循环是否真的是无限的。如果不是,那么您的目标应该是能够在循环顶部进行测试,以控制循环是否存在另一个循环。

于 2012-06-22T02:15:53.293 回答
1

yylex() 在输入的逻辑末尾返回 0。尝试这个:

int x = -1;
while(!(x == 0))
{
    x = yylex();
    switch(x):
    {
        case(0): printf("that's all, folks!"); break;
        case(ID): printf("ID"); break;
        case(NUM): printf("NUM"); break;
    }
}
于 2012-06-22T02:16:15.400 回答
0

好吧,虽然我承认我不熟悉 lex 是什么,但我确实对 linux 环境和终端了解不少,所以...

尝试在终端中同时输入“Ctrl”和“c”。如果这不起作用,请使用“Ctrl”+“z”。如果您不介意让进程在后台停止,直到计算机关闭并完全消失,在 Ctrl + Z 之后,您无需执行任何其他操作。如果 Ctrl + C 有效,那么程序就结束了,你很好。

如果无论出于何种原因都不起作用,如果您知道您编写的程序的名称,您可以在终端中输入:

pkill -9 [insert name of program here]

...这将向进程发送一个不可忽视的终止信号,并将其所有内存(RAM-它不会撤消对磁盘所做的更改)返回给父进程。

如果您不知道该程序的名称,但您认为您可能能够识别它,您可以尝试:

top

这将在终端中显示所有当前正在运行的进程。找到仍在运行的程序的名称后,按 q 退出 top,然后使用您在 top 中识别的名称键入上面的 kill 命令。如果您不知道程序的名称,并且 Ctrl + Z 有效,但您不希望停止的作业一直占用其内存,直到您关闭计算机,您可以键入:

ps -a

在您运行(和停止)程序的终端会话中,显示标记为“停止”的作业很可能是您的。同样,使用上面的 pkill 命令将杀死它。如果,出于某种原因,您知道进程 ID 但不知道名称(我不知道您为什么会知道,但您去...),您可以使用命令 'kill' 而不是 'pkill' (说明这些命令的使用方法网上都有,这里就不提了。他们也有帮助手册页,可以通过以下方式访问:

man [the name of the program you want help with; 'pkill' or 'kill', in this case.]
于 2012-06-22T00:58:41.433 回答
0

为了补充大卫的答案,这里有一个不同的版本:

do
{
    int x = yylex();

    if (!x)
        break;

    switch(x):
    {
        case(ID): printf("ID"); break;
        case(NUM): printf("NUM"); break;
    }
} while(1);

这只是为了表明您可以摆脱一段时间(1)。您将 x 保持在本地范围内,并且不会评估第一次传递或不必要的切换。当然,很可能有人会拿出“它不那么可读”的王牌……

于 2012-06-22T03:35:02.390 回答