从lex中的while循环中分解出来

时间:2012-06-22 00:39:10

标签: c lex

所以我在Linux中使用lex工具并陷入了一个令人尴尬的位置,我无法摆脱while循环。

例如:我写道;

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

}

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

P.S#感谢大家的回答;在作业提交日期之前紧张和睡眠不足;顺便说一句 - 我已经找到了答案。

4 个答案:

答案 0 :(得分: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在交换机的范围内执行此操作)。
  3. printf()语句应打印换行符,以便显示数据。
  4. 由于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)时,你正在编写一个无限循环。你有责任考虑循环是否真的是无限的。如果不是,那么你的目标是能够在循环的顶部进行测试,以控制是否有另一个循环到循环。

答案 1 :(得分: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;
    }
}

答案 2 :(得分:0)

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

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

如果您无论如何都不工作,如果您知道所写程序的名称,可以输入终端:

pkill -9 [insert name of program here]

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

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

top

将显示终端中当前正在运行的所有进程。找到正在运行的程序的名称后,按q退出顶部,然后在上面键入您在顶部识别的名称的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.]

答案 3 :(得分:0)

要添加大卫的答案,这是一个不同的版本:

do
{
    int x = yylex();

    if (!x)
        break;

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

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