Some fixes for libgedcom.so
[gedcom-parse.git] / gedcom_lohi.lex
index 3b315839ed5db01cf46b2536ebdb23300d94b70c..badd835d4015f7a74c80e12a6c4b0e67a8557916 100644 (file)
@@ -1,3 +1,12 @@
+/*  This program is free software; you can redistribute it and/or modify  *
+ *  it under the terms of the GNU General Public License as published by  *
+ *  the Free Software Foundation; either version 2 of the License, or     *
+ *  (at your option) any later version.                                   *
+
+ (C) 2001 by The Genes Development Team
+ Original author: Peter Verthez (Peter.Verthez@advalvas.be)
+*/
+
 /* $Id$ */
 /* $Name$ */
 
 /* i.e. this is utf-16-le */
 
 %{
-#include "gedcom.tab.h"
-#include "gedcom.h"
-#include "multilex.h"
-#include "encoding.h"
-
-#define YY_NO_UNPUT
+#undef IN_LEX    /* include only a specific part of the following file */
+#include "gedcom_lex_common.c"
+  
+static size_t encoding_width = 2;
 %}
 
 %s NORMAL
@@ -34,108 +41,21 @@ gen_delim    {delim}|{tab}
 escape       @\x00#\x00{any_char}+@\x00
 pointer      @\x00{alphanum}{non_at}+@\x00
 
-%{
-static int current_level=-1;
-static int level_diff=MAXGEDCLEVEL;
-#ifdef LEXER_TEST 
-YYSTYPE gedcom_lval;
-int line_no = 1; 
-#endif
-%} 
-
 %%
 
