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