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