2010-01-11 23 views
41

Estoy experimentando para aprender flex y me gustaría hacer coincidir los literales de cadena. Mi código es actualmente como:Expresión regular para un literal de cadena en flex/lex

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

He estado luchando con variaciones para una hora o así y no puedo conseguir que funcione como debería. En esencia, espero que coincida con un literal de cadena que no puede contener una nueva línea (a menos que se haya escapado) y admite caracteres escapados.

Probablemente estoy escribiendo una expresión regular pobre o una incompatible con flex. ¡Por favor avise!

+0

Muchas gracias a todos! Todos tus comentarios fueron muy útiles. La expresión regular que finalmente funcionó para mí es una variante de la utilizada en la especificación C vinculada por codadict (y explicada por Jonathan): \ "(\\ (. | \ N) | [^ \\" \ n]) * \ " – Thomas

+0

Dado que encontraste útil la respuesta de Jonathan, considera agregar un voto positivo para su respuesta. – codaddict

+0

Dicho sea de paso: en ninguna parte de tu pregunta especificas los literales de cadenas del idioma que te interesan. Es una muy buena idea poner el idioma estás preguntando sobre una de las etiquetas de la pregunta. –

Respuesta

92

Una cadena consiste en una comilla

" 

seguido de cero o más bien de un nada escapado

\\. 

o un no cita carácter

[^"\\] 

y, finalmente, una cita de terminación

" 

poner todo junto, y usted tiene

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

Las comillas delimitadoras se escapan porque son metacaracteres Flex.

+6

+1, para obtener una explicación clara de lo que está sucediendo. – codaddict

+3

Esto no soluciona el escape, desafortunadamente. Entonces, esto incorrectamente leería "" \ "" ' –

+4

Debe haber perdido" cero o más de un elemento escapado "? –

8

Cómo sobre el uso de un estado de inicio ...

 
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... 

Era similar a tal efecto (flex utiliza %s o %x para indicar en qué estado se podría esperar. Cuando la entrada de flex detecta una cita, la aplicación cambiará a otro estado, luego continúa léxico hasta que llega otra cita, en la que vuelve a su estado normal

+1

Es demasiado complejo, ¿no? – samoz

+2

@Samoz: En realidad, no se usa en los idiomas donde se usan los literales de cadena, se come lo que hay entre una cita inicial y una final, aunque haya extra cita dentro de ella, por lo tanto, el uso de estados de conmutación para masticar las comillas ... – t0mm13b

+5

El manual de flex contiene un ejemplo completo (en términos de uso flexible) de análisis de cadenas estilo C: http://flex.sourceforge.net /manual/Start-Conditions.html. Busque "cadenas entre comillas" en esa página. –

17

para una sola línea ... se puede usar este otro:.

\"([^\\\"]|\\.)*\" {/*matches string-literal on a single line*/;} 
+1

Esta es la mejor respuesta aquí. – refi64

0

Una respuesta que llega tarde, pero que puede ser útil para el próximo que se va a necesitar:

\"(([^\"]|\\\")*[^\\])?\" 
+1

Bienvenido a SO. Esta respuesta se mejorará con texto que explica * cómo * funciona y * cómo * es diferente. –

Cuestiones relacionadas