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