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