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