Properly initialize res variable.
[gedcom-parse.git] / gedcom / gedcom.y
1 /*  This program is free software; you can redistribute it and/or modify  *
2  *  it under the terms of the GNU General Public License as published by  *
3  *  the Free Software Foundation; either version 2 of the License, or     *
4  *  (at your option) any later version.                                   *
5
6  (C) 2001 by The Genes Development Team
7  Original author: Peter Verthez (Peter.Verthez@advalvas.be)
8 */
9
10 /* $Id$ */
11 /* $Name$ */
12
13 /* WARNING: THIS PARSER RELIES HEAVILY ON SOME FEATURES OF BISON.
14    DON'T TRY TO USE IT WITH YACC, IT WON'T WORK...
15 */
16
17 /* Design of the parser:
18    ---------------------
19    In general, a GEDCOM file contains records, each consisting of a line
20    (which we'll call a section), hierarchically containing other lines
21    (subsections of the section).
22
23    This means that in general we have:
24
25      A 'record' is a 'section' (sect) containing 'subsections' (subs)
26      Each 'subsection' (sub) is again a specific 'section' (sect)
27
28    In parser notation, this means:
29
30      record : sect
31
32      sect   : <some prefix> subs <some suffix>
33
34      subs   : <empty> | subs sub
35
36      sub    : sect_a | sect_b | ...
37
38    This pattern is repeated throughout the parser for the different types of
39    sections.
40    
41
42    Cardinality of the subsections:
43    -------------------------------
44    Note that in the above, the order of the subsections is of no importance.
45    Indeed, this is the case in the GEDCOM grammar.  However, this also makes
46    it difficult to check whether there are not too many subsections of a
47    specific type, or whether a mandatory subsection is indeed there.
48
49    Suppose there is a section A that can contain 0 or 1 B section and
50    2 C sections.
51
52    This can be expressed in parser notation as follows:
53
54      A    : CC | BCC | CBC | CCB
55
56    So, cardinality is indeed expressable.  However, as the number of subsection
57    types and the limits grow bigger (and even theoretically limitless), listing
58    all possible permutations becomes quickly unfeasible.
59
60    Much simpler is to say:
61
62      A    : subs
63      subs : <empty> | subs sub
64      sub  : B | C
65
66    and then check the cardinality in the semantic actions, which is the
67    solution chosen in the parser below, using the following macros:
68
69     - OPEN(<parent>)
70          Make a new context for the <parent> tag to count child tags in
71          
72     - OCCUR2(<child>, <min>, <max>)
73          Express that the <child> tag should occur at least <min> times and
74          at most <max> tags within its parent
75
76          What this actually does is the following.  It increments the counter
77          for that tag and then checks whether the maximum is exceeded.  If so,
78          then a parser error is produced.  The minimum is not actually checked
79          by this macro, but it makes the statements more declarative.
80
81     - OCCUR1(<child>, <min>)
82          Express that the <child> tag should occur at least <min> times within
83          its parent (no upper limit)
84
85          Actually, this only increments the counter for the tag, but it looks
86          very like the previous macro.
87
88          If the minimum is 0, it is not necessary to express this constraint.
89
90     - CHECKn(<child1>, ..., <childn>)
91          This closes the context for the parent tag and checks whether the
92          given <child> tags did effectively occur within the parent (i.e.
93          these are the tags that were mandatory).
94
95          Since the <min> values above are always 0 or 1 in GEDCOM, this is
96          sufficient.  All sub-tags that declare a minimum of 1 in the OCCUR
97          macros should be listed in this macro here.
98
99          The macros CHECK0 to CHECK4 are defined like this (the first one
100          has no arguments and is only used to close the parent context; note
101          that this is necessary for correct functioning).
102
103    Example of usage:
104
105      Only sections that have subsections need to use these macros.  This can
106      be done like this (the OPEN and CHECK macros are used as mid-rule
107      actions around the subsections):
108
109        head_sect : OPEN DELIM TAG_HEAD
110                    { OPEN(HEAD) }
111                    head_subs
112                    { CHECK1(SOUR) }
113                    CLOSE { <semantic actions> }
114                   
115        head_subs : <empty>
116                  | head_subs head_sub
117                  ;
118
119        head_sub  : head_sour_sect  { OCCUR2(SOUR, 1, 1) }
120                  | head_dest_sect  { OCCUR2(DEST, 0, 1) }
121                  | head_date_sect  { OCCUR2(DATE, 0, 1) }
122                  ;
123 */
124
125 /* General notes:
126
127    - The syntax analysis doesn't handle the contents of the line values;
128      this is done in the semantic analysis.
129
130  */
131
132 %{
133 #include "gedcom_internal.h"
134 #include "multilex.h"
135 #include "encoding.h"
136 #include "interface.h"
137
138 int  count_level    = 0;
139 int  fail           = 0;
140 int  compat_enabled = 1;
141 int  gedcom_high_level_debug = 0; 
142 int  compatibility  = 0; 
143 Gedcom_err_mech error_mechanism = IMMED_FAIL;
144  
145 char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
146 char *line_item_buf_ptr;
147
148 enum _COMPAT {
149   C_FTREE = 0x01
150 };
151
152 /* These are defined at the bottom of the file */ 
153 void push_countarray();
154 void set_parenttag(char* tag);
155 char* get_parenttag(); 
156 void set_parentctxt(Gedcom_ctxt ctxt);
157 Gedcom_ctxt get_parentctxt();
158 void pop_countarray();
159 int  count_tag(int tag);
160 int  check_occurrence(int tag);
161 void set_compatibility(char* program);
162 int  compat_mode(int flags); 
163
164 #define CLEAR_BUFFER(BUF)                                                     \
165      memset(BUF, 0, sizeof(BUF));
166  
167 #define HANDLE_ERROR                                                          \
168      { if (error_mechanism == IMMED_FAIL) {                                   \
169          YYABORT;                                                             \
170        }                                                                      \
171        else if (error_mechanism == DEFER_FAIL) {                              \
172          yyerrok; fail = 1;                                                   \
173        }                                                                      \
174        else if (error_mechanism == IGNORE_ERRORS) {                           \
175          yyerrok;                                                             \
176        }                                                                      \
177      }
178 #define START(PARENTTAG,PARENTCTXT)                                           \
179      { ++count_level;                                                         \
180        set_parenttag(#PARENTTAG);                                             \
181        set_parentctxt(PARENTCTXT);                                            \
182        push_countarray();                                                     \
183      }
184 #define PARENT                                                              \
185      get_parentctxt()
186 #define CHK(TAG)                                                              \
187      { if (!check_occurrence(TAG_##TAG)) {                                    \
188          char* parenttag = get_parenttag();                                   \
189          gedcom_error("The tag '%s' is mandatory within '%s', but missing",   \
190                       #TAG, parenttag);                                       \
191          HANDLE_ERROR;                                                        \
192        }                                                                      \
193      }
194 #define POP                                                                   \
195      { pop_countarray();                                                      \
196        --count_level;                                                         \
197      }
198 #define CHECK0 POP; 
199 #define CHECK1(TAG1) { CHK(TAG1); POP; }
200 #define CHECK2(TAG1,TAG2)                                                     \
201      { CHK(TAG1); CHK(TAG2); POP; }
202 #define CHECK3(TAG1,TAG2,TAG3)                                                \
203      { CHK(TAG1); CHK(TAG2); CHK(TAG3); POP; }
204 #define CHECK4(TAG1,TAG2,TAG3,TAG4)                                           \
205      { CHK(TAG1); CHK(TAG2); CHK(TAG3); CHK(TAG4); POP; } 
206 #define OCCUR1(CHILDTAG, MIN) { count_tag(TAG_##CHILDTAG); } 
207 #define OCCUR2(CHILDTAG, MIN, MAX)                                            \
208      { int num = count_tag(TAG_##CHILDTAG);                                   \
209        if (num > MAX) {                                                       \
210          char* parenttag = get_parenttag();                                   \
211          gedcom_error("The tag '%s' can maximally occur %d "                  \
212                       "time(s) within '%s'",                                  \
213                       #CHILDTAG, MAX, parenttag);                             \
214          HANDLE_ERROR;                                                        \
215        }                                                                      \
216      }
217 #define INVALID_TAG(CHILDTAG)                                                 \
218      { char* parenttag = get_parenttag();                                     \
219        gedcom_error("The tag '%s' is not a valid tag within '%s'",            \
220                     CHILDTAG, parenttag);                                     \
221        HANDLE_ERROR;                                                          \
222      }
223 #define INVALID_TOP_TAG(CHILDTAG)                                             \
224      { gedcom_error("The tag '%s' is not a valid top-level tag",              \
225                     CHILDTAG); \
226        HANDLE_ERROR; \
227      }
228
229 %}
230
231 %union {
232   int  number;
233   char *string;
234   Gedcom_ctxt ctxt;
235 }
236
237 %token_table
238 %expect 300
239
240 %token <string> BADTOKEN
241 %token <number> OPEN
242 %token <string> CLOSE
243 %token <string> ESCAPE
244 %token <string> DELIM
245 %token <string> ANYCHAR
246 %token <string> POINTER
247 %token <string> USERTAG
248 %token <string> TAG_ABBR
249 %token <string> TAG_ADDR
250 %token <string> TAG_ADR1
251 %token <string> TAG_ADR2
252 %token <string> TAG_ADOP
253 %token <string> TAG_AFN
254 %token <string> TAG_AGE
255 %token <string> TAG_AGNC
256 %token <string> TAG_ALIA
257 %token <string> TAG_ANCE
258 %token <string> TAG_ANCI
259 %token <string> TAG_ANUL
260 %token <string> TAG_ASSO
261 %token <string> TAG_AUTH
262 %token <string> TAG_BAPL
263 %token <string> TAG_BAPM
264 %token <string> TAG_BARM
265 %token <string> TAG_BASM
266 %token <string> TAG_BIRT
267 %token <string> TAG_BLES
268 %token <string> TAG_BLOB
269 %token <string> TAG_BURI
270 %token <string> TAG_CALN
271 %token <string> TAG_CAST
272 %token <string> TAG_CAUS
273 %token <string> TAG_CENS
274 %token <string> TAG_CHAN
275 %token <string> TAG_CHAR
276 %token <string> TAG_CHIL
277 %token <string> TAG_CHR
278 %token <string> TAG_CHRA
279 %token <string> TAG_CITY
280 %token <string> TAG_CONC
281 %token <string> TAG_CONF
282 %token <string> TAG_CONL
283 %token <string> TAG_CONT
284 %token <string> TAG_COPR
285 %token <string> TAG_CORP
286 %token <string> TAG_CREM
287 %token <string> TAG_CTRY
288 %token <string> TAG_DATA
289 %token <string> TAG_DATE
290 %token <string> TAG_DEAT
291 %token <string> TAG_DESC
292 %token <string> TAG_DESI
293 %token <string> TAG_DEST
294 %token <string> TAG_DIV
295 %token <string> TAG_DIVF
296 %token <string> TAG_DSCR
297 %token <string> TAG_EDUC
298 %token <string> TAG_EMIG
299 %token <string> TAG_ENDL
300 %token <string> TAG_ENGA
301 %token <string> TAG_EVEN
302 %token <string> TAG_FAM
303 %token <string> TAG_FAMC
304 %token <string> TAG_FAMF
305 %token <string> TAG_FAMS
306 %token <string> TAG_FCOM
307 %token <string> TAG_FILE
308 %token <string> TAG_FORM
309 %token <string> TAG_GEDC
310 %token <string> TAG_GIVN
311 %token <string> TAG_GRAD
312 %token <string> TAG_HEAD
313 %token <string> TAG_HUSB
314 %token <string> TAG_IDNO
315 %token <string> TAG_IMMI
316 %token <string> TAG_INDI
317 %token <string> TAG_LANG
318 %token <string> TAG_LEGA
319 %token <string> TAG_MARB
320 %token <string> TAG_MARC
321 %token <string> TAG_MARL
322 %token <string> TAG_MARR
323 %token <string> TAG_MARS
324 %token <string> TAG_MEDI
325 %token <string> TAG_NAME
326 %token <string> TAG_NATI
327 %token <string> TAG_NATU
328 %token <string> TAG_NCHI
329 %token <string> TAG_NICK
330 %token <string> TAG_NMR
331 %token <string> TAG_NOTE
332 %token <string> TAG_NPFX
333 %token <string> TAG_NSFX
334 %token <string> TAG_OBJE
335 %token <string> TAG_OCCU
336 %token <string> TAG_ORDI
337 %token <string> TAG_ORDN
338 %token <string> TAG_PAGE
339 %token <string> TAG_PEDI
340 %token <string> TAG_PHON
341 %token <string> TAG_PLAC
342 %token <string> TAG_POST
343 %token <string> TAG_PROB
344 %token <string> TAG_PROP
345 %token <string> TAG_PUBL
346 %token <string> TAG_QUAY
347 %token <string> TAG_REFN
348 %token <string> TAG_RELA
349 %token <string> TAG_RELI
350 %token <string> TAG_REPO
351 %token <string> TAG_RESI
352 %token <string> TAG_RESN
353 %token <string> TAG_RETI
354 %token <string> TAG_RFN
355 %token <string> TAG_RIN
356 %token <string> TAG_ROLE
357 %token <string> TAG_SEX
358 %token <string> TAG_SLGC
359 %token <string> TAG_SLGS
360 %token <string> TAG_SOUR
361 %token <string> TAG_SPFX
362 %token <string> TAG_SSN
363 %token <string> TAG_STAE
364 %token <string> TAG_STAT
365 %token <string> TAG_SUBM
366 %token <string> TAG_SUBN
367 %token <string> TAG_SURN
368 %token <string> TAG_TEMP
369 %token <string> TAG_TEXT
370 %token <string> TAG_TIME
371 %token <string> TAG_TITL
372 %token <string> TAG_TRLR
373 %token <string> TAG_TYPE
374 %token <string> TAG_VERS
375 %token <string> TAG_WIFE
376 %token <string> TAG_WILL
377
378 %type <string> anystdtag
379 %type <string> anytoptag
380 %type <string> line_item
381 %type <string> line_value
382 %type <string> mand_line_item
383 %type <string> mand_pointer
384 %type <string> note_line_item
385 %type <string> anychar
386 %type <string> opt_xref
387 %type <string> opt_value
388 %type <ctxt> head_sect
389
390 %%
391
392 file        : head_sect records trlr_sect
393                { if (fail == 1) YYABORT; }
394             ;
395
396 records     : /* empty */
397             | records record
398             ;
399
400 record      : fam_rec
401             | indiv_rec
402             | multim_rec
403             | note_rec
404             | repos_rec
405             | source_rec
406             | submis_rec
407             | submit_rec
408             | no_std_rec
409             ;
410
411 /*********************************************************************/
412 /**** Header                                                      ****/
413 /*********************************************************************/
414 head_sect    : OPEN DELIM TAG_HEAD
415                { $<ctxt>$ = start_record(REC_HEAD, $1, NULL, $3);
416                  START(HEAD, $<ctxt>$) }
417                head_subs
418                { if (compat_mode(C_FTREE))
419                    CHECK3(SOUR, GEDC, CHAR)
420                  else
421                    CHECK4(SOUR, SUBM, GEDC, CHAR)
422                }
423                CLOSE
424                { end_record(REC_HEAD, $<ctxt>4); }
425              ;
426
427 head_subs    : /* empty */
428              | head_subs head_sub
429              ;
430
431 head_sub     : head_sour_sect  { OCCUR2(SOUR, 1, 1) }
432              | head_dest_sect  { OCCUR2(DEST, 0, 1) }
433              | head_date_sect  { OCCUR2(DATE, 0, 1) }
434              | head_subm_sect  { OCCUR2(SUBM, 1, 1) }
435              | head_subn_sect  { OCCUR2(SUBN, 0, 1) }
436              | head_file_sect  { OCCUR2(FILE, 0, 1) }
437              | head_copr_sect  { OCCUR2(COPR, 0, 1) }
438              | head_gedc_sect  { OCCUR2(GEDC, 1, 1) }
439              | head_char_sect  { OCCUR2(CHAR, 1, 1) }
440              | head_lang_sect  { OCCUR2(LANG, 0, 1) }
441              | head_plac_sect  { OCCUR2(PLAC, 0, 1) }
442              | head_note_sect  { OCCUR2(NOTE, 0, 1) }
443              | no_std_sub
444              ;
445
446 /* HEAD.SOUR */
447 head_sour_sect : OPEN DELIM TAG_SOUR mand_line_item 
448                  { set_compatibility($4);
449                    $<ctxt>$ = start_element(ELT_HEAD_SOUR, PARENT,
450                                             $1, $3, $4, $4);
451                    START(SOUR, $<ctxt>$)
452                  }
453                  head_sour_subs
454                  { CHECK0 }
455                  CLOSE
456                  { end_element(ELT_HEAD_SOUR, PARENT, $<ctxt>5, NULL); }
457                ;
458
459 head_sour_subs : /* empty */
460                | head_sour_subs head_sour_sub
461                ;
462
463 head_sour_sub : head_sour_vers_sect  { OCCUR2(VERS, 0, 1) }
464               | head_sour_name_sect  { OCCUR2(NAME, 0, 1) }
465               | head_sour_corp_sect  { OCCUR2(CORP, 0, 1) } 
466               | head_sour_data_sect  { OCCUR2(DATA, 0, 1) }
467               | no_std_sub
468               ;
469
470 head_sour_vers_sect : OPEN DELIM TAG_VERS mand_line_item
471                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_VERS, PARENT,
472                                                  $1, $3, $4, $4);
473                         START(VERS, $<ctxt>$)
474                       }
475                       no_std_subs
476                       { CHECK0 }
477                       CLOSE
478                       { end_element(ELT_HEAD_SOUR_VERS,
479                                     PARENT, $<ctxt>5, NULL);
480                       }
481                     ;
482 head_sour_name_sect : OPEN DELIM TAG_NAME mand_line_item
483                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_NAME, PARENT,
484                                                  $1, $3, $4, $4);
485                         START(NAME, $<ctxt>$)
486                       }
487                       no_std_subs
488                       { CHECK0 }
489                       CLOSE
490                       { end_element(ELT_HEAD_SOUR_NAME,
491                                     PARENT, $<ctxt>5, NULL);
492                       }
493                     ;
494 head_sour_corp_sect : OPEN DELIM TAG_CORP mand_line_item 
495                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_CORP, PARENT,
496                                                  $1, $3, $4, $4);
497                         START(CORP, $<ctxt>$)
498                       }
499                       head_sour_corp_subs
500                       { CHECK0 }
501                       CLOSE
502                       { end_element(ELT_HEAD_SOUR_CORP,
503                                     PARENT, $<ctxt>5, NULL);
504                       }
505                     ;
506
507 head_sour_corp_subs : /* empty */
508                     | head_sour_corp_subs head_sour_corp_sub
509                     ;
510
511 head_sour_corp_sub : addr_struc_sub  /* 0:1 */
512                    | no_std_sub
513                    ;
514
515 head_sour_data_sect : OPEN DELIM TAG_DATA mand_line_item 
516                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA, PARENT,
517                                                  $1, $3, $4, $4);
518                         START(DATA, $<ctxt>$)
519                       }
520                       head_sour_data_subs
521                       { CHECK0 }
522                       CLOSE
523                       { end_element(ELT_HEAD_SOUR_DATA,
524                                     PARENT, $<ctxt>5, NULL);
525                       }
526                     ;
527
528 head_sour_data_subs : /* empty */
529                     | head_sour_data_subs head_sour_data_sub
530                     ;
531
532 head_sour_data_sub : head_sour_data_date_sect  { OCCUR2(DATE, 0, 1) }
533                    | head_sour_data_copr_sect  { OCCUR2(COPR, 0, 1) }
534                    | no_std_sub
535                    ;
536
537 head_sour_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
538                            { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_DATE,
539                                                       PARENT, $1, $3, $4, $4);
540                              START(DATE, $<ctxt>$)
541                            }
542                            no_std_subs
543                            { CHECK0 }
544                            CLOSE
545                            { end_element(ELT_HEAD_SOUR_DATA_DATE,
546                                          PARENT, $<ctxt>5, NULL);
547                            }
548                          ;
549 head_sour_data_copr_sect : OPEN DELIM TAG_COPR mand_line_item
550                            { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_COPR,
551                                                       PARENT, $1, $3, $4, $4);
552                              START(COPR, $<ctxt>$)
553                            }
554                            no_std_subs
555                            { CHECK0 }
556                            CLOSE
557                            { end_element(ELT_HEAD_SOUR_DATA_COPR,
558                                          PARENT, $<ctxt>5, NULL);
559                            }
560                          ;
561
562 /* HEAD.DEST */
563 head_dest_sect : OPEN DELIM TAG_DEST mand_line_item
564                  { $<ctxt>$ = start_element(ELT_HEAD_DEST,
565                                             PARENT, $1, $3, $4, $4);
566                    START(DEST, $<ctxt>$)
567                  }
568                  no_std_subs
569                  { CHECK0 }
570                  CLOSE
571                  { end_element(ELT_HEAD_DEST,
572                                PARENT, $<ctxt>5, NULL);
573                  }
574                ;
575
576 /* HEAD.DATE */
577 head_date_sect : OPEN DELIM TAG_DATE mand_line_item 
578                  { $<ctxt>$ = start_element(ELT_HEAD_DATE,
579                                             PARENT, $1, $3, $4, $4);
580                    START(DATE, $<ctxt>$)
581                  }
582                  head_date_subs
583                  { CHECK0 }
584                  CLOSE
585                  { end_element(ELT_HEAD_DATE,
586                                PARENT, $<ctxt>5, NULL);
587                  }
588                ;
589
590 head_date_subs : /* empty */
591                | head_date_subs head_date_sub
592                ;
593
594 head_date_sub  : head_date_time_sect  { OCCUR2(TIME, 0, 1) }
595                | no_std_sub
596                ;
597
598 head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
599                       { $<ctxt>$ = start_element(ELT_HEAD_DATE_TIME,
600                                                  PARENT, $1, $3, $4, $4);
601                         START(TIME, $<ctxt>$)
602                       }
603                       no_std_subs
604                       { CHECK0 }
605                       CLOSE
606                       { end_element(ELT_HEAD_DATE_TIME,
607                                     PARENT, $<ctxt>5, NULL);
608                       }
609                     ;
610
611 /* HEAD.SUBM */
612 head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
613                  { $<ctxt>$ = start_element(ELT_HEAD_SUBM,
614                                             PARENT, $1, $3, $4, $4);
615                    START(SUBM, $<ctxt>$)
616                  }
617                  no_std_subs
618                  { CHECK0 }
619                  CLOSE
620                  { end_element(ELT_HEAD_SUBM,
621                                PARENT, $<ctxt>5, NULL);
622                  }
623                ;
624 /* HEAD.SUBN */
625 head_subn_sect : OPEN DELIM TAG_SUBN mand_pointer 
626                  { $<ctxt>$ = start_element(ELT_HEAD_SUBN,
627                                             PARENT, $1, $3, $4, $4);
628                    START(SUBN, $<ctxt>$)
629                  }
630                  no_std_subs
631                  { CHECK0 }
632                  CLOSE
633                  { end_element(ELT_HEAD_SUBN,
634                                PARENT, $<ctxt>5, NULL);
635                  }
636                ;
637 /* HEAD.FILE */
638 head_file_sect : OPEN DELIM TAG_FILE mand_line_item 
639                  { $<ctxt>$ = start_element(ELT_HEAD_FILE,
640                                             PARENT, $1, $3, $4, $4);
641                    START(FILE, $<ctxt>$)
642                  }
643                  no_std_subs
644                  { CHECK0 }
645                  CLOSE
646                  { end_element(ELT_HEAD_FILE, PARENT, $<ctxt>5, NULL);
647                  }
648                ;
649 /* HEAD.COPR */
650 head_copr_sect : OPEN DELIM TAG_COPR mand_line_item 
651                  { $<ctxt>$ = start_element(ELT_HEAD_COPR,
652                                             PARENT, $1, $3, $4, $4);
653                    START(COPR, $<ctxt>$)
654                  }
655                  no_std_subs
656                  { CHECK0 }
657                  CLOSE
658                  { end_element(ELT_HEAD_COPR, PARENT, $<ctxt>5, NULL);
659                  }
660                ;
661 /* HEAD.GEDC */
662 head_gedc_sect : OPEN DELIM TAG_GEDC
663                  { $<ctxt>$ = start_element(ELT_HEAD_GEDC,
664                                             PARENT, $1, $3, NULL, NULL);
665                    START(GEDC, $<ctxt>$)
666                  }
667                  head_gedc_subs
668                  { CHECK2(VERS, FORM) }
669                  CLOSE
670                  { end_element(ELT_HEAD_GEDC, PARENT, $<ctxt>4, NULL);
671                  }
672                ;
673
674 head_gedc_subs : /* empty */
675                | head_gedc_subs head_gedc_sub
676                ;
677
678 head_gedc_sub  : head_gedc_vers_sect  { OCCUR2(VERS, 1, 1) }
679                | head_gedc_form_sect  { OCCUR2(FORM, 1, 1) }
680                | no_std_sub
681                ;
682 head_gedc_vers_sect : OPEN DELIM TAG_VERS mand_line_item  
683                       { $<ctxt>$ = start_element(ELT_HEAD_GEDC_VERS,
684                                                  PARENT, $1, $3, $4, $4);
685                         START(VERS, $<ctxt>$)
686                       }
687                       no_std_subs
688                       { CHECK0 }
689                       CLOSE
690                       { end_element(ELT_HEAD_GEDC_VERS,
691                                     PARENT, $<ctxt>5, NULL);
692                       }
693                     ;
694 head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item   
695                       { $<ctxt>$ = start_element(ELT_HEAD_GEDC_FORM,
696                                                  PARENT, $1, $3, $4, $4);
697                         START(FORM, $<ctxt>$)
698                       }
699                       no_std_subs
700                       { CHECK0 }
701                       CLOSE
702                       { end_element(ELT_HEAD_GEDC_FORM,
703                                     PARENT, $<ctxt>5, NULL);
704                       }
705                     ;
706
707 /* HEAD.CHAR */
708 head_char_sect : OPEN DELIM TAG_CHAR mand_line_item 
709                  { if (open_conv_to_internal($4) == 0) YYERROR;
710                    $<ctxt>$ = start_element(ELT_HEAD_CHAR,
711                                             PARENT, $1, $3, $4, $4);
712                    START(CHAR, $<ctxt>$)
713                  }
714                  head_char_subs
715                  { CHECK0 }
716                  CLOSE
717                  { end_element(ELT_HEAD_CHAR, PARENT, $<ctxt>5, NULL);
718                  }
719                ;
720
721 head_char_subs : /* empty */
722                | head_char_subs head_char_sub
723                ;
724
725 head_char_sub  : head_char_vers_sect  { OCCUR2(VERS, 0, 1) }
726                | no_std_sub
727                ;
728 head_char_vers_sect : OPEN DELIM TAG_VERS mand_line_item   
729                       { $<ctxt>$ = start_element(ELT_HEAD_CHAR_VERS,
730                                                  PARENT, $1, $3, $4, $4);
731                         START(VERS, $<ctxt>$)
732                       }
733                       no_std_subs
734                       { CHECK0 }
735                       CLOSE
736                       { end_element(ELT_HEAD_CHAR_VERS,
737                                     PARENT, $<ctxt>5, NULL);
738                       }
739                     ;
740
741 /* HEAD.LANG */
742 head_lang_sect : OPEN DELIM TAG_LANG mand_line_item   
743                  { $<ctxt>$ = start_element(ELT_HEAD_LANG,
744                                             PARENT, $1, $3, $4, $4);
745                    START(LANG, $<ctxt>$)
746                  }
747                  no_std_subs
748                  { CHECK0 }
749                  CLOSE
750                  { end_element(ELT_HEAD_LANG, PARENT, $<ctxt>5, NULL);
751                  }
752                ;
753 /* HEAD.PLAC */
754 head_plac_sect : OPEN DELIM TAG_PLAC
755                  { $<ctxt>$ = start_element(ELT_HEAD_PLAC,
756                                             PARENT, $1, $3, NULL, NULL);
757                    START(PLAC, $<ctxt>$)
758                  }
759                  head_plac_subs
760                  { CHECK1(FORM) }
761                  CLOSE
762                  { end_element(ELT_HEAD_PLAC, PARENT, $<ctxt>4, NULL);
763                  }
764                ;
765
766 head_plac_subs : /* empty */
767                | head_plac_subs head_plac_sub
768                ;
769
770 head_plac_sub  : head_plac_form_sect  { OCCUR2(FORM, 1, 1) }
771                | no_std_sub
772                ;
773 head_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item   
774                       { $<ctxt>$ = start_element(ELT_HEAD_PLAC_FORM,
775                                                  PARENT, $1, $3, $4, $4);
776                         START(FORM, $<ctxt>$)
777                       }
778                       no_std_subs
779                       { CHECK0 }
780                       CLOSE
781                       { end_element(ELT_HEAD_PLAC_FORM,
782                                     PARENT, $<ctxt>5, NULL);
783                       }
784                     ;
785
786 /* HEAD.NOTE */
787 head_note_sect : OPEN DELIM TAG_NOTE mand_line_item 
788                  { $<ctxt>$ = start_element(ELT_HEAD_NOTE,
789                                             PARENT, $1, $3, $4, $4);
790                    START(NOTE, $<ctxt>$)
791                  }
792                  head_note_subs
793                  { CHECK0 }
794                  CLOSE
795                  { end_element(ELT_HEAD_NOTE, PARENT, $<ctxt>5, NULL);
796                  }
797                ;
798
799 head_note_subs : /* empty */
800                | head_note_subs head_note_sub
801                ;
802
803 head_note_sub  : continuation_sub  /* 0:M */
804                | no_std_sub
805                ;
806
807 /*********************************************************************/
808 /**** Trailer                                                     ****/
809 /*********************************************************************/
810 /* Don't need callbacks here, there is no information... */
811 trlr_sect   : OPEN DELIM TAG_TRLR CLOSE { }
812             ;
813
814 /*********************************************************************/
815 /**** Family record                                               ****/
816 /*********************************************************************/
817 fam_rec      : OPEN DELIM POINTER DELIM TAG_FAM
818                { $<ctxt>$ = start_record(REC_FAM, $1, $3, $5);
819                  START(FAM, $<ctxt>$) }
820                fam_subs
821                { CHECK0 }
822                CLOSE
823                { end_record(REC_FAM, $<ctxt>6); }
824              ;
825
826 fam_subs     : /* empty */
827              | fam_subs fam_sub
828              ;
829
830 fam_sub      : fam_event_struc_sub  /* 0:M */
831              | fam_husb_sect  { OCCUR2(HUSB, 0, 1) }
832              | fam_wife_sect  { OCCUR2(WIFE, 0, 1) }
833              | fam_chil_sect  /* 0:M */
834              | fam_nchi_sect  { OCCUR2(NCHI, 0, 1) }
835              | fam_subm_sect  /* 0:M */
836              | lds_spouse_seal_sub  /* 0:M */
837              | source_cit_sub  /* 0:M */
838              | multim_link_sub  /* 0:M */
839              | note_struc_sub  /* 0:M */
840              | ident_struc_sub  /* 0:1 */
841              | change_date_sub  /* 0:1 */
842              | no_std_sub
843              ;
844
845 /* FAM.HUSB */
846 fam_husb_sect : OPEN DELIM TAG_HUSB mand_pointer    
847                 { START(HUSB, NULL) } no_std_subs { CHECK0 } CLOSE
848                        { }
849               ;
850
851 /* FAM.WIFE */
852 fam_wife_sect : OPEN DELIM TAG_WIFE mand_pointer 
853                 { START(WIFE, NULL) } no_std_subs { CHECK0 } CLOSE
854                        { }
855               ;
856
857 /* FAM.CHIL */
858 fam_chil_sect : OPEN DELIM TAG_CHIL mand_pointer
859                 { START(CHIL, NULL) } no_std_subs { CHECK0 } CLOSE
860                        { }
861               ;
862
863 /* FAM.NCHI */
864 fam_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item    
865                 { START(NCHI, NULL) } no_std_subs { CHECK0 } CLOSE
866                        { }
867               ;
868
869 /* FAM.SUBM */
870 fam_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
871                 { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE
872                        { }
873               ;
874
875 /*********************************************************************/
876 /**** Individual record                                           ****/
877 /*********************************************************************/
878 indiv_rec   : OPEN DELIM POINTER DELIM TAG_INDI
879               { $<ctxt>$ = start_record(REC_INDI, $1, $3, $5);
880                 START(INDI, $<ctxt>$) }
881               indi_subs
882               { CHECK0 }
883               CLOSE
884               { end_record(REC_INDI, $<ctxt>6); }
885             ;
886
887 indi_subs   : /* empty */
888             | indi_subs indi_sub
889             ;
890
891 indi_sub    : indi_resn_sect  { OCCUR2(RESN, 0, 1) }
892             | pers_name_struc_sub  /* 0:M */
893             | indi_sex_sect  { OCCUR2(SEX, 0, 1) }
894             | indiv_even_struc_sub  /* 0:M */
895             | indiv_attr_struc_sub  /* 0:M */
896             | lds_indiv_ord_sub  /* 0:M */
897             | chi_fam_link_sub  /* 0:M */
898             | spou_fam_link_sub  /* 0:M */
899             | indi_subm_sect  /* 0:M */
900             | assoc_struc_sub  /* 0:M */
901             | indi_alia_sect  /* 0:M */
902             | indi_anci_sect  /* 0:M */
903             | indi_desi_sect  /* 0:M */
904             | source_cit_sub  /* 0:M */
905             | multim_link_sub  /* 0:M */
906             | note_struc_sub  /* 0:M */
907             | indi_rfn_sect  { OCCUR2(RFN, 0, 1) }
908             | indi_afn_sect  /* 0:M */
909             | ident_struc_sub  /* 0:1 */
910             | change_date_sub  /* 0:1 */
911             | ftree_addr_sect { if (!compat_mode(C_FTREE))
912                                   INVALID_TAG("ADDR");
913                               }
914             | no_std_sub
915             ;
916
917 /* INDI.RESN */
918 indi_resn_sect : OPEN DELIM TAG_RESN mand_line_item     
919                  { START(RESN, NULL) } no_std_subs { CHECK0 } CLOSE { }
920                ;
921
922 /* INDI.SEX */
923 indi_sex_sect  : OPEN DELIM TAG_SEX mand_line_item     
924                  { START(SEX, NULL) } no_std_subs { CHECK0 } CLOSE { }
925                ;
926
927 /* INDI.SUBM */
928 indi_subm_sect : OPEN DELIM TAG_SUBM mand_pointer 
929                  { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
930                ;
931
932 /* INDI.ALIA */
933 indi_alia_sect : OPEN DELIM TAG_ALIA mand_pointer
934                  { START(ALIA, NULL) } no_std_subs { CHECK0 } CLOSE { }
935                ;
936
937 /* INDI.ANCI */
938 indi_anci_sect : OPEN DELIM TAG_ANCI mand_pointer
939                  { START(ANCI, NULL) } no_std_subs { CHECK0 } CLOSE { }
940                ;
941
942 /* INDI.DESI */
943 indi_desi_sect : OPEN DELIM TAG_DESI mand_pointer
944                  { START(DESI, NULL) } no_std_subs { CHECK0 } CLOSE { }
945                ;
946
947 /* INDI.RFN */
948 indi_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item     
949                  { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
950                ;
951
952 /* INDI.AFN */
953 indi_afn_sect  : OPEN DELIM TAG_AFN mand_line_item      
954                  { START(AFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
955                ;
956
957 /* INDI.ADDR (Only for 'ftree' compatibility) */
958 ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
959                   { START(ADDR, NULL) } no_std_subs { CHECK0 } CLOSE { }
960
961 /*********************************************************************/
962 /**** Multimedia record                                           ****/
963 /*********************************************************************/
964 multim_rec  : OPEN DELIM POINTER DELIM TAG_OBJE
965               { $<ctxt>$ = start_record(REC_OBJE, $1, $3, $5);
966                 START(OBJE, $<ctxt>$) }
967               obje_subs
968               { CHECK2(FORM, BLOB) }
969               CLOSE
970               { end_record(REC_OBJE, $<ctxt>6); }
971             ;
972
973 obje_subs   : /* empty */
974             | obje_subs obje_sub
975             ;
976
977 obje_sub    : obje_form_sect  { OCCUR2(FORM, 1, 1) }
978             | obje_titl_sect  { OCCUR2(TITL, 0, 1) }
979             | note_struc_sub  /* 0:M */
980             | obje_blob_sect  { OCCUR2(BLOB, 1, 1) }
981             | obje_obje_sect  { OCCUR2(OBJE, 0, 1) }
982             | ident_struc_sub  /* 0:1 */
983             | change_date_sub  /* 0:1 */
984             | no_std_sub
985             ;
986
987 /* OBJE.FORM */
988 obje_form_sect : OPEN DELIM TAG_FORM mand_line_item       
989                  { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
990                ;
991
992 /* OBJE.TITL */
993 obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item       
994                  { START(TITL, NULL) } no_std_subs { CHECK0 } CLOSE { }
995                ;
996
997 /* OBJE.BLOB */
998 obje_blob_sect : OPEN DELIM TAG_BLOB
999                  { START(BLOB, NULL) }
1000                  obje_blob_subs
1001                  { CHECK1(CONT) }
1002                  CLOSE { }
1003                ;
1004
1005 obje_blob_subs : /* empty */
1006                | obje_blob_subs obje_blob_sub
1007                ;
1008
1009 obje_blob_sub  : obje_blob_cont_sect  { OCCUR1(CONT, 1) }
1010                | no_std_sub
1011                ;
1012
1013 obje_blob_cont_sect : OPEN DELIM TAG_CONT mand_line_item        
1014                       { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1015                     ;
1016
1017 /* OBJE.OBJE */
1018 obje_obje_sect : OPEN DELIM TAG_OBJE mand_pointer 
1019                  { START(OBJE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1020                ;
1021
1022 /*********************************************************************/
1023 /**** Note record                                                 ****/
1024 /*********************************************************************/
1025 note_rec    : OPEN DELIM POINTER DELIM TAG_NOTE note_line_item
1026               { $<ctxt>$ = start_record(REC_NOTE, $1, $3, $5);
1027                 START(NOTE, $<ctxt>$) }
1028               note_subs
1029               { CHECK0 }
1030               CLOSE
1031               { end_record(REC_NOTE, $<ctxt>6); }
1032             ;
1033
1034 note_line_item : /* empty */
1035                    { if (!compat_mode(C_FTREE)) {
1036                        gedcom_error("Missing value"); YYERROR;
1037                      }
1038                    }
1039                | DELIM line_item
1040                    { gedcom_debug_print("==Val: %s==\n", $2);
1041                      $$ = $2; }
1042                ;
1043
1044 note_subs   : /* empty */
1045             | note_subs note_sub
1046             ;
1047
1048 note_sub    : continuation_sub  /* 0:M */
1049             | source_cit_sub  /* 0:M */
1050             | ident_struc_sub  /* 0:1 */
1051             | change_date_sub  /* 0:1 */
1052             | no_std_sub
1053             ;
1054
1055 /*********************************************************************/
1056 /**** Repository record                                           ****/
1057 /*********************************************************************/
1058 repos_rec   : OPEN DELIM POINTER DELIM TAG_REPO
1059               { $<ctxt>$ = start_record(REC_REPO, $1, $3, $5);
1060                 START(REPO, $<ctxt>$) }
1061               repo_subs
1062               { CHECK0 }
1063               CLOSE
1064               { end_record(REC_REPO, $<ctxt>6); }
1065             ;
1066
1067 repo_subs   : /* empty */
1068             | repo_subs repo_sub
1069             ;
1070
1071 repo_sub    : repo_name_sect  { OCCUR2(NAME, 0, 1) }
1072             | addr_struc_sub  /* 0:1 */
1073             | note_struc_sub  /* 0:M */
1074             | ident_struc_sub  /* 0:1 */
1075             | change_date_sub  /* 0:1 */
1076             | no_std_sub
1077             ;
1078
1079 /* REPO.NAME */
1080 repo_name_sect : OPEN DELIM TAG_NAME mand_line_item         
1081                  { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE {}
1082                ;
1083
1084 /*********************************************************************/
1085 /**** Source record                                               ****/
1086 /*********************************************************************/
1087 source_rec  : OPEN DELIM POINTER DELIM TAG_SOUR
1088               { $<ctxt>$ = start_record(REC_SOUR, $1, $3, $5);
1089                 START(SOUR, $<ctxt>$) }
1090               sour_subs
1091               { CHECK0 }
1092               CLOSE
1093               { end_record(REC_SOUR, $<ctxt>6); }
1094             ;
1095
1096 sour_subs   : /* empty */
1097             | sour_subs sour_sub
1098             ;
1099
1100 sour_sub    : sour_data_sect  { OCCUR2(DATA, 0, 1) }
1101             | sour_auth_sect  { OCCUR2(AUTH, 0, 1) }
1102             | sour_titl_sect  { OCCUR2(TITL, 0, 1) }
1103             | sour_abbr_sect  { OCCUR2(ABBR, 0, 1) }
1104             | sour_publ_sect  { OCCUR2(PUBL, 0, 1) }
1105             | sour_text_sect  { OCCUR2(TEXT, 0, 1) }
1106             | source_repos_cit_sub  /* 0:1 */
1107             | multim_link_sub  /* 0:M */
1108             | note_struc_sub  /* 0:M */
1109             | ident_struc_sub  /* 0:1 */
1110             | change_date_sub  /* 0:1 */
1111             | no_std_sub
1112             ;
1113
1114 /* SOUR.DATA */
1115 sour_data_sect : OPEN DELIM TAG_DATA
1116                  { START(DATA, NULL) }
1117                  sour_data_subs
1118                  { CHECK0 }
1119                  CLOSE { }
1120                ;
1121
1122 sour_data_subs : /* empty */
1123                | sour_data_subs sour_data_sub
1124                ;
1125
1126 sour_data_sub  : sour_data_even_sect  /* 0:M */
1127                | sour_data_agnc_sect  { OCCUR2(AGNC, 0, 1) }
1128                | note_struc_sub  /* 0:M */
1129                | no_std_sub
1130                ;
1131
1132 sour_data_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
1133                       { START(EVEN, NULL) }
1134                       sour_data_even_subs
1135                       { CHECK0 }
1136                       CLOSE { }
1137                     ;
1138
1139 sour_data_even_subs : /* empty */
1140                     | sour_data_even_subs sour_data_even_sub
1141                     ;
1142
1143 sour_data_even_sub  : sour_data_even_date_sect { OCCUR2(DATE, 0, 1) }
1144                     | sour_data_even_plac_sect { OCCUR2(PLAC, 0, 1) }
1145                     | no_std_sub
1146                     ;
1147
1148 sour_data_even_date_sect : OPEN DELIM TAG_DATE mand_line_item          
1149                            { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1150                          ;
1151
1152 sour_data_even_plac_sect : OPEN DELIM TAG_PLAC mand_line_item          
1153                            { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1154                          ;
1155
1156 sour_data_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item          
1157                       { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1158                     ;
1159
1160 /* SOUR.AUTH */
1161 sour_auth_sect : OPEN DELIM TAG_AUTH mand_line_item
1162                  { START(AUTH, NULL) }
1163                  sour_auth_subs
1164                  { CHECK0 }
1165                  CLOSE { }
1166                ;
1167
1168 sour_auth_subs : /* empty */
1169                | sour_auth_subs sour_auth_sub
1170                ;
1171
1172 sour_auth_sub  : continuation_sub  /* 0:M */
1173                | no_std_sub
1174                ;
1175
1176 /* SOUR.TITL */
1177 sour_titl_sect : OPEN DELIM TAG_TITL mand_line_item  
1178                  { START(TITL, NULL) }
1179                  sour_titl_subs 
1180                  { CHECK0 }
1181                  CLOSE { }
1182                ;
1183
1184 sour_titl_subs : /* empty */
1185                | sour_titl_subs sour_titl_sub
1186                ;
1187
1188 sour_titl_sub  : continuation_sub  /* 0:M */
1189                | no_std_sub
1190                ;
1191
1192 /* SOUR.ABBR */
1193 sour_abbr_sect : OPEN DELIM TAG_ABBR mand_line_item           
1194                  { START(ABBR, NULL) } no_std_subs { CHECK0 } CLOSE { }
1195                ;
1196
1197 /* SOUR.PUBL */
1198 sour_publ_sect : OPEN DELIM TAG_PUBL mand_line_item  
1199                  { START(PUBL, NULL) }
1200                  sour_publ_subs  
1201                  { CHECK0 }
1202                  CLOSE { }
1203                ;
1204
1205 sour_publ_subs : /* empty */
1206                | sour_publ_subs sour_publ_sub
1207                ;
1208
1209 sour_publ_sub  : continuation_sub  /* 0:M */
1210                | no_std_sub
1211                ;
1212
1213 /* SOUR.TEXT */
1214 sour_text_sect : OPEN DELIM TAG_TEXT mand_line_item   
1215                  { START(TEXT, NULL) }
1216                  sour_text_subs  
1217                  { CHECK0 }
1218                  CLOSE { }
1219                ;
1220
1221 sour_text_subs : /* empty */
1222                | sour_text_subs sour_text_sub
1223                ;
1224
1225 sour_text_sub  : continuation_sub  /* 0:M */
1226                | no_std_sub
1227                ;
1228
1229 /*********************************************************************/
1230 /**** Submission record                                           ****/
1231 /*********************************************************************/
1232 submis_rec  : OPEN DELIM POINTER DELIM TAG_SUBN    
1233               { $<ctxt>$ = start_record(REC_SUBN, $1, $3, $5);
1234                 START(SUBN, $<ctxt>$) }
1235               subn_subs
1236               { CHECK0 }
1237               CLOSE
1238               { end_record(REC_SUBN, $<ctxt>6); }
1239             ;
1240
1241 subn_subs   : /* empty */
1242             | subn_subs subn_sub
1243             ;
1244
1245 subn_sub    : subn_subm_sect  { OCCUR2(SUBM, 0, 1) }
1246             | subn_famf_sect  { OCCUR2(FAMF, 0, 1) }
1247             | subn_temp_sect  { OCCUR2(TEMP, 0, 1) }
1248             | subn_ance_sect  { OCCUR2(ANCE, 0, 1) }
1249             | subn_desc_sect  { OCCUR2(DESC, 0, 1) }
1250             | subn_ordi_sect  { OCCUR2(ORDI, 0, 1) }
1251             | subn_rin_sect  { OCCUR2(RIN, 0, 1) }
1252             | no_std_sub
1253             ;
1254
1255 /* SUBN.SUBM */
1256 subn_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
1257                  { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1258                ;
1259
1260 /* SUBN.FAMF */
1261 subn_famf_sect : OPEN DELIM TAG_FAMF mand_line_item            
1262                  { START(FAMF, NULL) } no_std_subs { CHECK0 } CLOSE { }
1263                ;
1264
1265 /* SUBN.TEMP */
1266 subn_temp_sect : OPEN DELIM TAG_TEMP mand_line_item            
1267                  { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1268                ;
1269
1270 /* SUBN.ANCE */
1271 subn_ance_sect : OPEN DELIM TAG_ANCE mand_line_item            
1272                  { START(ANCE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1273                ;
1274
1275 /* SUBN.DESC */
1276 subn_desc_sect : OPEN DELIM TAG_DESC mand_line_item            
1277                  { START(DESC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1278                ;
1279
1280 /* SUBN.ORDI */
1281 subn_ordi_sect : OPEN DELIM TAG_ORDI mand_line_item            
1282                  { START(ORDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1283                ;
1284
1285 /* SUBN.RIN */
1286 subn_rin_sect  : OPEN DELIM TAG_RIN mand_line_item            
1287                  { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1288                ;
1289
1290 /*********************************************************************/
1291 /**** Submitter record                                            ****/
1292 /*********************************************************************/
1293 submit_rec : OPEN DELIM POINTER DELIM TAG_SUBM    
1294              { $<ctxt>$ = start_record(REC_SUBM, $1, $3, $5);
1295                 START(SUBM, $<ctxt>$) }
1296              subm_subs
1297              { CHECK1(NAME) }
1298              CLOSE
1299              { end_record(REC_SUBM, $<ctxt>6); }
1300            ;
1301
1302 subm_subs  : /* empty */
1303            | subm_subs subm_sub
1304            ;
1305
1306 subm_sub   : subm_name_sect  { OCCUR2(NAME, 0, 1) }
1307            | addr_struc_sub  /* 0:1 */
1308            | multim_link_sub  /* 0:M */
1309            | subm_lang_sect  { OCCUR2(LANG, 0, 3) }
1310            | subm_rfn_sect  { OCCUR2(RFN, 0, 1) }
1311            | subm_rin_sect  { OCCUR2(RIN, 0, 1) }
1312            | change_date_sub  /* 0:1 */
1313            | no_std_sub
1314            ;
1315
1316 /* SUBM.NAME */
1317 subm_name_sect : OPEN DELIM TAG_NAME mand_line_item             
1318                  { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1319                ;
1320
1321 /* SUBM.LANG */
1322 subm_lang_sect : OPEN DELIM TAG_LANG mand_line_item             
1323                  { START(LANG, NULL) } no_std_subs { CHECK0 } CLOSE { }
1324                ;
1325
1326 /* SUBM.RFN */
1327 subm_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item             
1328                  { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1329                ;
1330
1331 /* SUBM.RIN */
1332 subm_rin_sect  : OPEN DELIM TAG_RIN mand_line_item             
1333                  { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1334                ;
1335
1336 /*********************************************************************/
1337 /**** Substructures                                               ****/
1338 /*********************************************************************/
1339
1340 /* ADDRESS STRUCTURE */
1341 addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) }
1342                | phon_sect { OCCUR2(PHON, 0, 3) }
1343                ;
1344
1345 addr_sect   : OPEN DELIM TAG_ADDR mand_line_item 
1346               { START(ADDR, NULL) }
1347               addr_subs
1348               { CHECK0 }
1349               CLOSE { }
1350             ;
1351
1352 addr_subs   : /* empty */
1353             | addr_subs addr_sub
1354             ;
1355
1356 addr_sub    : addr_cont_sect  /* 0:M */
1357             | addr_adr1_sect  { OCCUR2(ADR1, 0, 1) }
1358             | addr_adr2_sect  { OCCUR2(ADR2, 0, 1) }
1359             | addr_city_sect  { OCCUR2(CITY, 0, 1) }
1360             | addr_stae_sect  { OCCUR2(STAE, 0, 1) }
1361             | addr_post_sect  { OCCUR2(POST, 0, 1) }
1362             | addr_ctry_sect  { OCCUR2(CTRY, 0, 1) }
1363             | no_std_sub
1364             ;
1365
1366 addr_cont_sect : OPEN DELIM TAG_CONT mand_line_item              
1367                  { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1368                ;
1369 addr_adr1_sect : OPEN DELIM TAG_ADR1 mand_line_item              
1370                  { START(ADR1, NULL) } no_std_subs { CHECK0 } CLOSE { }
1371                ;
1372 addr_adr2_sect : OPEN DELIM TAG_ADR2 mand_line_item              
1373                  { START(ADR2, NULL) } no_std_subs { CHECK0 } CLOSE { }
1374                ;
1375 addr_city_sect : OPEN DELIM TAG_CITY mand_line_item              
1376                  { START(CITY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1377                ;
1378 addr_stae_sect : OPEN DELIM TAG_STAE mand_line_item              
1379                  { START(STAE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1380                ;
1381 addr_post_sect : OPEN DELIM TAG_POST mand_line_item              
1382                  { START(POST, NULL) } no_std_subs { CHECK0 } CLOSE { }
1383                ;
1384 addr_ctry_sect : OPEN DELIM TAG_CTRY mand_line_item              
1385                  { START(CTRY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1386                ;
1387
1388 phon_sect   : OPEN DELIM TAG_PHON mand_line_item              
1389               { START(PHON, NULL) } no_std_subs { CHECK0 } CLOSE { }
1390             ;
1391
1392 /* ASSOCIATION STRUCTURE */
1393 assoc_struc_sub : asso_sect /* 0:M */
1394                 ;
1395
1396 asso_sect : OPEN DELIM TAG_ASSO mand_pointer
1397             { START(ASSO, NULL) }
1398             asso_subs
1399             { CHECK2(TYPE,RELA) }
1400             CLOSE { }
1401           ;
1402
1403 asso_subs : /* empty */
1404           | asso_type_sect  { OCCUR2(TYPE, 1, 1) }
1405           | asso_rela_sect  { OCCUR2(RELA, 1, 1) }
1406           | note_struc_sub
1407           | source_cit_sub
1408           | no_std_sub
1409           ;
1410
1411 asso_type_sect : OPEN DELIM TAG_TYPE mand_line_item               
1412                  { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1413                ;
1414
1415 asso_rela_sect : OPEN DELIM TAG_RELA mand_line_item               
1416                  { START(RELA, NULL) } no_std_subs { CHECK0 } CLOSE { }
1417                ;
1418
1419 /* CHANGE DATE */
1420 change_date_sub : change_date_chan_sect  { OCCUR2(CHAN, 0, 1) }
1421                 ;
1422
1423 change_date_chan_sect : OPEN DELIM TAG_CHAN
1424                         { START(CHAN, NULL) }
1425                         change_date_chan_subs
1426                         { CHECK1(DATE) }
1427                         CLOSE { }
1428                       ;
1429
1430 change_date_chan_subs : /* empty */
1431                       | change_date_chan_subs change_date_chan_sub
1432                       ;
1433
1434 change_date_chan_sub  : change_date_date_sect  { OCCUR2(DATE, 1, 1) }
1435                       | note_struc_sub
1436                       | no_std_sub
1437                       ;
1438
1439 change_date_date_sect : OPEN DELIM TAG_DATE mand_line_item 
1440                         { START(DATE, NULL) }
1441                         change_date_date_subs
1442                         { CHECK0 }
1443                         CLOSE { }
1444                       ;
1445
1446 change_date_date_subs : /* empty */
1447                       | change_date_date_subs change_date_date_sub
1448                       ;
1449
1450 change_date_date_sub : change_date_date_time_sect  { OCCUR2(TIME, 0, 1) }
1451                      | no_std_sub
1452                      ;
1453
1454 change_date_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
1455                              { START(TIME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1456                            ;
1457
1458 /* CHILD TO FAMILY LINK */
1459 chi_fam_link_sub : famc_sect  /* 0:M */
1460                  ;
1461
1462 famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1463             { START(FAMC, NULL) }
1464             famc_subs
1465             { CHECK0 }
1466             CLOSE { }
1467           ;
1468
1469 famc_subs : /* empty */
1470           | famc_subs famc_sub
1471           ;
1472
1473 famc_sub  : famc_pedi_sect  /* 0:M */
1474           | note_struc_sub
1475           | no_std_sub
1476           ;
1477
1478 famc_pedi_sect : OPEN DELIM TAG_PEDI mand_line_item 
1479                  { START(PEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1480                ;
1481
1482 /* CONTINUATION SUBSECTIONS */
1483 continuation_sub : cont_sect  /* 0:M */
1484                  | conc_sect  /* 0:M */
1485                  ;
1486
1487 cont_sect : OPEN DELIM TAG_CONT mand_line_item 
1488             { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1489           ;
1490
1491 conc_sect : OPEN DELIM TAG_CONC mand_line_item 
1492             { START(CONC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1493           ; 
1494
1495 /* EVENT DETAIL */
1496 event_detail_sub : event_detail_type_sect  { OCCUR2(TYPE, 0, 1) }
1497                  | event_detail_date_sect  { OCCUR2(DATE, 0, 1) }
1498                  | place_struc_sub
1499                  | addr_struc_sub
1500                  | event_detail_age_sect  { OCCUR2(AGE, 0, 1) }
1501                  | event_detail_agnc_sect  { OCCUR2(AGNC, 0, 1) }
1502                  | event_detail_caus_sect  { OCCUR2(CAUS, 0, 1) }
1503                  | source_cit_sub
1504                  | multim_link_sub
1505                  | note_struc_sub
1506                  ;
1507
1508 event_detail_type_sect : OPEN DELIM TAG_TYPE mand_line_item 
1509                          { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1510                        ;
1511 event_detail_date_sect : OPEN DELIM TAG_DATE mand_line_item 
1512                          { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1513                        ;
1514 event_detail_age_sect  : OPEN DELIM TAG_AGE mand_line_item 
1515                          { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1516                        ;
1517 event_detail_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item 
1518                          { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1519                        ;
1520 event_detail_caus_sect : OPEN DELIM TAG_CAUS mand_line_item 
1521                          { START(CAUS, NULL) } no_std_subs { CHECK0 } CLOSE { }
1522                        ;
1523
1524 /* FAMILY EVENT STRUCTURE */
1525 fam_event_struc_sub : fam_event_sect
1526                     | fam_gen_even_sect  /* 0:M */
1527                     ;
1528
1529 fam_event_sect : OPEN DELIM fam_event_tag opt_value fam_event_subs
1530                  { CHECK0 }
1531                  CLOSE { }
1532                ;
1533
1534 fam_event_tag : TAG_ANUL { START(ANUL, NULL) }
1535               | TAG_CENS { START(CENS, NULL) }
1536               | TAG_DIV { START(DIV, NULL) }
1537               | TAG_DIVF { START(DIVF, NULL) }
1538               | TAG_ENGA { START(ENGA, NULL) }
1539               | TAG_MARR { START(MARR, NULL) }
1540               | TAG_MARB { START(MARB, NULL) }
1541               | TAG_MARC { START(MARC, NULL) }
1542               | TAG_MARL { START(MARL, NULL) }
1543               | TAG_MARS { START(MARS, NULL) }
1544               ;
1545
1546 fam_event_subs : /* empty */
1547                | fam_event_subs fam_event_sub
1548                ;
1549
1550 fam_event_sub : event_detail_sub
1551               | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
1552               | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
1553               | no_std_sub
1554               ;
1555
1556 fam_even_husb_sect : OPEN DELIM TAG_HUSB
1557                      { START(HUSB, NULL) }
1558                      fam_even_husb_subs
1559                      { CHECK1(AGE) }
1560                      CLOSE { }
1561                    ;
1562
1563 fam_even_husb_subs : /* empty */
1564                    | fam_even_husb_subs fam_even_husb_sub
1565                    ;
1566
1567 fam_even_husb_sub : fam_even_husb_age_sect  { OCCUR2(AGE, 1, 1) }
1568                   | no_std_sub
1569                   ;
1570
1571 fam_even_husb_age_sect : OPEN DELIM TAG_AGE mand_line_item  
1572                          { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1573                        ;
1574
1575 fam_even_wife_sect : OPEN DELIM TAG_WIFE
1576                      { START(HUSB, NULL) }
1577                      fam_even_husb_subs
1578                      { CHECK1(AGE) }
1579                      CLOSE { }
1580                    ;
1581
1582 fam_gen_even_sect : OPEN DELIM TAG_EVEN
1583                     { START(EVEN, NULL) }
1584                     fam_gen_even_subs
1585                     { CHECK0 }
1586                     CLOSE { }
1587                   ;
1588
1589 fam_gen_even_subs : /* empty */
1590                   | fam_gen_even_subs fam_gen_even_sub
1591                   ;
1592
1593 fam_gen_even_sub : event_detail_sub
1594                  | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
1595                  | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
1596                  | no_std_sub
1597                  ;
1598
1599 /* IDENTIFICATION STRUCTURE */
1600 ident_struc_sub : ident_refn_sect  /* 0:M */
1601                 | ident_rin_sect  { OCCUR2(RIN, 0, 1) }
1602                 ;
1603
1604 ident_refn_sect : OPEN DELIM TAG_REFN mand_line_item 
1605                   { START(REFN, NULL) }
1606                   ident_refn_subs
1607                   { CHECK0 }
1608                   CLOSE { }
1609                 ;
1610
1611 ident_refn_subs : /* empty */
1612                 | ident_refn_subs ident_refn_sub
1613                 ;
1614
1615 ident_refn_sub  : ident_refn_type_sect  { OCCUR2(TYPE, 0, 1) }
1616                 | no_std_sub
1617                 ;
1618
1619 ident_refn_type_sect : OPEN DELIM TAG_TYPE mand_line_item   
1620                        { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1621                      ;
1622
1623 ident_rin_sect  : OPEN DELIM TAG_RIN mand_line_item   
1624                   { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1625                 ;
1626
1627 /* INDIVIDUAL ATTRIBUTE STRUCTURE */
1628 indiv_attr_struc_sub : indiv_cast_sect  /* 0:M */
1629                      | indiv_dscr_sect  /* 0:M */
1630                      | indiv_educ_sect  /* 0:M */
1631                      | indiv_idno_sect  /* 0:M */
1632                      | indiv_nati_sect  /* 0:M */
1633                      | indiv_nchi_sect  /* 0:M */
1634                      | indiv_nmr_sect  /* 0:M */
1635                      | indiv_occu_sect  /* 0:M */
1636                      | indiv_prop_sect  /* 0:M */
1637                      | indiv_reli_sect  /* 0:M */
1638                      | indiv_resi_sect  /* 0:M */
1639                      | indiv_ssn_sect  /* 0:M */
1640                      | indiv_titl_sect  /* 0:M */
1641                      ;
1642
1643 indiv_cast_sect : OPEN DELIM TAG_CAST mand_line_item 
1644                   { START(CAST, NULL) }
1645                   indiv_attr_event_subs
1646                   { CHECK0 }
1647                   CLOSE { }
1648                 ;
1649 indiv_dscr_sect : OPEN DELIM TAG_DSCR mand_line_item 
1650                   { START(DSCR, NULL) }
1651                   indiv_attr_event_subs
1652                   { CHECK0 }
1653                   CLOSE { }
1654                 ;
1655 indiv_educ_sect : OPEN DELIM TAG_EDUC mand_line_item  
1656                   { START(EDUC, NULL) }
1657                   indiv_attr_event_subs 
1658                   { CHECK0 }
1659                   CLOSE { }
1660                 ;
1661 indiv_idno_sect : OPEN DELIM TAG_IDNO mand_line_item 
1662                   { START(IDNO, NULL) }
1663                   indiv_attr_event_subs 
1664                   { CHECK0 }
1665                   CLOSE { }
1666                 ;
1667 indiv_nati_sect : OPEN DELIM TAG_NATI mand_line_item 
1668                   { START(NATI, NULL) }
1669                   indiv_attr_event_subs 
1670                   { CHECK0 }
1671                   CLOSE { }
1672                 ;
1673 indiv_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item 
1674                   { START(NCHI, NULL) }
1675                   indiv_attr_event_subs 
1676                   { CHECK0 }
1677                   CLOSE { }
1678                 ;
1679 indiv_nmr_sect  : OPEN DELIM TAG_NMR mand_line_item 
1680                   { START(NMR, NULL) }
1681                   indiv_attr_event_subs 
1682                   { CHECK0 }
1683                   CLOSE { }
1684                 ;
1685 indiv_occu_sect : OPEN DELIM TAG_OCCU mand_line_item 
1686                   { START(OCCU, NULL) }
1687                   indiv_attr_event_subs 
1688                   { CHECK0 }
1689                   CLOSE { }
1690                 ;
1691 indiv_prop_sect : OPEN DELIM TAG_PROP mand_line_item 
1692                   { START(PROP, NULL) }
1693                   indiv_attr_event_subs 
1694                   { CHECK0 }
1695                   CLOSE { }
1696                 ;
1697 indiv_reli_sect : OPEN DELIM TAG_RELI mand_line_item 
1698                   { START(RELI, NULL) }
1699                   indiv_attr_event_subs 
1700                   { CHECK0 }
1701                   CLOSE { }
1702                 ;
1703 indiv_resi_sect : OPEN DELIM TAG_RESI 
1704                   { START(RESI, NULL) }
1705                   indiv_attr_event_subs 
1706                   { CHECK0 }
1707                   CLOSE { }
1708                 ;
1709 indiv_ssn_sect  : OPEN DELIM TAG_SSN mand_line_item 
1710                   { START(SSN, NULL) }
1711                   indiv_attr_event_subs 
1712                   { CHECK0 }
1713                   CLOSE { }
1714                 ;
1715 indiv_titl_sect : OPEN DELIM TAG_TITL mand_line_item 
1716                   { START(TITL, NULL) }
1717                   indiv_attr_event_subs 
1718                   { CHECK0 }
1719                   CLOSE { }
1720                 ;
1721
1722 indiv_attr_event_subs : /* empty */
1723                       | indiv_attr_event_subs indiv_attr_event_sub
1724                       ;
1725
1726 indiv_attr_event_sub  : event_detail_sub
1727                       | no_std_sub
1728                       ;
1729
1730 /* INDIVIDUAL EVENT STRUCTURE */
1731 indiv_even_struc_sub : indiv_birt_sect
1732                      | indiv_gen_sect
1733                      | indiv_adop_sect  /* 0:M */
1734                      | indiv_even_sect  /* 0:M */
1735                      ;
1736
1737 indiv_birt_sect : OPEN DELIM indiv_birt_tag opt_value indiv_birt_subs
1738                   { CHECK0 }
1739                   CLOSE { }
1740                 ;
1741
1742 indiv_birt_tag  : TAG_BIRT { START(BIRT, NULL) }
1743                 | TAG_CHR { START(CHR, NULL) }
1744                 ;
1745
1746 indiv_birt_subs : /* empty */
1747                 | indiv_birt_subs indiv_birt_sub
1748                 ;
1749
1750 indiv_birt_sub  : event_detail_sub
1751                 | indiv_birt_famc_sect  { OCCUR2(FAMC,0, 1) }
1752                 | no_std_sub
1753                 ;
1754
1755 indiv_birt_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1756                        { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1757                      ;
1758
1759 indiv_gen_sect  : OPEN DELIM indiv_gen_tag opt_value indiv_gen_subs
1760                   { CHECK0 }
1761                   CLOSE { }
1762                 ;
1763
1764 indiv_gen_tag   : TAG_DEAT { START(DEAT, NULL) }
1765                 | TAG_BURI { START(BURI, NULL) }
1766                 | TAG_CREM { START(CREM, NULL) }
1767                 | TAG_BAPM { START(BAPM, NULL) }
1768                 | TAG_BARM { START(BARM, NULL) }
1769                 | TAG_BASM { START(BASM, NULL) }
1770                 | TAG_BLES { START(BLES, NULL) }
1771                 | TAG_CHRA { START(CHRA, NULL) }
1772                 | TAG_CONF { START(CONF, NULL) }
1773                 | TAG_FCOM { START(FCOM, NULL) }
1774                 | TAG_ORDN { START(ORDN, NULL) }
1775                 | TAG_NATU { START(NATU, NULL) }
1776                 | TAG_EMIG { START(EMIG, NULL) }
1777                 | TAG_IMMI { START(IMMI, NULL) }
1778                 | TAG_CENS { START(CENS, NULL) }
1779                 | TAG_PROB { START(PROB, NULL) }
1780                 | TAG_WILL { START(WILL, NULL) }
1781                 | TAG_GRAD { START(GRAD, NULL) }
1782                 | TAG_RETI { START(RETI, NULL) }
1783                 ;
1784
1785 indiv_gen_subs  : /* empty */
1786                 | indiv_gen_subs indiv_gen_sub
1787                 ;
1788
1789 indiv_gen_sub   : event_detail_sub
1790                 | no_std_sub
1791                 ;
1792
1793 indiv_adop_sect : OPEN DELIM TAG_ADOP opt_value 
1794                   { START(ADOP, NULL) }
1795                   indiv_adop_subs
1796                   { CHECK0 }
1797                   CLOSE { }
1798                 ;
1799
1800 indiv_adop_subs : /* empty */
1801                 | indiv_adop_subs indiv_adop_sub
1802                 ;
1803
1804 indiv_adop_sub  : event_detail_sub
1805                 | indiv_adop_famc_sect  { OCCUR2(FAMC,0, 1) }
1806                 | no_std_sub
1807                 ;
1808
1809 indiv_adop_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1810                        { START(FAMC, NULL) }
1811                        indiv_adop_famc_subs
1812                        { CHECK0 }
1813                        CLOSE { }
1814                      ;
1815
1816 indiv_adop_famc_subs : /* empty */
1817                      | indiv_adop_famc_subs indiv_adop_famc_sub
1818                      ;
1819
1820 indiv_adop_famc_sub  : indiv_adop_famc_adop_sect  { OCCUR2(ADOP,0, 1) }
1821                      | no_std_sub
1822                      ;
1823
1824 indiv_adop_famc_adop_sect : OPEN DELIM TAG_ADOP mand_line_item   
1825                             { START(ADOP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1826                           ;
1827
1828 indiv_even_sect : OPEN DELIM TAG_EVEN
1829                   { START(EVEN, NULL) }
1830                   indiv_gen_subs
1831                   { CHECK0 }
1832                   CLOSE { }
1833                 ;
1834
1835 /* LDS INDIVIDUAL ORDINANCE */
1836 lds_indiv_ord_sub : lio_bapl_sect  /* 0:M */
1837                   | lio_slgc_sect  /* 0:M */
1838                   ;
1839
1840 lio_bapl_sect : OPEN DELIM lio_bapl_tag lio_bapl_subs
1841                 { CHECK0 }
1842                 CLOSE { }
1843               ;
1844
1845 lio_bapl_tag  : TAG_BAPL { START(BAPL, NULL) }
1846               | TAG_CONL { START(CONL, NULL) }
1847               | TAG_ENDL { START(ENDL, NULL) }
1848               ;
1849
1850 lio_bapl_subs : /* empty */
1851               | lio_bapl_subs lio_bapl_sub
1852               ;
1853
1854 lio_bapl_sub  : lio_bapl_stat_sect  { OCCUR2(STAT, 0, 1) }
1855               | lio_bapl_date_sect  { OCCUR2(DATE, 0, 1) }
1856               | lio_bapl_temp_sect  { OCCUR2(TEMP, 0, 1) }
1857               | lio_bapl_plac_sect  { OCCUR2(PLAC, 0, 1) }
1858               | source_cit_sub
1859               | note_struc_sub
1860               | no_std_sub
1861               ;
1862
1863 lio_bapl_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
1864                      { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1865                    ;
1866 lio_bapl_date_sect : OPEN DELIM TAG_DATE mand_line_item   
1867                      { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1868                    ;
1869 lio_bapl_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
1870                      { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1871                    ;
1872 lio_bapl_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
1873                      { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1874                    ;
1875
1876 lio_slgc_sect : OPEN DELIM TAG_SLGC
1877                 { START(SLGC, NULL) }
1878                 lio_slgc_subs
1879                 { CHECK1(FAMC) }
1880                 CLOSE { }
1881               ;
1882
1883 lio_slgc_subs : /* empty */
1884               | lio_slgc_subs lio_slgc_sub
1885               ;
1886
1887 lio_slgc_sub  : lio_bapl_sub
1888               | lio_slgc_famc_sect  { OCCUR2(FAMC, 1, 1) }
1889               ;
1890
1891 lio_slgc_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1892                      { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1893                    ;
1894
1895 /* LDS SPOUSE SEALING */
1896 lds_spouse_seal_sub : lss_slgs_sect
1897                     ;
1898
1899 lss_slgs_sect : OPEN DELIM TAG_SLGS
1900                 { START(SLGS, NULL) }
1901                 lss_slgs_subs
1902                 { CHECK0 }
1903                 CLOSE { }
1904               ;
1905
1906 lss_slgs_subs : /* empty */
1907               | lss_slgs_subs lss_slgs_sub
1908               ;
1909
1910 lss_slgs_sub  : lss_slgs_stat_sect  { OCCUR2(STAT, 0, 1) }
1911               | lss_slgs_date_sect  { OCCUR2(DATE, 0, 1) }
1912               | lss_slgs_temp_sect  { OCCUR2(TEMP, 0, 1) }
1913               | lss_slgs_plac_sect  { OCCUR2(PLAC, 0, 1) }
1914               | source_cit_sub
1915               | note_struc_sub
1916               | no_std_sub
1917               ;
1918
1919 lss_slgs_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
1920                      { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1921                    ;
1922 lss_slgs_date_sect : OPEN DELIM TAG_DATE mand_line_item   
1923                      { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1924                    ;
1925 lss_slgs_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
1926                      { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1927                    ;
1928 lss_slgs_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
1929                      { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1930                    ;
1931
1932 /* MULTIMEDIA LINK */
1933 multim_link_sub : multim_obje_link_sect
1934                 | multim_obje_emb_sect
1935                 ;
1936
1937 multim_obje_link_sect : OPEN DELIM TAG_OBJE DELIM POINTER    
1938                         { START(OBJE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1939                       ;
1940
1941 multim_obje_emb_sect : OPEN DELIM TAG_OBJE
1942                        { START(OBJE, NULL) }
1943                        multim_obje_emb_subs
1944                        { CHECK2(FORM,FILE) }
1945                        CLOSE { }
1946                      ;
1947
1948 multim_obje_emb_subs : /* empty */
1949                      | multim_obje_emb_subs multim_obje_emb_sub
1950                      ;
1951
1952 multim_obje_emb_sub : multim_obje_form_sect  { OCCUR2(FORM, 1, 1) }
1953                     | multim_obje_titl_sect  { OCCUR2(TITL, 0, 1) }
1954                     | multim_obje_file_sect  { OCCUR2(FILE, 1, 1) }
1955                     | note_struc_sub
1956                     | no_std_sub
1957                     ;
1958
1959 multim_obje_form_sect : OPEN DELIM TAG_FORM mand_line_item    
1960                         { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1961                       ;
1962 multim_obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item    
1963                         { START(TITL, NULL) } no_std_subs { CHECK0 } CLOSE { }
1964                       ;
1965 multim_obje_file_sect : OPEN DELIM TAG_FILE mand_line_item    
1966                         { START(FILE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1967                       ;
1968
1969 /* NOTE STRUCTURE */
1970 note_struc_sub : note_struc_link_sect  /* 0:M */
1971                | note_struc_emb_sect  /* 0:M */
1972                ;
1973
1974 note_struc_link_sect : OPEN DELIM TAG_NOTE DELIM POINTER
1975                        { START(NOTE, NULL) }
1976                        note_struc_link_subs
1977                        { CHECK0 }
1978                        CLOSE { }
1979                      ;
1980
1981 note_struc_link_subs : /* empty */
1982                      | note_struc_link_subs note_struc_link_sub
1983                      ;
1984
1985 note_struc_link_sub : source_cit_sub
1986                     | no_std_sub
1987                     ;
1988
1989 note_struc_emb_sect : OPEN DELIM TAG_NOTE opt_line_item
1990                       { START(NOTE, NULL) }
1991                       note_struc_emb_subs
1992                       { CHECK0 }
1993                       CLOSE { }
1994                     ;
1995
1996 note_struc_emb_subs : /* empty */
1997                     | note_struc_emb_subs note_struc_emb_sub
1998                     ;
1999
2000 note_struc_emb_sub  : continuation_sub
2001                     | source_cit_sub
2002                     | no_std_sub
2003                     ;
2004
2005 /* PERSONAL NAME STRUCTURE */
2006 pers_name_struc_sub : pers_name_sect /* 0:M */
2007                     ;
2008
2009 pers_name_sect : OPEN DELIM TAG_NAME mand_line_item 
2010                  { START(NAME, NULL) }
2011                  pers_name_subs
2012                  { CHECK0 }
2013                  CLOSE { }
2014                ;
2015
2016 pers_name_subs : /* empty */
2017                | pers_name_subs pers_name_sub
2018                ;
2019
2020 pers_name_sub  : pers_name_npfx_sect  { OCCUR2(NPFX, 0, 1) }
2021                | pers_name_givn_sect  { OCCUR2(GIVN, 0, 1) }
2022                | pers_name_nick_sect  { OCCUR2(NICK, 0, 1) }
2023                | pers_name_spfx_sect  { OCCUR2(SPFX, 0, 1) }
2024                | pers_name_surn_sect  { OCCUR2(SURN, 0, 1) }
2025                | pers_name_nsfx_sect  { OCCUR2(NSFX, 0, 1) }
2026                | source_cit_sub
2027                | note_struc_sub
2028                | no_std_sub
2029                ;
2030
2031 pers_name_npfx_sect : OPEN DELIM TAG_NPFX mand_line_item    
2032                       { START(NPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2033                     ;
2034 pers_name_givn_sect : OPEN DELIM TAG_GIVN mand_line_item    
2035                       { START(GIVN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2036                     ;
2037 pers_name_nick_sect : OPEN DELIM TAG_NICK mand_line_item    
2038                       { START(NICK, NULL) } no_std_subs { CHECK0 } CLOSE { }
2039                     ;
2040 pers_name_spfx_sect : OPEN DELIM TAG_SPFX mand_line_item    
2041                       { START(SPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2042                     ;
2043 pers_name_surn_sect : OPEN DELIM TAG_SURN mand_line_item    
2044                       { START(SURN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2045                     ;
2046 pers_name_nsfx_sect : OPEN DELIM TAG_NSFX mand_line_item    
2047                       { START(NSFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2048                     ;
2049
2050 /* PLACE STRUCTURE */
2051 place_struc_sub : place_struc_plac_sect /* 0:M */
2052                 ;
2053
2054 place_struc_plac_sect : OPEN DELIM TAG_PLAC mand_line_item 
2055                         { START(PLAC, NULL) }
2056                         place_struc_plac_subs
2057                         { CHECK0 }
2058                         CLOSE { }
2059                       ;
2060
2061 place_struc_plac_subs : /* empty */
2062                       | place_struc_plac_subs place_struc_plac_sub
2063                       ;
2064
2065 place_struc_plac_sub : place_plac_form_sect  { OCCUR2(FORM, 0, 1) }
2066                      | source_cit_sub
2067                      | note_struc_sub
2068                      | no_std_sub
2069                      ;
2070
2071 place_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item    
2072                        { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
2073                      ;
2074
2075 /* SOURCE_CITATION */
2076 source_cit_sub : source_cit_link_sect /* 0:M */
2077                | source_cit_emb_sect /* 0:M */
2078                ;
2079
2080 source_cit_link_sect : OPEN DELIM TAG_SOUR DELIM POINTER
2081                        { START(SOUR, NULL) }
2082                        source_cit_link_subs
2083                        { CHECK0 }
2084                        CLOSE { }
2085                      ;
2086
2087 source_cit_link_subs : /* empty */
2088                      | source_cit_link_subs source_cit_link_sub
2089                      ;
2090
2091 source_cit_link_sub : source_cit_page_sect  { OCCUR2(PAGE, 0, 1) }
2092                     | source_cit_even_sect  { OCCUR2(EVEN, 0, 1) }
2093                     | source_cit_data_sect  { OCCUR2(DATA, 0, 1) }
2094                     | source_cit_quay_sect  { OCCUR2(QUAY, 0, 1) }
2095                     | multim_link_sub
2096                     | note_struc_sub
2097                     | no_std_sub
2098                     ;
2099
2100 source_cit_page_sect : OPEN DELIM TAG_PAGE mand_line_item    
2101                        { START(PAGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2102                      ;
2103
2104 source_cit_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
2105                        { START(EVEN, NULL) }
2106                        source_cit_even_subs
2107                        { CHECK0 }
2108                        CLOSE { }
2109                      ;
2110
2111 source_cit_even_subs : /* empty */
2112                      | source_cit_even_subs source_cit_even_sub
2113                      ;
2114
2115 source_cit_even_sub  : source_cit_even_role_sect  { OCCUR2(ROLE, 0, 1) }
2116                      | no_std_sub
2117                      ;
2118
2119 source_cit_even_role_sect : OPEN DELIM TAG_ROLE mand_line_item    
2120                           { START(ROLE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2121                           ;
2122
2123 source_cit_data_sect : OPEN DELIM TAG_DATA
2124                        { START(DATA, NULL) }
2125                        source_cit_data_subs
2126                        { CHECK0 }
2127                        CLOSE { }
2128                      ;
2129
2130 source_cit_data_subs : /* empty */
2131                      | source_cit_data_subs source_cit_data_sub
2132                      ;
2133
2134 source_cit_data_sub : source_cit_data_date_sect  { OCCUR2(DATE, 0, 1) }
2135                     | source_cit_text_sect  /* 0:M */
2136                     | no_std_sub
2137                     ;
2138
2139 source_cit_data_date_sect : OPEN DELIM TAG_DATE mand_line_item    
2140                             { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2141                           ;
2142
2143 source_cit_text_sect : OPEN DELIM TAG_TEXT mand_line_item 
2144                        { START(TEXT, NULL) }
2145                        source_cit_text_subs
2146                        { CHECK0 }
2147                        CLOSE { }
2148                      ;
2149
2150 source_cit_text_subs : /* empty */
2151                      | source_cit_text_subs source_cit_text_sub
2152                      ;
2153
2154 source_cit_text_sub : continuation_sub
2155                     | no_std_sub
2156                     ;
2157
2158 source_cit_quay_sect : OPEN DELIM TAG_QUAY mand_line_item    
2159                        { START(QUAY, NULL) } no_std_subs { CHECK0 } CLOSE { }
2160                      ;
2161
2162 source_cit_emb_sect : OPEN DELIM TAG_SOUR mand_line_item
2163                       { START(SOUR, NULL) }
2164                       source_cit_emb_subs
2165                       { CHECK0 }
2166                       CLOSE { }
2167                     ;
2168
2169 source_cit_emb_subs : /* empty */
2170                     | source_cit_emb_subs source_cit_emb_sub
2171                     ;
2172
2173 source_cit_emb_sub : continuation_sub
2174                    | source_cit_text_sect  /* 0:M */
2175                    | note_struc_sub
2176                    | no_std_sub
2177                    ;
2178
2179 /* SOURCE REPOSITORY CITATION */
2180 source_repos_cit_sub : source_repos_repo_sect  { OCCUR2(REPO, 0, 1) }
2181                      ;
2182
2183 source_repos_repo_sect : OPEN DELIM TAG_REPO mand_pointer
2184                          { START(REPO, NULL) }
2185                          source_repos_repo_subs
2186                          { CHECK0 }
2187                          CLOSE { }
2188                        ;
2189
2190 source_repos_repo_subs : /* empty */
2191                        | source_repos_repo_subs source_repos_repo_sub
2192                        ;
2193
2194 source_repos_repo_sub  : note_struc_sub
2195                        | caln_sect  /* 0:M */
2196                        | no_std_sub
2197                        ;
2198
2199 caln_sect : OPEN DELIM TAG_CALN mand_line_item 
2200             { START(CALN, NULL) }
2201             caln_subs
2202             { CHECK0 }
2203             CLOSE { }
2204           ;
2205
2206 caln_subs : /* empty */
2207           | caln_subs caln_sub
2208           ;
2209
2210 caln_sub  : caln_medi_sect  { OCCUR2(MEDI, 0, 1) }
2211           | no_std_sub
2212           ;
2213
2214 caln_medi_sect : OPEN DELIM TAG_MEDI mand_line_item    
2215                  { START(MEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
2216                ;
2217  
2218 /* SPOUSE TO FAMILY LINK */
2219 spou_fam_link_sub : spou_fam_fams_sect  /* 0:M */
2220                   ;
2221
2222 spou_fam_fams_sect : OPEN DELIM TAG_FAMS mand_pointer
2223                      { START(FAMS, NULL) }
2224                      spou_fam_fams_subs
2225                      { CHECK0 }
2226                      CLOSE { }
2227                    ;
2228
2229 spou_fam_fams_subs : /* empty */
2230                    | spou_fam_fams_subs spou_fam_fams_sub
2231                    ;
2232
2233 spou_fam_fams_sub  : note_struc_sub
2234                    | no_std_sub
2235                    ;
2236
2237 /*********************************************************************/
2238 /**** General                                                     ****/
2239 /*********************************************************************/
2240
2241 no_std_subs : /* empty */
2242             | no_std_subs no_std_sub
2243             ;
2244
2245 no_std_sub  : user_sect /* 0:M */
2246             | gen_sect
2247             | error error_subs CLOSE  { HANDLE_ERROR }
2248             ;
2249
2250 no_std_rec  : user_rec /* 0:M */
2251             | gen_rec
2252             | error error_subs CLOSE  { HANDLE_ERROR }
2253             ;
2254
2255 user_rec    : OPEN DELIM opt_xref USERTAG 
2256               { if ($4[0] != '_') {
2257                   gedcom_error("Undefined tag (and not a valid user tag): %s",
2258                                $4);
2259                   YYERROR;
2260                 }
2261               }
2262               opt_value
2263               { $<ctxt>$ = start_record(REC_USER, $1, $3, $4);
2264                 START($4, $<ctxt>$)
2265               }
2266               user_sects
2267               { CHECK0 }
2268               CLOSE
2269               { end_record(REC_USER, $<ctxt>7); }
2270             ;
2271 user_sect   : OPEN DELIM opt_xref USERTAG 
2272               { if ($4[0] != '_') {
2273                   gedcom_error("Undefined tag (and not a valid user tag): %s",
2274                                $4);
2275                   YYERROR;
2276                 }
2277               }
2278               opt_value
2279               { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6, $6);
2280                 START($4, $<ctxt>$);
2281               }
2282               user_sects
2283               { CHECK0 }
2284               CLOSE
2285               { end_element(ELT_USER, PARENT, $<ctxt>7, NULL);
2286               }
2287             ;
2288
2289 user_sects   : /* empty */     { }
2290             | user_sects user_sect { }
2291             ;
2292
2293 opt_xref    : /* empty */        { $$ = NULL; }
2294             | POINTER DELIM        { $$ = $1; }
2295             ;
2296
2297 opt_value   : /* empty */        { $$ = NULL; }
2298             | DELIM line_value        { $$ = $2; }
2299             ;
2300
2301 line_value  : POINTER        { $$ = $1; }
2302             | line_item        { $$ = $1; }
2303             ;
2304
2305 mand_pointer : /* empty */ { gedcom_error("Missing pointer"); YYERROR; }
2306              | DELIM POINTER { gedcom_debug_print("==Ptr: %s==\n", $2);
2307                                $$ = $2; }
2308              ;
2309
2310 mand_line_item : /* empty */ { gedcom_error("Missing value"); YYERROR; }
2311                | DELIM line_item { gedcom_debug_print("==Val: %s==\n", $2);
2312                                    $$ = $2; }
2313                ;
2314
2315 opt_line_item : /* empty */ { }
2316               | DELIM line_item { }
2317               ;
2318
2319 line_item   : anychar  { size_t i;
2320                          CLEAR_BUFFER(line_item_buf);
2321                          line_item_buf_ptr = line_item_buf;
2322                          /* The following also takes care of '@@' */
2323                          if (!strncmp($1, "@@", 3))
2324                            *line_item_buf_ptr++ = '@';
2325                          else
2326                            for (i=0; i < strlen($1); i++)
2327                              *line_item_buf_ptr++ = $1[i];
2328                          $$ = line_item_buf;
2329                        }
2330             | ESCAPE   { CLEAR_BUFFER(line_item_buf);
2331                          line_item_buf_ptr = line_item_buf;
2332                          /* For now, ignore escapes */
2333                          $$ = line_item_buf;
2334                        }
2335             | line_item anychar
2336                   { size_t i;
2337                     /* The following also takes care of '@@' */
2338                     if (!strncmp($2, "@@", 3))
2339                       *line_item_buf_ptr++ = '@';
2340                     else
2341                       for (i=0; i < strlen($2); i++)
2342                         *line_item_buf_ptr++ = $2[i];
2343                     $$ = line_item_buf;
2344                   }
2345             | line_item ESCAPE
2346                   { /* For now, ignore escapes */
2347                     $$ = line_item_buf;
2348                   }
2349             ;
2350
2351 anychar     : ANYCHAR        { }
2352             | DELIM        { }
2353             ;
2354
2355 error_subs  : /* empty */
2356             | error_subs error_sect
2357             ;
2358
2359 error_sect  : OPEN DELIM opt_xref anytag opt_value error_subs CLOSE { }
2360
2361 gen_sect    : OPEN DELIM opt_xref anystdtag
2362               { INVALID_TAG($4); }
2363               opt_value opt_sects CLOSE
2364               { }
2365             ;
2366
2367 gen_rec : gen_rec_top
2368         | gen_rec_norm
2369         ;
2370
2371 gen_rec_norm : OPEN DELIM opt_xref anystdtag
2372                { INVALID_TOP_TAG($4) }
2373                opt_value opt_sects CLOSE
2374                { }
2375              ;
2376
2377 gen_rec_top : OPEN DELIM anytoptag
2378               { gedcom_error("Missing cross-reference"); YYERROR; }
2379               opt_value opt_sects CLOSE
2380                 { }
2381             ;
2382
2383 opt_sects   : /* empty */     { }
2384             | opt_sects gen_sect { }
2385             ;
2386
2387 anytag      : USERTAG { }
2388             | anystdtag { }
2389             ;
2390
2391 anytoptag   : TAG_FAM
2392             | TAG_INDI
2393             | TAG_OBJE
2394             | TAG_NOTE
2395             | TAG_REPO
2396             | TAG_SOUR
2397             | TAG_SUBN
2398             | TAG_SUBM
2399             ;
2400
2401 anystdtag   : TAG_ABBR
2402             | TAG_ADDR
2403             | TAG_ADR1
2404             | TAG_ADR2   { }
2405             | TAG_ADOP   { }
2406             | TAG_AFN   { }
2407             | TAG_AGE   { }
2408             | TAG_AGNC   { }
2409             | TAG_ALIA   { }
2410             | TAG_ANCE   { }
2411             | TAG_ANCI   { }
2412             | TAG_ANUL   { }
2413             | TAG_ASSO   { }
2414             | TAG_AUTH   { }
2415             | TAG_BAPL   { }
2416             | TAG_BAPM   { }
2417             | TAG_BARM   { }
2418             | TAG_BASM   { }
2419             | TAG_BIRT   { }
2420             | TAG_BLES   { }
2421             | TAG_BLOB   { }
2422             | TAG_BURI   { }
2423             | TAG_CALN   { }
2424             | TAG_CAST   { }
2425             | TAG_CAUS   { }
2426             | TAG_CENS   { }
2427             | TAG_CHAN   { }
2428             | TAG_CHAR   { }
2429             | TAG_CHIL   { }
2430             | TAG_CHR   { }
2431             | TAG_CHRA   { }
2432             | TAG_CITY   { }
2433             | TAG_CONC   { }
2434             | TAG_CONF   { }
2435             | TAG_CONL   { }
2436             | TAG_CONT   { }
2437             | TAG_COPR   { }
2438             | TAG_CORP   { }
2439             | TAG_CREM   { }
2440             | TAG_CTRY   { }
2441             | TAG_DATA   { }
2442             | TAG_DATE   { }
2443             | TAG_DEAT   { }
2444             | TAG_DESC   { }
2445             | TAG_DESI   { }
2446             | TAG_DEST   { }
2447             | TAG_DIV   { }
2448             | TAG_DIVF   { }
2449             | TAG_DSCR   { }
2450             | TAG_EDUC   { }
2451             | TAG_EMIG   { }
2452             | TAG_ENDL   { }
2453             | TAG_ENGA   { }
2454             | TAG_EVEN   { }
2455             | TAG_FAM    { }
2456             | TAG_FAMC   { }
2457             | TAG_FAMS   { }
2458             | TAG_FCOM   { }
2459             | TAG_FILE   { }
2460             | TAG_FORM   { }
2461             | TAG_GEDC   { }
2462             | TAG_GIVN   { }
2463             | TAG_GRAD   { }
2464             | TAG_HEAD   { }
2465             | TAG_HUSB   { }
2466             | TAG_IDNO   { }
2467             | TAG_IMMI   { }
2468             | TAG_INDI   { }
2469             | TAG_LANG   { }
2470             | TAG_LEGA   { }
2471             | TAG_MARB   { }
2472             | TAG_MARC   { }
2473             | TAG_MARL   { }
2474             | TAG_MARR   { }
2475             | TAG_MARS   { }
2476             | TAG_MEDI   { }
2477             | TAG_NAME   { }
2478             | TAG_NATI   { }
2479             | TAG_NCHI   { }
2480             | TAG_NICK   { }
2481             | TAG_NMR   { }
2482             | TAG_NOTE   { }
2483             | TAG_NPFX   { }
2484             | TAG_NSFX   { }
2485             | TAG_OBJE   { }
2486             | TAG_OCCU   { }
2487             | TAG_ORDI   { }
2488             | TAG_ORDN   { }
2489             | TAG_PAGE   { }
2490             | TAG_PEDI   { }
2491             | TAG_PHON   { }
2492             | TAG_PLAC   { }
2493             | TAG_POST   { }
2494             | TAG_PROB   { }
2495             | TAG_PROP   { }
2496             | TAG_PUBL   { }
2497             | TAG_QUAY   { }
2498             | TAG_REFN   { }
2499             | TAG_RELA   { }
2500             | TAG_RELI   { }
2501             | TAG_REPO   { }
2502             | TAG_RESI   { }
2503             | TAG_RESN   { }
2504             | TAG_RETI   { }
2505             | TAG_RFN   { }
2506             | TAG_RIN   { }
2507             | TAG_ROLE   { }
2508             | TAG_SEX   { }
2509             | TAG_SLGC   { }
2510             | TAG_SLGS   { }
2511             | TAG_SOUR   { }
2512             | TAG_SPFX   { }
2513             | TAG_SSN   { }
2514             | TAG_STAE   { }
2515             | TAG_STAT   { }
2516             | TAG_SUBM   { }
2517             | TAG_SUBN   { }
2518             | TAG_SURN   { }
2519             | TAG_TEMP   { }
2520             | TAG_TEXT   { }
2521             | TAG_TIME   { }
2522             | TAG_TITL   { }
2523             | TAG_TRLR   { }
2524             | TAG_TYPE   { }
2525             | TAG_VERS   { }
2526             | TAG_WIFE   { }
2527             | TAG_WILL   { }
2528
2529 %%
2530
2531 /* Functions that handle the counting of subtags */
2532
2533 int* count_arrays[MAXGEDCLEVEL+1];
2534 char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLEN+1];
2535 Gedcom_ctxt ctxt_stack[MAXGEDCLEVEL+1];
2536
2537 void push_countarray()
2538 {
2539   int *count = NULL;
2540   if (count_level > MAXGEDCLEVEL) {
2541     gedcom_error("Internal error: count array overflow");
2542     exit(1);
2543   }
2544   else {
2545     count = (int *)calloc(YYNTOKENS, sizeof(int));
2546     if (count == NULL) {
2547       gedcom_error("Internal error: count array calloc error");
2548       exit(1);
2549     }
2550     else {
2551       count_arrays[count_level] = count;
2552     }
2553   }
2554 }
2555
2556 void set_parenttag(char* tag)
2557 {
2558   strncpy(tag_stack[count_level], tag, MAXSTDTAGLEN+1);
2559 }
2560
2561 void set_parentctxt(Gedcom_ctxt ctxt)
2562 {
2563   ctxt_stack[count_level] = ctxt;
2564 }
2565
2566 char* get_parenttag()
2567 {
2568   return tag_stack[count_level];
2569 }
2570
2571 Gedcom_ctxt get_parentctxt()
2572 {
2573   return ctxt_stack[count_level];
2574 }
2575
2576 int count_tag(int tag)
2577 {
2578   int *count = count_arrays[count_level];
2579   return ++count[tag - GEDCOMTAGOFFSET];
2580 }
2581
2582 int check_occurrence(int tag)
2583 {
2584   int *count = count_arrays[count_level];
2585   return (count[tag - GEDCOMTAGOFFSET] > 0);
2586 }
2587
2588 void pop_countarray()
2589 {
2590   int *count;
2591   if (count_level < 0) {
2592     gedcom_error("Internal error: count array underflow");
2593     exit(1);
2594   }
2595   else {
2596     count = count_arrays[count_level];
2597     free(count);
2598     count_arrays[count_level] = NULL;
2599   }
2600 }
2601
2602 /* Enabling debug mode */
2603 /* level 0: no debugging */
2604 /* level 1: only internal */
2605 /* level 2: also bison */
2606 FILE* trace_output;
2607
2608 void gedcom_set_debug_level(int level, FILE* f)
2609 {
2610   if (f != NULL)
2611     trace_output = f;
2612   else
2613     trace_output = stderr;
2614   if (level > 0) {
2615     gedcom_high_level_debug = 1;
2616   }
2617   if (level > 1) {
2618 #if YYDEBUG != 0
2619     gedcom_debug = 1;
2620 #endif
2621   }
2622 }
2623
2624 int gedcom_debug_print(char* s, ...)
2625 {
2626   int res = 0;
2627   if (gedcom_high_level_debug) {
2628     va_list ap;
2629     va_start(ap, s);
2630     res = vfprintf(trace_output, s, ap);
2631     va_end(ap);
2632   }
2633   return(res);
2634 }
2635
2636 /* Setting the error mechanism */
2637 void gedcom_set_error_handling(Gedcom_err_mech mechanism)
2638 {
2639   error_mechanism = mechanism;
2640 }
2641
2642 /* Compatibility handling */
2643
2644 void gedcom_set_compat_handling(int enable_compat)
2645 {
2646   compat_enabled = enable_compat;
2647 }
2648
2649 void set_compatibility(char* program)
2650 {
2651   if (compat_enabled) {
2652     gedcom_debug_print("==== Program: %s\n", program);
2653     if (! strncmp(program, "ftree", 6)) {
2654       gedcom_warning("Enabling compatibility with 'ftree'");
2655       compatibility = C_FTREE;
2656     }
2657     else {
2658       compatibility = 0;
2659     }
2660   }
2661 }
2662
2663 int compat_mode(int compat_flags)
2664 {
2665   return (compat_flags & compatibility);
2666 }
2667