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