Программа Lex для подсчета количества строк, символов, цифр и ключевых слов - PullRequest
0 голосов
/ 14 сентября 2018

Я работал над созданием сканера lex, однако, когда я передаю его своему входному файлу, он выдает неправильный вывод. Вот мой исходный код:

%{
#include <stdio.h>

int NumberOfLines=0;
int NumberOfChar=0;
int NumberOfIntegers=0;
int KWCount=0;
int NumberOfComments=0;
%}

DIGIT   [0-9]*
ID  [a-z][a-z0-9]*
%x COMMENT
%option noyywrap
%%

^[\t]*"/*" {BEGIN COMMENT;}
^[\t]*"/*".*"*/"[\t]*\n {NumberOfComments++;}

<COMMENT>"*/"[\t]*\n {BEGIN 0; NumberOfComments++;}
<COMMENT>"*/" {BEGIN 0;}
<COMMENT>\n {NumberOfComments++;}
<COMMENT>.\n {NumberOfComments++;}

\n {NumberOfLines++, NumberOfChar++; NumberOfChar +=strlen(yytext);}
. {NumberOfChar++; NumberOfChar +=strlen(yytext);}



{DIGIT}     {NumberOfIntegers++; NumberOfChar +=strlen(yytext); }


{DIGIT}+"."{DIGIT}* {
    printf("A flot: %s (%g) \n", yytext, atof(yytext));
    NumberOfChar +=strlen(yytext); 
    }

if|else|while|return    {
    printf("A keyword: %s\n", yytext); KWCount++;
    NumberOfChar +=strlen(yytext); 
    }

{ID}        {
    printf("An identifier: %s\n", yytext);
    NumberOfChar +=strlen(yytext); 
    }
"{"[^}\n]*"}"   {
    /*each up one-line comments*/
    NumberOfChar +=strlen(yytext);
    }

%%
int main(int argc, char **argv){
    ++argv, --argc; /*skip over program name */
    if (argc > 0)
        yyin = fopen(argv[0], "r"); 
    else
        yyin = stdin; 
    yylex();
    printf("Character count: %d",NumberOfChar);
    printf("\n");
    printf("Number count: %d",NumberOfIntegers);
    printf("\n");
    printf("Keyword count: %d",KWCount);
    printf("\n");
    printf("Line count: %d",NumberOfLines);
    printf("\n");
    printf("Comment count: %d", NumberOfComments);
    printf("\n"); 
    return 0; 
}

Всякий раз, когда я запускаю свой входной файл с источником, он выдает неправильный вывод. Например, вывод файла должен быть:

Выход:

Number of Keywords: 3

Number of Characters: 196

Number of Lines: 17

Number of Digits: 3

Однако вывод, который он в данный момент производит:

Выход:

Number of keywords: 0

Number of Characters: 3

Number of Lines: 7

Number of Digits: 0   

Я подозреваю, что это связано с моими регулярными выражениями, любая помощь будет признательна, так как я все еще изучаю регулярные выражения!

Вот содержимое моего входного файла:

/*comment 1*/
/*comment
  comment 2 
  */
  /*comment 3*
   */if this is a line
{comment 4}
int i = 789; 
int j = 689;
if i == 172 then
 {comment 5}
else
{comment 6}
{comment 7}
/*8 comments
 *
 */ 
end

1 Ответ

0 голосов
/ 14 сентября 2018

Вот некоторый в основном рабочий код, тесно связанный с вашим кодом.

%{
#include <stdio.h>

int NumberOfLines=0;
int NumberOfChar=0;
int NumberOfIntegers=0;
int KWCount = 0;
int IDCount = 0;
int RCCount = 0;
int OCCount = 0;
int DTCount = 0;
int FLCount = 0;
%}

%option noyywrap
%option noinput
%option nounput

DIGIT   [0-9]*
ID  [a-z][a-z0-9]*

%%

\n {NumberOfLines++; NumberOfChar++; RCCount += strlen(yytext); }
. {NumberOfChar++; DTCount++; RCCount++; printf(" '%c'", yytext[0]); }

