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