-    /* The GEDCOM level number is converted into a sequence of opening
-       and closing brackets.  Simply put, the following GEDCOM fragment:
-
-         0 HEAD
-        1 SOUR genes
-        2 VERS 1.6
-        2 NAME Genes
-        1 DATE 07 OCT 2001
-        ...
-        0 TRLR
-
-       is converted into:
-
-         { HEAD                     (initial)  
-        { SOUR genes               (1 higher: no closing brackets)
-        { VERS 1.6                 (1 higher: no closing brackets)
-        } { NAME Genes             (same level: 1 closing bracket)
-        } } { DATE 07 OCT 2001     (1 lower: 2 closing brackets)
-        ...
-        } { TRLR }
-
-       or more clearly:
-
-         { HEAD
-          { SOUR genes
-            { VERS 1.6 }
-            { NAME Genes } }
-          { DATE 07 OCT 2001
-        ... }
-        { TRLR }
-
-       But because this means that one token is converted into a series
-       of tokens, there is some initial code following immediately here
-       that returns "pending" tokens. */
-
 %{
-char string_buf[MAXGEDCLINELEN+1];
-if (level_diff < 1) {
-  level_diff++;
-  return CLOSE;
-}
-else if (level_diff == 1) {
-  level_diff++;
-  return OPEN;
-}
-else {
-  /* out of brackets... */
-}
-
-#define TO_INTERNAL(str) to_internal(str, yyleng) 
-
-#define MKTAGACTION(tag) \
-  { gedcom_lval.string = TO_INTERNAL(yytext); \
-    BEGIN(NORMAL); \
-    return TAG_##tag; }
+#define IN_LEX    /* include only a specific part of the following file */
+#include "gedcom_lex_common.c"
 
+ACTION_BEFORE_REGEXPS
+  
 %}
 
-<INITIAL>{gen_delim}* /* ignore leading whitespace (also tabs) */
+<INITIAL>{gen_delim}*     ACTION_INITIAL_WHITESPACE
 
-<INITIAL>\x00[0]{digit}+ { gedcom_error ("Level number with leading zero");
-                           return BADTOKEN;
-                         }
+<INITIAL>\x00[0]{digit}+  ACTION_0_DIGITS
 
-<INITIAL>{digit}+ { int level = atoi(TO_INTERNAL(yytext));
-                    if ((level < 0) || (level > MAXGEDCLEVEL)) {
-                     gedcom_error ("Level number out of range [0..%d]",
-                                   MAXGEDCLEVEL);
-                     return BADTOKEN;
-                   }
-                    level_diff = level - current_level;
-                   BEGIN(EXPECT_TAG);
-                   current_level = level;
-                   if (level_diff < 1) {
-                     level_diff++;
-                     return CLOSE;
-                   }
-                   else if (level_diff == 1) {
-                     level_diff++;
-                     return OPEN;
-                   }
-                   else {
-                     /* should never happen (error to GEDCOM spec) */
-                     gedcom_error ("GEDCOM level number is %d higher than "
-                                   "previous",
-                                   level_diff);
-                     return BADTOKEN;
-                   }
-                  }
+<INITIAL>{digit}+         ACTION_DIGITS
 
 <EXPECT_TAG>A\x00B\x00B\x00R\x00  MKTAGACTION(ABBR)
 <EXPECT_TAG>A\x00D\x00D\x00R\x00  MKTAGACTION(ADDR)
@@ -267,57 +187,21 @@ else {
 <EXPECT_TAG>W\x00I\x00F\x00E\x00  MKTAGACTION(WIFE)
 <EXPECT_TAG>W\x00I\x00L\x00L\x00  MKTAGACTION(WILL)
      
-<EXPECT_TAG>{alphanum}+ { if (strlen(yytext) > MAXGEDCTAGLEN) {
-                            gedcom_error("Tag '%s' too long, max %d chars");
-                            return BADTOKEN;
-                          }
-                          strncpy(string_buf, yytext, MAXGEDCTAGLEN+1);
-                         gedcom_lval.string = TO_INTERNAL(string_buf);
-                         BEGIN(NORMAL);
-                         return USERTAG;
-                        }
-
-{delim}      { gedcom_lval.string = TO_INTERNAL(yytext);
-               return DELIM;
-             }
-
-{any_but_delim} { gedcom_lval.string = TO_INTERNAL(yytext);
-                  return ANYCHAR;
-                }
+<EXPECT_TAG>{alphanum}+  ACTION_ALPHANUM
 
-{escape}/{non_at}  { gedcom_lval.string = TO_INTERNAL(yytext);
-                     return ESCAPE;
-                   }
+{delim}                  ACTION_DELIM
 
-{pointer}    { gedcom_lval.string = TO_INTERNAL(yytext);
-               return POINTER;
-             }
+{any_but_delim}          ACTION_ANY
 
-   /* Due to the conversion of level numbers into brackets, the
-      terminator is not important, so no token is returned here.
-      Although not strictly according to the GEDCOM spec, we'll ignore
-      whitespace just before the terminator.
-   */
+{escape}/{non_at}        ACTION_ESCAPE
 
-{gen_delim}*{terminator} { line_no++; BEGIN(INITIAL); }
+{pointer}                ACTION_POINTER
 
-   /* Eventually we have to return 1 closing bracket (for the trailer).
-      We can detect whether we have sent the closing bracket using the
-      level_diff (at eof, first it is 2, then we increment it ourselves) */
+{gen_delim}*{terminator} ACTION_TERMINATOR
 
-<<EOF>> { if (level_diff == 2) {
-           level_diff++;
-            return CLOSE;
-          }
-          else {
-           yyterminate();
-         }
-        } 
+<<EOF>>                  ACTION_EOF
 
-.  { gedcom_error("Unexpected character: '%s' (0x%02x)",
-                 yytext, yytext[0]);
-     return BADTOKEN;
-   }
+.                        ACTION_UNEXPECTED
 
 %%
 
@@ -327,35 +211,13 @@ int yywrap()
 }
 
 #ifdef LEXER_TEST
+int gedcom_lex()
+{
+  return gedcom_lohi_lex();
+}
 
 int main()
 {
-  int tok, res;
-  init_encodings();
-  set_encoding_width(TWO_BYTE_LOHI);
-  res = open_conv_to_internal("UNICODE");
-  if (!res) {
-    gedcom_error("Unable to open conversion context: %s",
-                strerror(errno));
-    return 1;
-  }
-  tok = gedcom_lohi_lex();
-  while (tok) {
-    switch(tok) {
-      case BADTOKEN: printf("BADTOKEN "); break;
-      case OPEN: printf("OPEN "); break;
-      case CLOSE: printf("CLOSE "); break;
-      case ESCAPE: printf("ESCAPE(%s) ", gedcom_lval.string); break;
-      case DELIM: printf("DELIM "); break;
-      case ANYCHAR: printf("%s ", gedcom_lval.string); break;
-      case POINTER: printf("POINTER(%s) ", gedcom_lval.string); break;
-      case USERTAG: printf("USERTAG(%s) ", gedcom_lval.string); break;
-      default: printf("TAG(%s) ", gedcom_lval.string); break;
-    }
-    tok = gedcom_lohi_lex();
-  }
-  printf("\n");
-  close_conv_to_internal();
-  return 0;
+  return test_loop(TWO_BYTE_LOHI, "UNICODE");
 }
 #endif