%{
#include <stdio.h>
int comment_lines = 0; // Count of comment lines (single-line and multi-line)
int identifiers = 0; // Count of identifiers
int characters = 0; // Count of characters
int words = 0; // Count of words
%}
/* Definitions */
DIGIT [0-9]
LETTER [a-zA-Z_]
IDENTIFIER {LETTER}({LETTER}|{DIGIT})*
WORD [a-zA-Z]+
/* Rules */
%%
"//"[^\n]*\n { comment_lines++; characters += yyleng; } /* Single-line comment */
"/*"([^*]|\*+[^*/])*\*+"/" { comment_lines++; characters += yyleng;
/* Count multi-line comments; increment for each line if spans multiple */
for(int i = 0; i < yyleng; i++) if(yytext[i] == '\n') comment_lines++; }
{IDENTIFIER} { identifiers++; characters += yyleng; words++; } /* Identifiers are also words */
{WORD} { words++; characters += yyleng; } /* Other words */
[ \t\n] { characters += yyleng; } /* Whitespace characters */
. { characters++; } /* Any other character */
%%
/* User Code */
int main(int argc, char* argv[]) {
if
(argc
> 1) { // If a file
is provided as argument
yyin = fopen(argv[1], "r");
if(!yyin) {
perror("Error opening file");
return 1;
}
} else { // Use standard input
yyin = stdin;
printf("Enter the input (Ctrl+D to end):\n");
}
yylex(); // Run the lexical analyzer
printf
("
Number of comment lines
: %d\n", comment_lines); printf
("
Number of identifiers
: %d\n", identifiers); printf
("
Number of characters
: %d\n", characters); printf
("
Number of words
: %d\n", words);
if(argc > 1) fclose(yyin);
return 0;
}
int yywrap() {
return 1; // Indicate end of input
}
CiV7CiNpbmNsdWRlIDxzdGRpby5oPgppbnQgY29tbWVudF9saW5lcyA9IDA7ICAvLyBDb3VudCBvZiBjb21tZW50IGxpbmVzIChzaW5nbGUtbGluZSBhbmQgbXVsdGktbGluZSkKaW50IGlkZW50aWZpZXJzID0gMDsgICAgLy8gQ291bnQgb2YgaWRlbnRpZmllcnMKaW50IGNoYXJhY3RlcnMgPSAwOyAgICAgLy8gQ291bnQgb2YgY2hhcmFjdGVycwppbnQgd29yZHMgPSAwOyAgICAgICAgICAvLyBDb3VudCBvZiB3b3JkcwolfQoKLyogRGVmaW5pdGlvbnMgKi8KRElHSVQgICAgICAgWzAtOV0KTEVUVEVSICAgICAgW2EtekEtWl9dCklERU5USUZJRVIgIHtMRVRURVJ9KHtMRVRURVJ9fHtESUdJVH0pKgpXT1JEICAgICAgICBbYS16QS1aXSsKCi8qIFJ1bGVzICovCiUlCgoiLy8iW15cbl0qXG4gICAgICAgICAgIHsgY29tbWVudF9saW5lcysrOyBjaGFyYWN0ZXJzICs9IHl5bGVuZzsgfSAgLyogU2luZ2xlLWxpbmUgY29tbWVudCAqLwoiLyoiKFteKl18XCorW14qL10pKlwqKyIvIiAgeyBjb21tZW50X2xpbmVzKys7IGNoYXJhY3RlcnMgKz0geXlsZW5nOyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQ291bnQgbXVsdGktbGluZSBjb21tZW50czsgaW5jcmVtZW50IGZvciBlYWNoIGxpbmUgaWYgc3BhbnMgbXVsdGlwbGUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHl5bGVuZzsgaSsrKSBpZih5eXRleHRbaV0gPT0gJ1xuJykgY29tbWVudF9saW5lcysrOyB9Cgp7SURFTlRJRklFUn0gICAgICAgICAgIHsgaWRlbnRpZmllcnMrKzsgY2hhcmFjdGVycyArPSB5eWxlbmc7IHdvcmRzKys7IH0gIC8qIElkZW50aWZpZXJzIGFyZSBhbHNvIHdvcmRzICovCntXT1JEfSAgICAgICAgICAgICAgICAgeyB3b3JkcysrOyBjaGFyYWN0ZXJzICs9IHl5bGVuZzsgfSAgLyogT3RoZXIgd29yZHMgKi8KWyBcdFxuXSAgICAgICAgICAgICAgICB7IGNoYXJhY3RlcnMgKz0geXlsZW5nOyB9ICAvKiBXaGl0ZXNwYWNlIGNoYXJhY3RlcnMgKi8KLiAgICAgICAgICAgICAgICAgICAgICB7IGNoYXJhY3RlcnMrKzsgfSAgLyogQW55IG90aGVyIGNoYXJhY3RlciAqLwoKJSUKCi8qIFVzZXIgQ29kZSAqLwppbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CiAgICBpZihhcmdjID4gMSkgeyAgLy8gSWYgYSBmaWxlIGlzIHByb3ZpZGVkIGFzIGFyZ3VtZW50CiAgICAgICAgeXlpbiA9IGZvcGVuKGFyZ3ZbMV0sICJyIik7CiAgICAgICAgaWYoIXl5aW4pIHsKICAgICAgICAgICAgcGVycm9yKCJFcnJvciBvcGVuaW5nIGZpbGUiKTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgfSBlbHNlIHsgIC8vIFVzZSBzdGFuZGFyZCBpbnB1dAogICAgICAgIHl5aW4gPSBzdGRpbjsKICAgICAgICBwcmludGYoIkVudGVyIHRoZSBpbnB1dCAoQ3RybCtEIHRvIGVuZCk6XG4iKTsKICAgIH0KICAgIAogICAgeXlsZXgoKTsgIC8vIFJ1biB0aGUgbGV4aWNhbCBhbmFseXplcgogICAgCiAgICBwcmludGYoIk51bWJlciBvZiBjb21tZW50IGxpbmVzOiAlZFxuIiwgY29tbWVudF9saW5lcyk7CiAgICBwcmludGYoIk51bWJlciBvZiBpZGVudGlmaWVyczogJWRcbiIsIGlkZW50aWZpZXJzKTsKICAgIHByaW50ZigiTnVtYmVyIG9mIGNoYXJhY3RlcnM6ICVkXG4iLCBjaGFyYWN0ZXJzKTsKICAgIHByaW50ZigiTnVtYmVyIG9mIHdvcmRzOiAlZFxuIiwgd29yZHMpOwogICAgCiAgICBpZihhcmdjID4gMSkgZmNsb3NlKHl5aW4pOwogICAgcmV0dXJuIDA7Cn0KCmludCB5eXdyYXAoKSB7CiAgICByZXR1cm4gMTsgIC8vIEluZGljYXRlIGVuZCBvZiBpbnB1dAp9