Pergunta

Could anyone please help me in writing a LEX program to check and count comment lines in a C program. I have searched for it everywhere and failed to get the complete code.

Foi útil?

Solução

comment lines are of the form

%% {START} {whatever symbols,alphanumerics and letters} {END} %%

  • START symbol can be // or /* in C.
  • END symbol is */
  • If it is "//" any other symbol can follow it in the LINE including a second occurances of // (which is ignored).
  • IF it is " /* " it will find the next immediate match for " */ " and all the rest of the patterns that appear in between is matched(This matching may include blank spaces,tabs ,"//" and " /* " in it)

Here is a sample code to do it

`   

%{
#include<stdio.h>
int c=0;
%}
START "/*"
END "*/"
SIMPLE [^*]
SPACE [ \t\n]
COMPLEX "*"[^/]
%s newstate
%%
"//"(.*[ \t]*.*)*[\n]+    {c++; fprintf(yyout," ");}
{START}                    {yymore();BEGIN newstate;}
 <newstate>{SIMPLE}        {yymore();BEGIN newstate;}
 <newstate>{COMPLEX}      {yymore();BEGIN newstate;}
 <newstate>{SPACE}        {yymore();BEGIN newstate;}
 <newstate>{END}  {c++;fprintf(yyout," ");BEGIN 0;}
%%
main()
{//program to remove comment lines
yyin=fopen("file4","r");
yyout=fopen("fileout4","w");system("cat file4");
yylex();system("cat fileout4");
printf("no.of comments=%d",c);
fclose(yyin);
fclose(yyout);
}
`

The input file "file4" is below

/* #include <stdlib.h>


    {}.@All nonsense symbols */
//another comment
int main{}
{/**/
 printf("hello");
 /* comment inside// comment is ignored */
 //how about//this?
 /* now we /* try this */ */
 printf("COOL!!");
 return (0);
}

It gives the following output which is stored in "fileout4" `

 int main{}
{


 printf("hello");
     */
 printf("COOL!!");
 return (0);
}

`

The number of comment lines in the above program is 6.

Outras dicas

You can maintain a boolean variable which keeps track of whether the line you're parsing is inside a multi-line comment or not.

%{
#include <stdio.h>
#include <stdbool.h>
int comment_lines = 0;
bool in_comment = false;
%}

%%
"/*".*\n { in_comment = true; ++comment_lines; }
.*"*/"\n { in_comment = false; ++comment_lines; }
"//".*\n { ++comment_lines; }
.*\n { 
    if (in_comment) {
    ++comment_lines;
    } else {
    fprintf(yyout, yytext);  
    }
}

%%

int yywrap() {
    return 1;
}

int main(void) {
    printf("Enter input file: ");
    char filename[64];
    scanf("%s", filename);
    yyin = fopen(filename, "r");

    printf("Enter output file: ");
    scanf("%s", filename);
    yyout = fopen(filename, "w");

    yylex();
    printf("Number of comments: %d\n", comment_lines);
}

In the above code, in_comment is used to indicate the state of the line being analyzed. If it is in a comment, the comment_lines value is incremented, otherwise the text is written to an output file given by yyout.

input file

#include <stdio.h>

/*
 *
 * This is a multi-line comment
 *
 */

void dummy();

// main function is the entry point.
int main(void) {
    /* 
     * Here we print a message on user's 
     * console.
     */
    printf("Hello world\n");
    // That is it.
}

output file generated after lexical analysis

#include <stdio.h>


void dummy();

int main(void) {
    printf("Hello world\n");
}

Number of comments: 11
%{


#undef yywrap
#define yywrap() 1
int single=0, multiline =0;
%}


%%


"//".*"\n" {printf("%s\n", yytext); single++;}
"/*".*[\n]*.*"*/" {printf("%s\n", yytext); multiline++;}
.;

%%


int main()
{
 yyin = fopen("yourfile","r");
 yylex(); //calling the rules section
 printf(" Single line comments = %d, multiline comments = %d", single, multiline);
 fclose(yyin);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top