2

我正在尝试在 C 中创建一个词法分析器。该程序读取另一个程序作为输入以将其转换为标记,源代码在这里-

#include <stdio.h>
#include <conio.h>
#include <string.h>

int main()  {
    FILE *fp;
    char read[50];
    char seprators [] = "\n";
    char *p;
    fp=fopen("C:\\Sum.c", "r");

    clrscr();

    while ( fgets(read, sizeof(read)-1, fp) !=NULL )    {
        //Get the first token
        p=strtok(read, seprators);

        //Get and print other tokens
        while (p!=NULL) {
            printf("%s\n", p);
            p=strtok(NULL, seprators);
        }
    }

    return 0;
}

Sum.c 的内容是——

#include <stdio.h>

int main()  {
    int x;
    int y;
    int sum;

    printf("Enter two numbers\n");
    scanf("%d%d", &x, &y);

    sum=x+y;

    printf("The sum of these numbers is %d", sum);

    return 0;
}

我没有得到正确的输出,只看到一个空白屏幕代替输出。

谁能告诉我我哪里错了??提前非常感谢你..

4

1 回答 1

1

自从这个问题以来,你已经问了几个问题,所以我猜你已经继续前进了。关于您的问题和您的解决方案开始可以帮助其他人开始解决类似问题,有几点需要注意。您还会发现,人们在回答明显是作业的问题时往往反应迟钝。我们经常等到作业截止日期过去。:-)

首先,我注意到您使用了一些特定于 Borland C 编译器的非标准特性,不会使解决方案具有可移植性或通用性。你可以在没有他们的情况下解决问题,这通常是一个不错的选择。例如,您过去#include <conio.h>只是用 a 清除屏幕,clrscr();这可能是不必要的,并且与词法分析器问题无关。

我测试了该程序,并且按照编写它的工作原理!它将文件的所有行转录Sum.cstdout. 如果您只看到一个空白屏幕,那是因为它找不到文件。要么您没有将其写入您的C:\目录,要么使用了不同的名称。正如@WhozCraig 已经提到的,您需要检查文件是否已找到并正确打开

我看到您正在使用C函数strtok将输入划分为标记。在您可以包含在您的代码中的文档中有一些很好的使用示例,这些示例比您的简单案例做得更多。正如@Grijesh Chauhan 所提到的,需要考虑的分隔符多于\n, 或行尾。例如,空格和制表符怎么样。

但是,在程序中,事物并不总是由空格和行分隔。举个例子:

result=(number*scale)+total;

如果我们只使用空格作为分隔符,那么它就不会识别所使用的单词,而只会选择整个表达式,这显然不是分词。我们可以将这些东西添加到分隔符列表中:

char seprators [] = "\n=(*)+;";

然后你的代码也会挑选出这些词。该策略仍然存在缺陷,因为在编程语言中,这些符号也是需要识别的标记。编程语言标记化的问题是标记之间没有明确的分隔符。

这背后有很多理论,但基本上我们必须写下构成我们想要识别的标记基础的模式,而不是查看它们之间的差距,因为正如已经显示的那样,没有任何!这些模式通常写为正则表达式。计算机科学理论告诉我们,我们可以使用有限状态自动机来匹配这些正则表达式。编写词法分析器涉及一种特殊的编码风格,它具有这种风格:

while ( NOT <<EOF>> ) {
  switch ( next_symbol() ) {

     case state_symbol[1]: 
              ....
             break;

      case state_symbol[2]:
              ....
              break;

       default:
             error(diagnostic);
  }
}

所以,现在,也许学术任务的价值变得更加清晰。

于 2015-05-01T16:07:46.007 回答