Регулярное выражение для строкового литерала в flex / lex - PullRequest
46 голосов
/ 11 января 2010

Я экспериментирую, чтобы изучить flex и хотел бы соответствовать строковым литералам. Мой код в настоящее время выглядит так:

"\""([^\n\"\\]*(\\[.\n])*)*"\""        {/*matches string-literal*/;}

Я боролся с вариациями в течение часа или около того и не могу заставить его работать так, как должно. По сути, я надеюсь сопоставить строковый литерал, который не может содержать новую строку (если он не экранирован) и поддерживает экранированные символы.

Я, вероятно, просто пишу плохое регулярное выражение или несовместимое с flex. Пожалуйста, сообщите!

Ответы [ 6 ]

108 голосов
/ 11 января 2010

Строка состоит из кавычки

"

, за которым следует ноль или более из чего-либо сбежавшего

\\.

или символ без кавычек

[^"\\]

и, наконец, завершающая цитата

"

Соберите все вместе, и вы получите

\"(\\.|[^"\\])*\"

Кавычки-разделители экранированы, поскольку они являются метасимволами Flex.

18 голосов
/ 13 февраля 2012

Для одной строки ... вы можете использовать это:

\"([^\\\"]|\\.)*\"  {/*matches string-literal on a single line*/;}
8 голосов
/ 11 января 2010

Как насчет использования начального состояния ...

int enter_dblquotes = 0;

%x DBLQUOTES
%%

\"  { BEGIN(DBLQUOTES); enter_dblquotes++; }

<DBLQUOTES>*\" 
{ 
   if (enter_dblquotes){
       handle_this_dblquotes(yytext); 
       BEGIN(INITIAL); /* revert back to normal */
       enter_dblquotes--; 
   } 
}
         ...more rules follow...

Это было похоже на этот эффект (flex использует %s или %x для указания ожидаемого состояния. Когда гибкий вход обнаруживает кавычку, он переключается в другое состояние, затем продолжает лексирование, пока не достигнет другой кавычки, в котором он возвращается в нормальное состояние.

0 голосов
/ 20 февраля 2019

Вставьте мой фрагмент кода об обработке строки в flex, надеюсь, вдохновит ваше мышление.

Использование Начальное условие для обработки строкового литерала будет более масштабируемым и понятным.

%x SINGLE_STRING

%%

\"                          BEGIN(SINGLE_STRING);
<SINGLE_STRING>{
  \n                        yyerror("the string misses \" to termiate before newline");
  <<EOF>>                   yyerror("the string misses \" to terminate before EOF");
  ([^\\\"]|\\.)*            {/* do your work like save in here */}
  \"                        BEGIN(INITIAL);
  .                         ;
}
0 голосов
/ 27 сентября 2018

Это то, что мы используем в Zolang для однострочных строковых литералов со встроенными шаблонами ${...}

\"(\$\{.*\}|\\.|[^\"\\])*\"

0 голосов
/ 03 июня 2017

Ответ, который приходит поздно, но который может быть полезен для следующего, кому он понадобится:

\"(([^\"]|\\\")*[^\\])?\"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...