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