{DIGIT}     {NumberOfIntegers++; RCCount += strlen(yytext); }

{DIGIT}+"."{DIGIT}* {
    printf("\nA float: %s (%g) \n", yytext, atof(yytext)); 
    RCCount += strlen(yytext);
    FLCount++;
    }

if|else|while|return    {
    printf("\nA keyword: %s\n", yytext); 
    KWCount++;
    RCCount += strlen(yytext);
    }

{ID}        {
    printf("\nAn identifier: %s\n", yytext); 
    IDCount++;
    RCCount += strlen(yytext);
    }
"{"[^}\n]*"}"   {
    RCCount += strlen(yytext);
    OCCount += strlen(yytext);
    }

%%
int main(int argc, char **argv){
    ++argv, --argc; /*skip over program name */
    if (argc > 0)
        yyin = fopen(argv[0], "r"); 
    else
        yyin = stdin; 
    yylex();
    printf("Character count: %d\n", NumberOfChar);
    printf("Number count:    %d\n", NumberOfIntegers);
    printf("Keyword count:   %d\n", KWCount);
    printf("Line count:      %d\n", NumberOfLines);
    printf("ID count:        %d\n", IDCount);
    printf("Dot count:       %d\n", DTCount);
    printf("Raw count:       %d\n", RCCount);
    printf("Float count:     %d\n", FLCount);
    printf("Other count:     %d\n", OCCount);
    printf("\n"); 
    return 0; 
}

При запуске с файлом данных:

/*commEnt 1*/
/*COMMENT
  commEnt 2 
  */
  /*commEnt 3*
   */if this is a linE
{commEnt 4}
int i = 789; 
int j = 689;
if i == 172 thEn
 {commEnt 5}
ElsE
{commEnt 6}
{commEnt 7}
float 12.34
/*8 commEnts
 *
 else
 return
 while
 the
 going
 is
 good
 */ 
end

Я получаю вывод:

 '/' '*'
An identifier: comm
 'E'
An identifier: nt
 ' ' '1' '*' '/' '/' '*' 'C' 'O' 'M' 'M' 'E' 'N' 'T' ' ' ' '
An identifier: comm
 'E'
An identifier: nt
 ' ' '2' ' ' ' ' ' ' '*' '/' ' ' ' ' '/' '*'
An identifier: comm
 'E'
An identifier: nt
 ' ' '3' '*' ' ' ' ' ' ' '*' '/'
A keyword: if
 ' '
An identifier: this
 ' '
An identifier: is
 ' ' 'a' ' '
An identifier: lin
 'E'
An identifier: int
 ' ' 'i' ' ' '=' ' ' ';' ' '
An identifier: int
 ' ' 'j' ' ' '=' ' ' ';'
A keyword: if
 ' ' 'i' ' ' '=' '=' ' ' ' '
An identifier: th
 'E' 'n' ' ' 'E'
An identifier: ls
 'E'
An identifier: float
 ' '
A float: 12.34 (12.34) 
 '/' '*' '8' ' '
An identifier: comm
 'E'
An identifier: nts
 ' ' '*' ' '
A keyword: else
 ' '
A keyword: return
 ' '
A keyword: while
 ' '
An identifier: the
 ' '
An identifier: going
 ' '
An identifier: is
 ' '
An identifier: good
 ' ' '*' '/' ' '
An identifier: end
Character count: 115
Number count:    3
Keyword count:   5
Line count:      26
ID count:        21
Dot count:       89
Raw count:       258
Float count:     1
Other count:     44

Выходные данные wc:

$ wc data.2
      26      49     258 data.2
$

«Необработанный счетчик» символов соответствует количеству символов из wc;количество строк тоже совпадает.Количество целых чисел, чисел с плавающей запятой, ключевых слов и идентификаторов выглядит правильно, учитывая, что заглавные буквы считаются в «точечных символах»Вы можете решить, есть ли другие проблемы;Я думаю, что число целых чисел неверно, но я не уверен, почему.

...