2017-04-01 1 views
2

Nous essayons d'analyser le format de fichier GEDCOM. Selon sa norme, toutes les combinaisons de CR et LF sont valides pour indiquer une rupture de ligne.Comment traiter différentes conventions de nouvelle ligne avec Flex

Il s'agit d'un format basé sur une ligne, si souvent nous voulons faire correspondre le reste de la ligne lorsque nous avons déjà fait correspondre le numéro et l'étiquette. Un exemple d'une règle serait

"NAME ".+    { /* deal with the name */ } 

Les nouvelles lignes sont compensées par

[\r\n]+    {return ENDLINE;} 

Cela fonctionne bien sous Windows, car il convertit \ r \ n \ n derrière votre dos, mais il n » t sur Linux. Là, \ r peut être égalé par le point. Parce que Flex utilise la règle de correspondance la plus longue, il inclura le \ r dans les données, ou il correspondra à une balise connue à la règle UNKNOWNTAG parce que cette correspondance techniquement correcte sera un octet plus long

Une solution pourrait être de remplacer tous les points avec [^ \ r \ n], mais qui semblent inélégants. Y a-t-il un meilleur moyen?

+1

Il y a seulement un drapeau qui passe entre '. = [^ \ n] 'et'. = «N'importe quel caractère». Je pense que le mieux que vous puissiez faire est de définir un motif 'ANY = [^ \ r \ n]' et d'utiliser simplement "" NAME "{ANY} +'. – kennytm

+0

Je suis d'accord avec @kennytm, ou normalise les fichiers gedcom ('sed -ri 's/\ r \ n/\ n /' * .degcom') avant lex, ou le convertis lors de l'entrée lex' main() {yyin = popen ("sed -r 's/\ r/n/\ n /'", r); yylex())} ' – JJoao

+0

Je prends un butin au format GEDCOM. On dirait que vous avez besoin d'utiliser l'analyseur comme bison pour le faire. Si vous le voulez, vous pouvez définir des jetons différents et utiliser '(\ r \ n | \ n)' comme EOL. Donc, il n'y aura pas de "match le reste de la ligne", et ce ne sera pas un problème :) – komar

Répondre

0

Vous pouvez utiliser la redéfinition YY_INPUT pour remplacer \r à \n:

%{ 
#define YY_INPUT(buf,result,max_size) { \ 
     int c = getc(yyin);    \ 
     buf[0] = (c == '\r') ? '\n' : c; \ 
     result = 1;      \ 
    } 
%} 
+0

Forcer Flex à lire un caractère à la fois est une très mauvaise idée. – rici