2

我对 Lex 非常陌生,这个问题的完整要求如下:

编写一个 Lex 输入文件,该文件将生成一个计算文本文件中的字符、单词和行数并报告计数的程序。将单词定义为任何字母和/或数字序列,没有标点符号或空格。标点符号和空格不算作单词。

现在我写下了代码:

%{
#include <stdio.h>
#include <stdlib.h>
int cno = 0, wno = 0, lno = 0; /*counts of characters, words and lines */
%}
character [a-z]
digit [0-9]
word ({character}|{digit})+[^({character}|{digit})]
line \n
%%
{line} { lno++; REJECT; }
{word} { wno++; REJECT; }
{character} { cno++; }
%%
void main()
{ yylex();
  fprintf(stderr, "Number of characters: %d; Number of words: %d; Number of lines: %d\n", cno, wno, lno);
  return;
}

我用文本文件对其进行了测试:

this is line #1
line #2 is here
!@#$%^&*()
haha hey hey

我得到了输出

   #1
 #2  
!@#$%^&*()

Number of characters: 30; Number of words: 45; Number of lines: 4

但正确的输出应该是

Number of characters: 30; Number of words: 11; Number of lines: 4

我猜“字数”的错误应该是由于每个字符数,所以我应该如何修改我的程序来解决这个问题?

此外,还会出现一些不必要的输出(那些标点符号)。我应该如何修改我的程序以避免它们?

非常感谢。

4

1 回答 1

10

你需要一个规则来处理“无趣”的角色;你仍然需要计算它们。

您不想拒绝换行符。

您不需要word. 您可能应该将大写字母作为character.

这似乎有效:

%{
#include <stdio.h>
#include <stdlib.h>
int cno = 0, wno = 0, lno = 0; /*counts of characters, words and lines */
%}

character [a-zA-Z]
digit [0-9]
word ({character}|{digit})+
line \n

%%

{line} { cno++; lno++; }
{word} { wno++; cno += strlen(yytext); }
. { cno++; }

%%

int main(void)
{
    yylex();
    printf("Number of characters: %d; ", cno);
    printf("Number of words:      %d; ", wno);
    printf("Number of lines:      %d\n", lno);
    return 0;
}

在其自己的源代码上运行时,输出为:

Number of characters: 463; Number of words:      65; Number of lines:      27

标准wc命令(对“单词”有不同的定义)产生:

  27      73     463 xyz.l

这与行数和字符数一致。

于 2012-05-09T04:58:57.390 回答