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