Как найти определенное слово в lex с учетом входного файла?

Я новичок в Лексе. Я пытаюсь разработать синтаксический анализатор для поиска количества определенных слов в заданном входном файле ...

Мой код

%{
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    int lnum = 1, fresult = 0, cc=0, wc=0, lc=0, bc=0, sc=0, nc=0, tc=0, result;
    char temp[20], str[20], fname[20];
    FILE *fp;
    #undef yywrap
%}
digit[0-9]+
word [a-zA-Z]+
eol  [\n]
blank [ ]
tab   [\t]
result [word]
%%
{result} {
    if((strstr(temp, str)) != 0)
    {
        printf(" A match found on line: %d\n", lnum);
        fresult++;
        wc++;
        cc+=yyleng;
    }
    lnum++;
    if(fresult == 0)
    {
        printf(" Match not found\n");
    }
}
{digit} {nc++;}
{word}  {wc++; cc+=yyleng;}
{tab}   {tc++;}
{blank} {bc++;}
{eol}   {lc++;}
.    sc++;

%%

int main(int argc, char *argv[])
{
    strcpy(fname,argv[1]);
    strcpy(str,argv[2]);
    fp=fopen(fname,"r+");
    yyin=fp;
    yylex();
    printf(" Total count of the word is :%d\n", fresult);
    printf(" Character Count = %d\n", cc);
    printf(" Number Count = %d\n", nc);
    printf(" Word Count = %d\n", wc);
    printf(" Line Count = %d\n", lc);
    printf(" Special Character Count = %d\n", sc);
    printf(" Blank Count = %d\n", bc);
    printf(" Tab Count = %d\n", tc);
    return(0);
}
int yywrap()
{
    return -1;
}

Подсчет слов и другие работают отлично .... Но поиск слов принимает входные данные, но не дает конкретного подсчета ... Как я могу улучшить код? Мне нужно что-нибудь добавить?

Заранее спасибо...... :)


lex
person Swathi Naik    schedule 30.08.2013    source источник


Ответы (2)


Я внес некоторые изменения в ваш код, чтобы помочь вам в правильном направлении. Сначала я создал переменную, чтобы отслеживать, найдено совпадение или нет.

Во-вторых, я больше не использую strstr (), а вместо этого использую используя strcmp (), потому что вы хотите сопоставить слово со словом ни слова в предложении, и нам не нужен возвращаемый указатель. strcmp () хорош, потому что мы просто получаем целое число.

Я понимаю, что вы пытались сделать с result [word], однако, как вы выяснили, это не сработает. Этот раздел файла Flex известен как раздел rules. Здесь вы используете регулярные выражения, которые вы определили в предыдущем разделе (определения), чтобы сообщить Flex, что делать при совпадении правила.

Как видите, я удалил все вхождения результата [word] - это не сработает. В разделе rules я также удалил определение result, потому что у нас больше нет правила, которое бы ему соответствовало. Однако я сохраняю код для result определений и просто применяю его к word определению.

Последним важным изменением является добавление правила <<EOF>>, которое является специальным правилом, которое сообщает Измените, что делать, когда он встретил конец файла. В нашем случае, если переменная соответствия не равна 1, то мы не нашли совпадения и хотели бы вывести это на экран. Нам также необходимо вызвать yyterminate() (определение внизу страницы), чтобы остановить лексический анализатор.

Ниже приведен обновленный код. Надеюсь, это поможет!

%{
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    int lnum = 1, fresult = 0, cc=0, wc=0, lc=0, bc=0, sc=0, nc=0, tc=0, result;
    char temp[20], str[20], fname[20];
    FILE *fp;
    int match = 0;//For keeping track of matches
    #undef yywrap
%}

/*Rules*/

digit   [0-9]+
word    [a-zA-Z]+
eol     [\n]
blank   [ ]
tab     [\t]

/*Definitions*/
%%

{digit} {
            nc++;
        }
{tab}   {           
            tc++;
        }
{blank} {       
            bc++;
        }
{eol}   {       
            lc++;
        }   
{word}    {
            if((strcmp(yytext, str)) == 0)//We found a match
            {
                printf("\n A match found on line: %d\n", lnum);
                fresult++;
                wc++;
                cc+=yyleng;
                match = 1;//We have a match         
            }
            else //We found a word, but it was not a match
            {
                wc++;
            }

        }
.   {   
        sc++;
    }
<<EOF>> {   
            if(!match)
            {   
                printf(" Match not found\n");
            }
            yyterminate();
        }

%%

int main(int argc, char *argv[])
{
    strcpy(fname,argv[1]);
    strcpy(str,argv[2]);
    fp = fopen(fname,"r+");
    yyin = fp;
    yylex();
    printf("\n\n Total count of the word is :%d\n", fresult);
    printf(" Character Count = %d\n", cc);
    printf(" Number Count = %d\n", nc);
    printf(" Word Count = %d\n", wc);
    printf(" Line Count = %d\n", lc);
    printf(" Special Character Count = %d\n", sc);
    printf(" Blank Count = %d\n", bc);
    printf(" Tab Count = %d\n", tc);

    fclose(fp);
    return(0);
}
int yywrap()
{
    return 1;
}
person larrylampco    schedule 04.09.2013

{result} {
    if((strstr(temp, str)) != 0)

результат [слово]

Результатом является регулярное выражение для символов 'w', 'o', 'r', 'd', а это не то, что вам нужно. Вероятно, вы захотите найти совпадение на {word}. Вдобавок temp всегда будет нулевым - я думаю, вы захотите использовать вместо этого yytext.

person BlackJack    schedule 30.08.2013
comment
Я пробовал использовать «yytext», но yytext сохраняет только букву «r» из результата. - person Swathi Naik; 31.08.2013