Программа Lex для удаления однострочных и многострочных комментариев из заданного текста

Я пытаюсь написать программу lex, которая удалит как однострочный, так и многострочный комментарий.

%{
#include<stdio.h>
int single=0;
int multi=0;    
%}
%%
"//"([a-z]|[A-Z]|[0-9]|" ")* {++single;}
"/*"(.*\n)* "*/" {++multi;}
%%
int main(int argc, int **argv)
{
    yyin=fopen("abc.txt","r");
    yylex();
    printf("no of single line comment = %d ", single);
    printf("no of multi line comment = %d ", multi);
    return 0;
}

Эта программа не умеет удалять многострочные комментарии.


person Subhadip    schedule 27.08.2018    source источник
comment
вам может потребоваться проверить наличие дополнительных символов конца строки... LF: перевод строки, U+000A VT: вертикальная табуляция, U+000B FF: перевод страницы, U+000C CR: возврат каретки, U+000D CR+LF: CR (U+000D), за которым следует LF (U+000A) NEL: следующая строка, U+0085 LS: разделитель строк, U+2028 PS: разделитель абзацев, U+2029 en.wikipedia.org/wiki/Newline   -  person Any Moose    schedule 27.08.2018
comment
Пожалуйста, просмотрите эти повторяющиеся вопросы; Я уверен, что вы найдете ответ: stackoverflow.com/search?q=Count+comments+%5Blex% 5D   -  person rici    schedule 27.08.2018
comment
Возможный дубликат программы lex при подсчете количества строк комментариев   -  person CaptainDaVinci    schedule 06.06.2019


Ответы (2)


Если в вашем файле abc.txt есть несколько многострочных комментариев, тогда ваш шаблон для многострочного комментария будет соответствовать всему между началом первого многострочного комментария и концом последнего многострочного комментария. Это происходит, когда lex проявляет жадность и пытается сопоставить самый длинный префикс входной строки. И ваш шаблон для многострочного комментария позволяет /* и */ сопоставляться с (.*\n)*

Также ваш код не будет обнаруживать однострочные комментарии, содержащие какие-либо символы, кроме буквенно-цифровых символов и пробела (например, - , ; : и т. д.).

Измените свои шаблонные действия на эти, и это должно достичь вашей цели.

"//".*\n            { ++single; }
"/*"[^*/]*"*/"      { ++multi; }

Хотя приведенный выше код по-прежнему оставит несколько новых строк вместо удаленных многострочных комментариев. Это немного сложно, и я не могу найти быстрое решение для удаления этих новых строк.

Надеюсь это поможет!

person Pandav Patel    schedule 12.09.2018

Для гибкости,

"//".* {singleLine++;}
"/*"([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ {multiLine++;}

Для получения подробной информации: https://blog.ostermiller.org/finding-comments-in-source-code-using-regular-expressions/

person hari_431    schedule 22.10.2020