Ваши две scanf
строки фактически совпадают. Строка printf
не соответствует, потому что шаблон для строкового литерала не совпадает. Проблема в том, что lex не понимает \w
или \W
, поэтому [\w\W]
соответствует только буквам w
и W
.
Если lex действительно поддерживает \w
и \W
, тогда [\w\W]
будет соответствовать каждому символу, который является или не является "символом слова". Другими словами, это будет соответствовать всему. Это говорит нам о том, что вместо [\w\W]
вы можете просто написать .
, который поддерживается lex и соответствует всему. Он также говорит нам, что бит (%[d|c|f|lf|s])*)+
является избыточным, потому что все, что может быть сопоставлено этой частью, уже было бы сопоставлено частью .*
. Следовательно, квалификатор +
снаружи также является избыточным.
Таким образом, с учетом этого регулярное выражение для строковых литералов станет \".*\"
(что не соответствует символам новой строки, но это нормально, потому что C не делает не разрешать неэкранированные символы новой строки в строковых литералах). Проблема в том, что это будет соответствовать всему от первого "
на входе до last "
, а не next "
. Итак, вы хотите запретить "
s появляться внутри строки. Тем не менее, "
внутри строки допускается, если ее экранировать, предшествуя ей с обратной косой чертой sh (как и переводы строки). Итак, принимая во внимание все это, подходящее регулярное выражение для строковых литералов:
\"(\\(.|\n)|[^\n\\"])*\"