首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在lex中中断while循环

在lex中中断while循环
EN

Stack Overflow用户
提问于 2012-06-22 08:39:10
回答 4查看 1.9K关注 0票数 0

所以我在linux中使用了lex工具,陷入了一个尴尬的境地,我无法从while循环中解脱出来。

例如:我写了;

代码语言:javascript
复制
while(1)
{
 int x = yylex();
 switch(x):
  case(ID):printf("ID");
  case(NUM):printf("NUM");

}

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

P.S#感谢你所有的答案;在作业提交日期之前的紧张和缺乏睡眠;顺便说一句-我已经想好了答案。

EN

回答 4

Stack Overflow用户

发布于 2012-06-22 10:15:53

我发现C代码有一些问题,独立于yylex()函数内部发生的事情。您将代码引用为:

代码语言:javascript
复制
while(1)
{
  int x = yylex();
  switch(x):
  case(ID):printf("ID");
  case(NUM):printf("NUM");
}

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

代码语言:javascript
复制
while(1)
{   
    int x = yylex();
    switch(x)
    {   
    case(ID):printf("ID");
    case(NUM):printf("NUM");
    }   
}

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

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

< break; >G218

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

代码语言:javascript
复制
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分析器,使其不能正确终止。我选择不让默认情况终止循环,因为循环的边界是返回0的yylex()

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

票数 2
EN

Stack Overflow用户

发布于 2012-06-22 10:16:15

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

代码语言:javascript
复制
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;
    }
}
票数 1
EN

Stack Overflow用户

发布于 2012-06-22 08:58:41

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

尝试在终端中同时键入“Ctrl”和“c”。如果这不起作用,使用'Ctrl‘+ 'z’。如果你不介意让进程在后台停止,直到计算机关闭,它完全消失,在Ctrl +Z之后,你不需要做任何其他事情。如果Ctrl +C起作用了,那么程序就结束了,你就没问题了。

如果,无论出于什么原因,都不起作用,如果你知道你写的程序的名称,你可以在终端中键入:

代码语言:javascript
复制
pkill -9 [insert name of program here]

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

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

代码语言:javascript
复制
top

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

代码语言:javascript
复制
ps -a

在运行(和停止)程序的终端会话中,标记为“已停止”的作业很可能就是您的作业。同样,使用上面的pkill命令将杀死它。如果,不管出于什么原因,你知道进程ID,但是不知道它的名字(我不知道你为什么知道,但是这就对了…),你可以使用命令'kill‘而不是'pkill’(关于如何使用这些命令的说明在互联网上到处都是,所以我不会在这里提及它们。它们还提供了有用的帮助手册页面,可通过以下方式访问:

代码语言:javascript
复制
man [the name of the program you want help with; 'pkill' or 'kill', in this case.]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11148797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档