Updated.
[gedcom-parse.git] / gedcom / gedcom.y
1 /* Parser for Gedcom.
2    Copyright (C) 2001 The Genes Development Team
3    This file is part of the Gedcom parser library.
4    Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
5
6    The Gedcom parser library is free software; you can redistribute it
7    and/or modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The Gedcom parser library is distributed in the hope that it will be
12    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the Gedcom parser library; if not, write to the
18    Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* $Id$ */
22 /* $Name$ */
23
24 /* WARNING: THIS PARSER RELIES HEAVILY ON SOME FEATURES OF BISON.
25    DON'T TRY TO USE IT WITH YACC, IT WON'T WORK...
26 */
27
28 /* Design of the parser:
29    ---------------------
30    In general, a GEDCOM file contains records, each consisting of a line
31    (which we'll call a section), hierarchically containing other lines
32    (subsections of the section).
33
34    This means that in general we have:
35
36      A 'record' is a 'section' (sect) containing 'subsections' (subs)
37      Each 'subsection' (sub) is again a specific 'section' (sect)
38
39    In parser notation, this means:
40
41      record : sect
42
43      sect   : <some prefix> subs <some suffix>
44
45      subs   : <empty> | subs sub
46
47      sub    : sect_a | sect_b | ...
48
49    This pattern is repeated throughout the parser for the different types of
50    sections.
51    
52
53    Cardinality of the subsections:
54    -------------------------------
55    Note that in the above, the order of the subsections is of no importance.
56    Indeed, this is the case in the GEDCOM grammar.  However, this also makes
57    it difficult to check whether there are not too many subsections of a
58    specific type, or whether a mandatory subsection is indeed there.
59
60    Suppose there is a section A that can contain 0 or 1 B section and
61    2 C sections.
62
63    This can be expressed in parser notation as follows:
64
65      A    : CC | BCC | CBC | CCB
66
67    So, cardinality is indeed expressable.  However, as the number of subsection
68    types and the limits grow bigger (and even theoretically limitless), listing
69    all possible permutations becomes quickly unfeasible.
70
71    Much simpler is to say:
72
73      A    : subs
74      subs : <empty> | subs sub
75      sub  : B | C
76
77    and then check the cardinality in the semantic actions, which is the
78    solution chosen in the parser below, using the following macros:
79
80     - OPEN(<parent>)
81          Make a new context for the <parent> tag to count child tags in
82          
83     - OCCUR2(<child>, <min>, <max>)
84          Express that the <child> tag should occur at least <min> times and
85          at most <max> tags within its parent
86
87          What this actually does is the following.  It increments the counter
88          for that tag and then checks whether the maximum is exceeded.  If so,
89          then a parser error is produced.  The minimum is not actually checked
90          by this macro, but it makes the statements more declarative.
91
92     - OCCUR1(<child>, <min>)
93          Express that the <child> tag should occur at least <min> times within
94          its parent (no upper limit)
95
96          Actually, this only increments the counter for the tag, but it looks
97          very like the previous macro.
98
99          If the minimum is 0, it is not necessary to express this constraint.
100
101     - CHECKn(<child1>, ..., <childn>)
102          This closes the context for the parent tag and checks whether the
103          given <child> tags did effectively occur within the parent (i.e.
104          these are the tags that were mandatory).
105
106          Since the <min> values above are always 0 or 1 in GEDCOM, this is
107          sufficient.  All sub-tags that declare a minimum of 1 in the OCCUR
108          macros should be listed in this macro here.
109
110          The macros CHECK0 to CHECK4 are defined like this (the first one
111          has no arguments and is only used to close the parent context; note
112          that this is necessary for correct functioning).
113
114    Example of usage:
115
116      Only sections that have subsections need to use these macros.  This can
117      be done like this (the OPEN and CHECK macros are used as mid-rule
118      actions around the subsections):
119
120        head_sect : OPEN DELIM TAG_HEAD
121                    { OPEN(HEAD) }
122                    head_subs
123                    { CHECK1(SOUR) }
124                    CLOSE { <semantic actions> }
125                   
126        head_subs : <empty>
127                  | head_subs head_sub
128                  ;
129
130        head_sub  : head_sour_sect  { OCCUR2(SOUR, 1, 1) }
131                  | head_dest_sect  { OCCUR2(DEST, 0, 1) }
132                  | head_date_sect  { OCCUR2(DATE, 0, 1) }
133                  ;
134 */
135
136 /* General notes:
137
138    - The syntax analysis doesn't handle the contents of the line values;
139      this is done in the semantic analysis.
140
141  */
142
143 %{
144 #include "gedcom_internal.h"
145 #include "multilex.h"
146 #include "encoding.h"
147 #include "interface.h"
148 #include "date.h"
149
150 int  count_level    = 0;
151 int  fail           = 0;
152 int  compat_enabled = 1;
153 int  gedcom_high_level_debug = 0; 
154 int  compatibility  = 0; 
155 Gedcom_err_mech error_mechanism = IMMED_FAIL;
156 Gedcom_val_struct val; 
157  
158 char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
159 char *line_item_buf_ptr;
160
161 enum _COMPAT {
162   C_FTREE = 0x01
163 };
164
165 /* These are defined at the bottom of the file */ 
166 void push_countarray();
167 void set_parenttag(char* tag);
168 char* get_parenttag(); 
169 void set_parentctxt(Gedcom_ctxt ctxt);
170 Gedcom_ctxt get_parentctxt();
171 void pop_countarray();
172 int  count_tag(int tag);
173 int  check_occurrence(int tag);
174 void set_compatibility(char* program);
175 int  compat_mode(int flags); 
176
177 #define CLEAR_BUFFER(BUF)                                                     \
178      memset(BUF, 0, sizeof(BUF));
179  
180 #define HANDLE_ERROR                                                          \
181      { if (error_mechanism == IMMED_FAIL) {                                   \
182          YYABORT;                                                             \
183        }                                                                      \
184        else if (error_mechanism == DEFER_FAIL) {                              \
185          yyerrok; fail = 1;                                                   \
186        }                                                                      \
187        else if (error_mechanism == IGNORE_ERRORS) {                           \
188          yyerrok;                                                             \
189        }                                                                      \
190      }
191 #define START(PARENTTAG,PARENTCTXT)                                           \
192      { ++count_level;                                                         \
193        set_parenttag(#PARENTTAG);                                             \
194        set_parentctxt(PARENTCTXT);                                            \
195        push_countarray();                                                     \
196      }
197 #define PARENT                                                              \
198      get_parentctxt()
199 #define CHK(TAG)                                                              \
200      { if (!check_occurrence(TAG_##TAG)) {                                    \
201          char* parenttag = get_parenttag();                                   \
202          gedcom_error(_("The tag '%s' is mandatory within '%s', but missing"),\
203                       #TAG, parenttag);                                       \
204          HANDLE_ERROR;                                                        \
205        }                                                                      \
206      }
207 #define POP                                                                   \
208      { pop_countarray();                                                      \
209        --count_level;                                                         \
210      }
211 #define CHECK0 POP; 
212 #define CHECK1(TAG1) { CHK(TAG1); POP; }
213 #define CHECK2(TAG1,TAG2)                                                     \
214      { CHK(TAG1); CHK(TAG2); POP; }
215 #define CHECK3(TAG1,TAG2,TAG3)                                                \
216      { CHK(TAG1); CHK(TAG2); CHK(TAG3); POP; }
217 #define CHECK4(TAG1,TAG2,TAG3,TAG4)                                           \
218      { CHK(TAG1); CHK(TAG2); CHK(TAG3); CHK(TAG4); POP; } 
219 #define OCCUR1(CHILDTAG, MIN) { count_tag(TAG_##CHILDTAG); } 
220 #define OCCUR2(CHILDTAG, MIN, MAX)                                            \
221      { int num = count_tag(TAG_##CHILDTAG);                                   \
222        if (num > MAX) {                                                       \
223          char* parenttag = get_parenttag();                                   \
224          gedcom_error(_("The tag '%s' can maximally occur %d time(s) within '%s'"),                                                                          \
225                       #CHILDTAG, MAX, parenttag);                             \
226          HANDLE_ERROR;                                                        \
227        }                                                                      \
228      }
229 #define INVALID_TAG(CHILDTAG)                                                 \
230      { char* parenttag = get_parenttag();                                     \
231        gedcom_error(_("The tag '%s' is not a valid tag within '%s'"),         \
232                     CHILDTAG, parenttag);                                     \
233        HANDLE_ERROR;                                                          \
234      }
235 #define INVALID_TOP_TAG(CHILDTAG)                                             \
236      { gedcom_error(_("The tag '%s' is not a valid top-level tag"),           \
237                     CHILDTAG); \
238        HANDLE_ERROR; \
239      }
240
241 %}
242
243 %union {
244   int  number;
245   char *string;
246   Gedcom_ctxt ctxt;
247 }
248
249 %token_table
250 %expect 300
251
252 %token <string> BADTOKEN
253 %token <number> OPEN
254 %token <string> CLOSE
255 %token <string> ESCAPE
256 %token <string> DELIM
257 %token <string> ANYCHAR
258 %token <string> POINTER
259 %token <string> USERTAG
260 %token <string> TAG_ABBR
261 %token <string> TAG_ADDR
262 %token <string> TAG_ADR1
263 %token <string> TAG_ADR2
264 %token <string> TAG_ADOP
265 %token <string> TAG_AFN
266 %token <string> TAG_AGE
267 %token <string> TAG_AGNC
268 %token <string> TAG_ALIA
269 %token <string> TAG_ANCE
270 %token <string> TAG_ANCI
271 %token <string> TAG_ANUL
272 %token <string> TAG_ASSO
273 %token <string> TAG_AUTH
274 %token <string> TAG_BAPL
275 %token <string> TAG_BAPM
276 %token <string> TAG_BARM
277 %token <string> TAG_BASM
278 %token <string> TAG_BIRT
279 %token <string> TAG_BLES
280 %token <string> TAG_BLOB
281 %token <string> TAG_BURI
282 %token <string> TAG_CALN
283 %token <string> TAG_CAST
284 %token <string> TAG_CAUS
285 %token <string> TAG_CENS
286 %token <string> TAG_CHAN
287 %token <string> TAG_CHAR
288 %token <string> TAG_CHIL
289 %token <string> TAG_CHR
290 %token <string> TAG_CHRA
291 %token <string> TAG_CITY
292 %token <string> TAG_CONC
293 %token <string> TAG_CONF
294 %token <string> TAG_CONL
295 %token <string> TAG_CONT
296 %token <string> TAG_COPR
297 %token <string> TAG_CORP
298 %token <string> TAG_CREM
299 %token <string> TAG_CTRY
300 %token <string> TAG_DATA
301 %token <string> TAG_DATE
302 %token <string> TAG_DEAT
303 %token <string> TAG_DESC
304 %token <string> TAG_DESI
305 %token <string> TAG_DEST
306 %token <string> TAG_DIV
307 %token <string> TAG_DIVF
308 %token <string> TAG_DSCR
309 %token <string> TAG_EDUC
310 %token <string> TAG_EMIG
311 %token <string> TAG_ENDL
312 %token <string> TAG_ENGA
313 %token <string> TAG_EVEN
314 %token <string> TAG_FAM
315 %token <string> TAG_FAMC
316 %token <string> TAG_FAMF
317 %token <string> TAG_FAMS
318 %token <string> TAG_FCOM
319 %token <string> TAG_FILE
320 %token <string> TAG_FORM
321 %token <string> TAG_GEDC
322 %token <string> TAG_GIVN
323 %token <string> TAG_GRAD
324 %token <string> TAG_HEAD
325 %token <string> TAG_HUSB
326 %token <string> TAG_IDNO
327 %token <string> TAG_IMMI
328 %token <string> TAG_INDI
329 %token <string> TAG_LANG
330 %token <string> TAG_LEGA
331 %token <string> TAG_MARB
332 %token <string> TAG_MARC
333 %token <string> TAG_MARL
334 %token <string> TAG_MARR
335 %token <string> TAG_MARS
336 %token <string> TAG_MEDI
337 %token <string> TAG_NAME
338 %token <string> TAG_NATI
339 %token <string> TAG_NATU
340 %token <string> TAG_NCHI
341 %token <string> TAG_NICK
342 %token <string> TAG_NMR
343 %token <string> TAG_NOTE
344 %token <string> TAG_NPFX
345 %token <string> TAG_NSFX
346 %token <string> TAG_OBJE
347 %token <string> TAG_OCCU
348 %token <string> TAG_ORDI
349 %token <string> TAG_ORDN
350 %token <string> TAG_PAGE
351 %token <string> TAG_PEDI
352 %token <string> TAG_PHON
353 %token <string> TAG_PLAC
354 %token <string> TAG_POST
355 %token <string> TAG_PROB
356 %token <string> TAG_PROP
357 %token <string> TAG_PUBL
358 %token <string> TAG_QUAY
359 %token <string> TAG_REFN
360 %token <string> TAG_RELA
361 %token <string> TAG_RELI
362 %token <string> TAG_REPO
363 %token <string> TAG_RESI
364 %token <string> TAG_RESN
365 %token <string> TAG_RETI
366 %token <string> TAG_RFN
367 %token <string> TAG_RIN
368 %token <string> TAG_ROLE
369 %token <string> TAG_SEX
370 %token <string> TAG_SLGC
371 %token <string> TAG_SLGS
372 %token <string> TAG_SOUR
373 %token <string> TAG_SPFX
374 %token <string> TAG_SSN
375 %token <string> TAG_STAE
376 %token <string> TAG_STAT
377 %token <string> TAG_SUBM
378 %token <string> TAG_SUBN
379 %token <string> TAG_SURN
380 %token <string> TAG_TEMP
381 %token <string> TAG_TEXT
382 %token <string> TAG_TIME
383 %token <string> TAG_TITL
384 %token <string> TAG_TRLR
385 %token <string> TAG_TYPE
386 %token <string> TAG_VERS
387 %token <string> TAG_WIFE
388 %token <string> TAG_WILL
389
390 %type <string> anystdtag
391 %type <string> anytoptag
392 %type <string> line_item
393 %type <string> line_value
394 %type <string> mand_line_item
395 %type <string> mand_pointer
396 %type <string> note_line_item
397 %type <string> anychar
398 %type <string> opt_xref
399 %type <string> opt_value
400 %type <string> opt_line_item
401 %type <string> fam_event_tag
402 %type <string> indiv_attr_tag
403 %type <string> indiv_birt_tag
404 %type <string> indiv_gen_tag
405 %type <string> lio_bapl_tag
406 %type <ctxt> head_sect
407
408 %%
409
410 file        : head_sect records trlr_sect
411                { if (fail == 1) YYABORT; }
412             ;
413
414 records     : /* empty */
415             | records record
416             ;
417
418 record      : fam_rec
419             | indiv_rec
420             | multim_rec
421             | note_rec
422             | repos_rec
423             | source_rec
424             | submis_rec
425             | submit_rec
426             | no_std_rec
427             ;
428
429 /*********************************************************************/
430 /**** Header                                                      ****/
431 /*********************************************************************/
432 head_sect    : OPEN DELIM TAG_HEAD
433                { $<ctxt>$ = start_record(REC_HEAD, $1, NULL, $3);
434                  START(HEAD, $<ctxt>$) }
435                head_subs
436                { if (compat_mode(C_FTREE))
437                    CHECK3(SOUR, GEDC, CHAR)
438                  else
439                    CHECK4(SOUR, SUBM, GEDC, CHAR)
440                }
441                CLOSE
442                { end_record(REC_HEAD, $<ctxt>4); }
443              ;
444
445 head_subs    : /* empty */
446              | head_subs head_sub
447              ;
448
449 head_sub     : head_sour_sect  { OCCUR2(SOUR, 1, 1) }
450              | head_dest_sect  { OCCUR2(DEST, 0, 1) }
451              | head_date_sect  { OCCUR2(DATE, 0, 1) }
452              | head_subm_sect  { OCCUR2(SUBM, 1, 1) }
453              | head_subn_sect  { OCCUR2(SUBN, 0, 1) }
454              | head_file_sect  { OCCUR2(FILE, 0, 1) }
455              | head_copr_sect  { OCCUR2(COPR, 0, 1) }
456              | head_gedc_sect  { OCCUR2(GEDC, 1, 1) }
457              | head_char_sect  { OCCUR2(CHAR, 1, 1) }
458              | head_lang_sect  { OCCUR2(LANG, 0, 1) }
459              | head_plac_sect  { OCCUR2(PLAC, 0, 1) }
460              | head_note_sect  { OCCUR2(NOTE, 0, 1) }
461              | no_std_sub
462              ;
463
464 /* HEAD.SOUR */
465 head_sour_sect : OPEN DELIM TAG_SOUR mand_line_item 
466                  { set_compatibility($4);
467                    $<ctxt>$ = start_element(ELT_HEAD_SOUR, PARENT,
468                                             $1, $3, $4,
469                                             GEDCOM_MAKE_STRING($4));
470                    START(SOUR, $<ctxt>$)
471                  }
472                  head_sour_subs
473                  { CHECK0 }
474                  CLOSE
475                  { end_element(ELT_HEAD_SOUR, PARENT, $<ctxt>5, NULL); }
476                ;
477
478 head_sour_subs : /* empty */
479                | head_sour_subs head_sour_sub
480                ;
481
482 head_sour_sub : head_sour_vers_sect  { OCCUR2(VERS, 0, 1) }
483               | head_sour_name_sect  { OCCUR2(NAME, 0, 1) }
484               | head_sour_corp_sect  { OCCUR2(CORP, 0, 1) } 
485               | head_sour_data_sect  { OCCUR2(DATA, 0, 1) }
486               | no_std_sub
487               ;
488
489 head_sour_vers_sect : OPEN DELIM TAG_VERS mand_line_item
490                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_VERS, PARENT,
491                                                  $1, $3, $4,
492                                                  GEDCOM_MAKE_STRING($4));
493                         START(VERS, $<ctxt>$)
494                       }
495                       no_std_subs
496                       { CHECK0 }
497                       CLOSE
498                       { end_element(ELT_HEAD_SOUR_VERS,
499                                     PARENT, $<ctxt>5, NULL);
500                       }
501                     ;
502 head_sour_name_sect : OPEN DELIM TAG_NAME mand_line_item
503                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_NAME, PARENT,
504                                                  $1, $3, $4,
505                                                  GEDCOM_MAKE_STRING($4));
506                         START(NAME, $<ctxt>$)
507                       }
508                       no_std_subs
509                       { CHECK0 }
510                       CLOSE
511                       { end_element(ELT_HEAD_SOUR_NAME,
512                                     PARENT, $<ctxt>5, NULL);
513                       }
514                     ;
515 head_sour_corp_sect : OPEN DELIM TAG_CORP mand_line_item 
516                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_CORP, PARENT,
517                                                  $1, $3, $4, 
518                                                  GEDCOM_MAKE_STRING($4));
519                         START(CORP, $<ctxt>$)
520                       }
521                       head_sour_corp_subs
522                       { CHECK0 }
523                       CLOSE
524                       { end_element(ELT_HEAD_SOUR_CORP,
525                                     PARENT, $<ctxt>5, NULL);
526                       }
527                     ;
528
529 head_sour_corp_subs : /* empty */
530                     | head_sour_corp_subs head_sour_corp_sub
531                     ;
532
533 head_sour_corp_sub : addr_struc_sub  /* 0:1 */
534                    | no_std_sub
535                    ;
536
537 head_sour_data_sect : OPEN DELIM TAG_DATA mand_line_item 
538                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA, PARENT,
539                                                  $1, $3, $4, 
540                                                  GEDCOM_MAKE_STRING($4));
541                         START(DATA, $<ctxt>$)
542                       }
543                       head_sour_data_subs
544                       { CHECK0 }
545                       CLOSE
546                       { end_element(ELT_HEAD_SOUR_DATA,
547                                     PARENT, $<ctxt>5, NULL);
548                       }
549                     ;
550
551 head_sour_data_subs : /* empty */
552                     | head_sour_data_subs head_sour_data_sub
553                     ;
554
555 head_sour_data_sub : head_sour_data_date_sect  { OCCUR2(DATE, 0, 1) }
556                    | head_sour_data_copr_sect  { OCCUR2(COPR, 0, 1) }
557                    | no_std_sub
558                    ;
559
560 head_sour_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
561                            { struct date_value dv = gedcom_parse_date($4);
562                              $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_DATE,
563                                                       PARENT, $1, $3, $4, 
564                                                       GEDCOM_MAKE_DATE(dv));
565                              START(DATE, $<ctxt>$)
566                            }
567                            no_std_subs
568                            { CHECK0 }
569                            CLOSE
570                            { end_element(ELT_HEAD_SOUR_DATA_DATE,
571                                          PARENT, $<ctxt>5, NULL);
572                            }
573                          ;
574 head_sour_data_copr_sect : OPEN DELIM TAG_COPR mand_line_item
575                            { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_COPR,
576                                                       PARENT, $1, $3, $4, 
577                                                       GEDCOM_MAKE_STRING($4));
578                              START(COPR, $<ctxt>$)
579                            }
580                            no_std_subs
581                            { CHECK0 }
582                            CLOSE
583                            { end_element(ELT_HEAD_SOUR_DATA_COPR,
584                                          PARENT, $<ctxt>5, NULL);
585                            }
586                          ;
587
588 /* HEAD.DEST */
589 head_dest_sect : OPEN DELIM TAG_DEST mand_line_item
590                  { $<ctxt>$ = start_element(ELT_HEAD_DEST,
591                                             PARENT, $1, $3, $4, 
592                                             GEDCOM_MAKE_STRING($4));
593                    START(DEST, $<ctxt>$)
594                  }
595                  no_std_subs
596                  { CHECK0 }
597                  CLOSE
598                  { end_element(ELT_HEAD_DEST,
599                                PARENT, $<ctxt>5, NULL);
600                  }
601                ;
602
603 /* HEAD.DATE */
604 head_date_sect : OPEN DELIM TAG_DATE mand_line_item 
605                  { struct date_value dv = gedcom_parse_date($4);
606                    $<ctxt>$ = start_element(ELT_HEAD_DATE,
607                                             PARENT, $1, $3, $4, 
608                                             GEDCOM_MAKE_DATE(dv));
609                    START(DATE, $<ctxt>$)
610                  }
611                  head_date_subs
612                  { CHECK0 }
613                  CLOSE
614                  { end_element(ELT_HEAD_DATE,
615                                PARENT, $<ctxt>5, NULL);
616                  }
617                ;
618
619 head_date_subs : /* empty */
620                | head_date_subs head_date_sub
621                ;
622
623 head_date_sub  : head_date_time_sect  { OCCUR2(TIME, 0, 1) }
624                | no_std_sub
625                ;
626
627 head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
628                       { $<ctxt>$ = start_element(ELT_HEAD_DATE_TIME,
629                                                  PARENT, $1, $3, $4, 
630                                                  GEDCOM_MAKE_STRING($4));
631                         START(TIME, $<ctxt>$)
632                       }
633                       no_std_subs
634                       { CHECK0 }
635                       CLOSE
636                       { end_element(ELT_HEAD_DATE_TIME,
637                                     PARENT, $<ctxt>5, NULL);
638                       }
639                     ;
640
641 /* HEAD.SUBM */
642 head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
643                  { $<ctxt>$ = start_element(ELT_HEAD_SUBM,
644                                             PARENT, $1, $3, $4, 
645                                             GEDCOM_MAKE_STRING($4));
646                    START(SUBM, $<ctxt>$)
647                  }
648                  no_std_subs
649                  { CHECK0 }
650                  CLOSE
651                  { end_element(ELT_HEAD_SUBM,
652                                PARENT, $<ctxt>5, NULL);
653                  }
654                ;
655 /* HEAD.SUBN */
656 head_subn_sect : OPEN DELIM TAG_SUBN mand_pointer 
657                  { $<ctxt>$ = start_element(ELT_HEAD_SUBN,
658                                             PARENT, $1, $3, $4, 
659                                             GEDCOM_MAKE_STRING($4));
660                    START(SUBN, $<ctxt>$)
661                  }
662                  no_std_subs
663                  { CHECK0 }
664                  CLOSE
665                  { end_element(ELT_HEAD_SUBN,
666                                PARENT, $<ctxt>5, NULL);
667                  }
668                ;
669 /* HEAD.FILE */
670 head_file_sect : OPEN DELIM TAG_FILE mand_line_item 
671                  { $<ctxt>$ = start_element(ELT_HEAD_FILE,
672                                             PARENT, $1, $3, $4, 
673                                             GEDCOM_MAKE_STRING($4));
674                    START(FILE, $<ctxt>$)
675                  }
676                  no_std_subs
677                  { CHECK0 }
678                  CLOSE
679                  { end_element(ELT_HEAD_FILE, PARENT, $<ctxt>5, NULL);
680                  }
681                ;
682 /* HEAD.COPR */
683 head_copr_sect : OPEN DELIM TAG_COPR mand_line_item 
684                  { $<ctxt>$ = start_element(ELT_HEAD_COPR,
685                                             PARENT, $1, $3, $4, 
686                                             GEDCOM_MAKE_STRING($4));
687                    START(COPR, $<ctxt>$)
688                  }
689                  no_std_subs
690                  { CHECK0 }
691                  CLOSE
692                  { end_element(ELT_HEAD_COPR, PARENT, $<ctxt>5, NULL);
693                  }
694                ;
695 /* HEAD.GEDC */
696 head_gedc_sect : OPEN DELIM TAG_GEDC
697                  { $<ctxt>$ = start_element(ELT_HEAD_GEDC,
698                                             PARENT, $1, $3, NULL,
699                                             GEDCOM_MAKE_NULL());
700                    START(GEDC, $<ctxt>$)
701                  }
702                  head_gedc_subs
703                  { CHECK2(VERS, FORM) }
704                  CLOSE
705                  { end_element(ELT_HEAD_GEDC, PARENT, $<ctxt>4, NULL);
706                  }
707                ;
708
709 head_gedc_subs : /* empty */
710                | head_gedc_subs head_gedc_sub
711                ;
712
713 head_gedc_sub  : head_gedc_vers_sect  { OCCUR2(VERS, 1, 1) }
714                | head_gedc_form_sect  { OCCUR2(FORM, 1, 1) }
715                | no_std_sub
716                ;
717 head_gedc_vers_sect : OPEN DELIM TAG_VERS mand_line_item  
718                       { $<ctxt>$ = start_element(ELT_HEAD_GEDC_VERS,
719                                                  PARENT, $1, $3, $4, 
720                                                  GEDCOM_MAKE_STRING($4));
721                         START(VERS, $<ctxt>$)
722                       }
723                       no_std_subs
724                       { CHECK0 }
725                       CLOSE
726                       { end_element(ELT_HEAD_GEDC_VERS,
727                                     PARENT, $<ctxt>5, NULL);
728                       }
729                     ;
730 head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item   
731                       { $<ctxt>$ = start_element(ELT_HEAD_GEDC_FORM,
732                                                  PARENT, $1, $3, $4, 
733                                                  GEDCOM_MAKE_STRING($4));
734                         START(FORM, $<ctxt>$)
735                       }
736                       no_std_subs
737                       { CHECK0 }
738                       CLOSE
739                       { end_element(ELT_HEAD_GEDC_FORM,
740                                     PARENT, $<ctxt>5, NULL);
741                       }
742                     ;
743
744 /* HEAD.CHAR */
745 head_char_sect : OPEN DELIM TAG_CHAR mand_line_item 
746                  { if (open_conv_to_internal($4) == 0) YYERROR;
747                    $<ctxt>$ = start_element(ELT_HEAD_CHAR,
748                                             PARENT, $1, $3, $4, 
749                                             GEDCOM_MAKE_STRING($4));
750                    START(CHAR, $<ctxt>$)
751                  }
752                  head_char_subs
753                  { CHECK0 }
754                  CLOSE
755                  { end_element(ELT_HEAD_CHAR, PARENT, $<ctxt>5, NULL);
756                  }
757                ;
758
759 head_char_subs : /* empty */
760                | head_char_subs head_char_sub
761                ;
762
763 head_char_sub  : head_char_vers_sect  { OCCUR2(VERS, 0, 1) }
764                | no_std_sub
765                ;
766 head_char_vers_sect : OPEN DELIM TAG_VERS mand_line_item   
767                       { $<ctxt>$ = start_element(ELT_HEAD_CHAR_VERS,
768                                                  PARENT, $1, $3, $4, 
769                                                  GEDCOM_MAKE_STRING($4));
770                         START(VERS, $<ctxt>$)
771                       }
772                       no_std_subs
773                       { CHECK0 }
774                       CLOSE
775                       { end_element(ELT_HEAD_CHAR_VERS,
776                                     PARENT, $<ctxt>5, NULL);
777                       }
778                     ;
779
780 /* HEAD.LANG */
781 head_lang_sect : OPEN DELIM TAG_LANG mand_line_item   
782                  { $<ctxt>$ = start_element(ELT_HEAD_LANG,
783                                             PARENT, $1, $3, $4, 
784                                             GEDCOM_MAKE_STRING($4));
785                    START(LANG, $<ctxt>$)
786                  }
787                  no_std_subs
788                  { CHECK0 }
789                  CLOSE
790                  { end_element(ELT_HEAD_LANG, PARENT, $<ctxt>5, NULL);
791                  }
792                ;
793 /* HEAD.PLAC */
794 head_plac_sect : OPEN DELIM TAG_PLAC
795                  { $<ctxt>$ = start_element(ELT_HEAD_PLAC,
796                                             PARENT, $1, $3, NULL,
797                                             GEDCOM_MAKE_NULL());
798                    START(PLAC, $<ctxt>$)
799                  }
800                  head_plac_subs
801                  { CHECK1(FORM) }
802                  CLOSE
803                  { end_element(ELT_HEAD_PLAC, PARENT, $<ctxt>4, NULL);
804                  }
805                ;
806
807 head_plac_subs : /* empty */
808                | head_plac_subs head_plac_sub
809                ;
810
811 head_plac_sub  : head_plac_form_sect  { OCCUR2(FORM, 1, 1) }
812                | no_std_sub
813                ;
814 head_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item   
815                       { $<ctxt>$ = start_element(ELT_HEAD_PLAC_FORM,
816                                                  PARENT, $1, $3, $4, 
817                                                  GEDCOM_MAKE_STRING($4));
818                         START(FORM, $<ctxt>$)
819                       }
820                       no_std_subs
821                       { CHECK0 }
822                       CLOSE
823                       { end_element(ELT_HEAD_PLAC_FORM,
824                                     PARENT, $<ctxt>5, NULL);
825                       }
826                     ;
827
828 /* HEAD.NOTE */
829 head_note_sect : OPEN DELIM TAG_NOTE mand_line_item 
830                  { $<ctxt>$ = start_element(ELT_HEAD_NOTE,
831                                             PARENT, $1, $3, $4, 
832                                             GEDCOM_MAKE_STRING($4));
833                    START(NOTE, $<ctxt>$)
834                  }
835                  head_note_subs
836                  { CHECK0 }
837                  CLOSE
838                  { end_element(ELT_HEAD_NOTE, PARENT, $<ctxt>5, NULL);
839                  }
840                ;
841
842 head_note_subs : /* empty */
843                | head_note_subs head_note_sub
844                ;
845
846 head_note_sub  : continuation_sub  /* 0:M */
847                | no_std_sub
848                ;
849
850 /*********************************************************************/
851 /**** Trailer                                                     ****/
852 /*********************************************************************/
853 /* Don't need callbacks here, there is no information... */
854 trlr_sect   : OPEN DELIM TAG_TRLR CLOSE { }
855             ;
856
857 /*********************************************************************/
858 /**** Family record                                               ****/
859 /*********************************************************************/
860 fam_rec      : OPEN DELIM POINTER DELIM TAG_FAM
861                { $<ctxt>$ = start_record(REC_FAM, $1, $3, $5);
862                  START(FAM, $<ctxt>$) }
863                fam_subs
864                { CHECK0 }
865                CLOSE
866                { end_record(REC_FAM, $<ctxt>6); }
867              ;
868
869 fam_subs     : /* empty */
870              | fam_subs fam_sub
871              ;
872
873 fam_sub      : fam_event_struc_sub  /* 0:M */
874              | fam_husb_sect  { OCCUR2(HUSB, 0, 1) }
875              | fam_wife_sect  { OCCUR2(WIFE, 0, 1) }
876              | fam_chil_sect  /* 0:M */
877              | fam_nchi_sect  { OCCUR2(NCHI, 0, 1) }
878              | fam_subm_sect  /* 0:M */
879              | lds_spouse_seal_sub  /* 0:M */
880              | source_cit_sub  /* 0:M */
881              | multim_link_sub  /* 0:M */
882              | note_struc_sub  /* 0:M */
883              | ident_struc_sub  /* 0:1 */
884              | change_date_sub  /* 0:1 */
885              | no_std_sub
886              ;
887
888 /* FAM.HUSB */
889 fam_husb_sect : OPEN DELIM TAG_HUSB mand_pointer    
890                 { $<ctxt>$ = start_element(ELT_FAM_HUSB,
891                                            PARENT, $1, $3, $4, 
892                                            GEDCOM_MAKE_STRING($4));
893                   START(HUSB, $<ctxt>$)
894                 }
895                 no_std_subs
896                 { CHECK0 }
897                 CLOSE
898                 { end_element(ELT_FAM_HUSB, PARENT, $<ctxt>5, NULL);
899                 }
900               ;
901
902 /* FAM.WIFE */
903 fam_wife_sect : OPEN DELIM TAG_WIFE mand_pointer 
904                 { $<ctxt>$ = start_element(ELT_FAM_WIFE,
905                                            PARENT, $1, $3, $4, 
906                                            GEDCOM_MAKE_STRING($4));
907                   START(WIFE, $<ctxt>$)
908                 }
909                 no_std_subs
910                 { CHECK0 }
911                 CLOSE
912                 { end_element(ELT_FAM_WIFE, PARENT, $<ctxt>5, NULL);
913                 }
914               ;
915
916 /* FAM.CHIL */
917 fam_chil_sect : OPEN DELIM TAG_CHIL mand_pointer
918                 { $<ctxt>$ = start_element(ELT_FAM_CHIL,
919                                            PARENT, $1, $3, $4, 
920                                            GEDCOM_MAKE_STRING($4));
921                   START(CHIL, $<ctxt>$) 
922                 } 
923                 no_std_subs 
924                 { CHECK0 } 
925                 CLOSE
926                 { end_element(ELT_FAM_CHIL, PARENT, $<ctxt>5, NULL);
927                 }
928               ;
929
930 /* FAM.NCHI */
931 fam_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item    
932                 { $<ctxt>$ = start_element(ELT_FAM_NCHI,
933                                            PARENT, $1, $3, $4, 
934                                            GEDCOM_MAKE_STRING($4));
935                   START(NCHI, $<ctxt>$)  
936                 }  
937                 no_std_subs  
938                 { CHECK0 }  
939                 CLOSE
940                 { end_element(ELT_FAM_NCHI, PARENT, $<ctxt>5, NULL);
941                 }
942               ;
943
944 /* FAM.SUBM */
945 fam_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
946                 { $<ctxt>$ = start_element(ELT_FAM_SUBM,
947                                            PARENT, $1, $3, $4, 
948                                            GEDCOM_MAKE_STRING($4));
949                   START(SUBM, $<ctxt>$)   
950                 }   
951                 no_std_subs   
952                 { CHECK0 }   
953                 CLOSE
954                 { end_element(ELT_FAM_SUBM, PARENT, $<ctxt>5, NULL);
955                 }
956               ;
957
958 /*********************************************************************/
959 /**** Individual record                                           ****/
960 /*********************************************************************/
961 indiv_rec   : OPEN DELIM POINTER DELIM TAG_INDI
962               { $<ctxt>$ = start_record(REC_INDI, $1, $3, $5);
963                 START(INDI, $<ctxt>$) }
964               indi_subs
965               { CHECK0 }
966               CLOSE
967               { end_record(REC_INDI, $<ctxt>6); }
968             ;
969
970 indi_subs   : /* empty */
971             | indi_subs indi_sub
972             ;
973
974 indi_sub    : indi_resn_sect  { OCCUR2(RESN, 0, 1) }
975             | pers_name_struc_sub  /* 0:M */
976             | indi_sex_sect  { OCCUR2(SEX, 0, 1) }
977             | indiv_even_struc_sub  /* 0:M */
978             | indiv_attr_struc_sub  /* 0:M */
979             | lds_indiv_ord_sub  /* 0:M */
980             | chi_fam_link_sub  /* 0:M */
981             | spou_fam_link_sub  /* 0:M */
982             | indi_subm_sect  /* 0:M */
983             | assoc_struc_sub  /* 0:M */
984             | indi_alia_sect  /* 0:M */
985             | indi_anci_sect  /* 0:M */
986             | indi_desi_sect  /* 0:M */
987             | source_cit_sub  /* 0:M */
988             | multim_link_sub  /* 0:M */
989             | note_struc_sub  /* 0:M */
990             | indi_rfn_sect  { OCCUR2(RFN, 0, 1) }
991             | indi_afn_sect  /* 0:M */
992             | ident_struc_sub  /* 0:1 */
993             | change_date_sub  /* 0:1 */
994             | ftree_addr_sect { if (!compat_mode(C_FTREE))
995                                   INVALID_TAG("ADDR");
996                               }
997             | no_std_sub
998             ;
999
1000 /* INDI.RESN */
1001 indi_resn_sect : OPEN DELIM TAG_RESN mand_line_item     
1002                  { $<ctxt>$ = start_element(ELT_INDI_RESN,
1003                                             PARENT, $1, $3, $4, 
1004                                             GEDCOM_MAKE_STRING($4));
1005                    START(RESN, $<ctxt>$)    
1006                  }    
1007                  no_std_subs     
1008                  { CHECK0 }     
1009                  CLOSE     
1010                  { end_element(ELT_INDI_RESN, PARENT, $<ctxt>5, NULL);
1011                  }
1012                ;
1013
1014 /* INDI.SEX */
1015 indi_sex_sect  : OPEN DELIM TAG_SEX mand_line_item     
1016                  { $<ctxt>$ = start_element(ELT_INDI_SEX,
1017                                             PARENT, $1, $3, $4, 
1018                                             GEDCOM_MAKE_STRING($4));
1019                    START(SEX, $<ctxt>$)     
1020                  }     
1021                  no_std_subs     
1022                  { CHECK0 }     
1023                  CLOSE     
1024                  { end_element(ELT_INDI_SEX, PARENT, $<ctxt>5, NULL);
1025                  }
1026                ;
1027
1028 /* INDI.SUBM */
1029 indi_subm_sect : OPEN DELIM TAG_SUBM mand_pointer 
1030                  { $<ctxt>$ = start_element(ELT_INDI_SUBM,
1031                                             PARENT, $1, $3, $4, 
1032                                             GEDCOM_MAKE_STRING($4));
1033                    START(SUBM, $<ctxt>$)      
1034                  }      
1035                  no_std_subs      
1036                  { CHECK0 }      
1037                  CLOSE      
1038                  { end_element(ELT_INDI_SUBM, PARENT, $<ctxt>5, NULL);
1039                  }
1040                ;
1041
1042 /* INDI.ALIA */
1043 indi_alia_sect : OPEN DELIM TAG_ALIA mand_pointer
1044                  { $<ctxt>$ = start_element(ELT_INDI_ALIA,
1045                                             PARENT, $1, $3, $4, 
1046                                             GEDCOM_MAKE_STRING($4));
1047                    START(ALIA, $<ctxt>$)       
1048                  }       
1049                  no_std_subs       
1050                  { CHECK0 }       
1051                  CLOSE       
1052                  { end_element(ELT_INDI_ALIA, PARENT, $<ctxt>5, NULL);
1053                  }
1054                ;
1055
1056 /* INDI.ANCI */
1057 indi_anci_sect : OPEN DELIM TAG_ANCI mand_pointer
1058                  { $<ctxt>$ = start_element(ELT_INDI_ANCI,
1059                                             PARENT, $1, $3, $4, 
1060                                             GEDCOM_MAKE_STRING($4));
1061                    START(ANCI, $<ctxt>$)        
1062                  }        
1063                  no_std_subs        
1064                  { CHECK0 }        
1065                  CLOSE        
1066                  { end_element(ELT_INDI_ANCI, PARENT, $<ctxt>5, NULL);
1067                  }
1068                ;
1069
1070 /* INDI.DESI */
1071 indi_desi_sect : OPEN DELIM TAG_DESI mand_pointer
1072                  { $<ctxt>$ = start_element(ELT_INDI_DESI,
1073                                             PARENT, $1, $3, $4, 
1074                                             GEDCOM_MAKE_STRING($4));
1075                    START(DESI, $<ctxt>$)         
1076                  }         
1077                  no_std_subs         
1078                  { CHECK0 }         
1079                  CLOSE         
1080                  { end_element(ELT_INDI_DESI, PARENT, $<ctxt>5, NULL);
1081                  }
1082                ;
1083
1084 /* INDI.RFN */
1085 indi_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item     
1086                  { $<ctxt>$ = start_element(ELT_INDI_RFN,
1087                                             PARENT, $1, $3, $4, 
1088                                             GEDCOM_MAKE_STRING($4));
1089                    START(RFN, $<ctxt>$)          
1090                  }          
1091                  no_std_subs          
1092                  { CHECK0 }          
1093                  CLOSE          
1094                  { end_element(ELT_INDI_RFN, PARENT, $<ctxt>5, NULL);
1095                  }
1096                ;
1097
1098 /* INDI.AFN */
1099 indi_afn_sect  : OPEN DELIM TAG_AFN mand_line_item      
1100                  { $<ctxt>$ = start_element(ELT_INDI_AFN,
1101                                             PARENT, $1, $3, $4, 
1102                                             GEDCOM_MAKE_STRING($4));
1103                    START(AFN, $<ctxt>$)           
1104                  }           
1105                  no_std_subs           
1106                  { CHECK0 }           
1107                  CLOSE           
1108                  { end_element(ELT_INDI_AFN, PARENT, $<ctxt>5, NULL);
1109                  }
1110                ;
1111
1112 /* INDI.ADDR (Only for 'ftree' compatibility) */
1113 ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
1114                   { START(ADDR, NULL) } no_std_subs { CHECK0 } CLOSE { }
1115
1116 /*********************************************************************/
1117 /**** Multimedia record                                           ****/
1118 /*********************************************************************/
1119 multim_rec  : OPEN DELIM POINTER DELIM TAG_OBJE
1120               { $<ctxt>$ = start_record(REC_OBJE, $1, $3, $5);
1121                 START(OBJE, $<ctxt>$) }
1122               obje_subs
1123               { CHECK2(FORM, BLOB) }
1124               CLOSE
1125               { end_record(REC_OBJE, $<ctxt>6); }
1126             ;
1127
1128 obje_subs   : /* empty */
1129             | obje_subs obje_sub
1130             ;
1131
1132 obje_sub    : obje_form_sect  { OCCUR2(FORM, 1, 1) }
1133             | obje_titl_sect  { OCCUR2(TITL, 0, 1) }
1134             | note_struc_sub  /* 0:M */
1135             | obje_blob_sect  { OCCUR2(BLOB, 1, 1) }
1136             | obje_obje_sect  { OCCUR2(OBJE, 0, 1) }
1137             | ident_struc_sub  /* 0:1 */
1138             | change_date_sub  /* 0:1 */
1139             | no_std_sub
1140             ;
1141
1142 /* OBJE.FORM */
1143 obje_form_sect : OPEN DELIM TAG_FORM mand_line_item       
1144                  { $<ctxt>$ = start_element(ELT_OBJE_FORM,
1145                                             PARENT, $1, $3, $4, 
1146                                             GEDCOM_MAKE_STRING($4));
1147                    START(FORM, $<ctxt>$)            
1148                  }            
1149                  no_std_subs            
1150                  { CHECK0 }            
1151                  CLOSE            
1152                  { end_element(ELT_OBJE_FORM, PARENT, $<ctxt>5, NULL);
1153                  }
1154                ;
1155
1156 /* OBJE.TITL */
1157 obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item       
1158                  { $<ctxt>$ = start_element(ELT_OBJE_TITL,
1159                                             PARENT, $1, $3, $4, 
1160                                             GEDCOM_MAKE_STRING($4));
1161                    START(TITL, $<ctxt>$)             
1162                  }             
1163                  no_std_subs             
1164                  { CHECK0 }             
1165                  CLOSE             
1166                  { end_element(ELT_OBJE_TITL, PARENT, $<ctxt>5, NULL);
1167                  }
1168                ;
1169
1170 /* OBJE.BLOB */
1171 obje_blob_sect : OPEN DELIM TAG_BLOB
1172                  { $<ctxt>$ = start_element(ELT_OBJE_BLOB,
1173                                             PARENT, $1, $3, NULL,
1174                                             GEDCOM_MAKE_NULL());
1175                    START(BLOB, $<ctxt>$)              
1176                  }
1177                  obje_blob_subs
1178                  { CHECK1(CONT) }
1179                  CLOSE              
1180                  { end_element(ELT_OBJE_BLOB, PARENT, $<ctxt>4, NULL);
1181                  }
1182                ;
1183
1184 obje_blob_subs : /* empty */
1185                | obje_blob_subs obje_blob_sub
1186                ;
1187
1188 obje_blob_sub  : obje_blob_cont_sect  { OCCUR1(CONT, 1) }
1189                | no_std_sub
1190                ;
1191
1192 obje_blob_cont_sect : OPEN DELIM TAG_CONT mand_line_item        
1193                       { $<ctxt>$ = start_element(ELT_OBJE_BLOB_CONT,
1194                                                  PARENT, $1, $3, $4, 
1195                                                  GEDCOM_MAKE_STRING($4));
1196                         START(CONT, $<ctxt>$)               
1197                       }                
1198                       no_std_subs                
1199                       { CHECK0 }                
1200                       CLOSE                
1201                       { end_element(ELT_OBJE_BLOB_CONT, PARENT,
1202                                     $<ctxt>5, NULL);
1203                       }
1204                     ;
1205
1206 /* OBJE.OBJE */
1207 obje_obje_sect : OPEN DELIM TAG_OBJE mand_pointer 
1208                  { $<ctxt>$ = start_element(ELT_OBJE_OBJE,
1209                                             PARENT, $1, $3, $4, 
1210                                             GEDCOM_MAKE_STRING($4));
1211                    START(OBJE, $<ctxt>$)  
1212                  }  
1213                  no_std_subs  
1214                  { CHECK0 }  
1215                  CLOSE  
1216                  { end_element(ELT_OBJE_OBJE, PARENT, $<ctxt>5, NULL);
1217                  }
1218                ;
1219
1220 /*********************************************************************/
1221 /**** Note record                                                 ****/
1222 /*********************************************************************/
1223 note_rec    : OPEN DELIM POINTER DELIM TAG_NOTE note_line_item
1224               { $<ctxt>$ = start_record(REC_NOTE, $1, $3, $5);
1225                 START(NOTE, $<ctxt>$) }
1226               note_subs
1227               { CHECK0 }
1228               CLOSE
1229               { end_record(REC_NOTE, $<ctxt>6); }
1230             ;
1231
1232 note_line_item : /* empty */
1233                    { if (!compat_mode(C_FTREE)) {
1234                        gedcom_error(_("Missing value")); YYERROR;
1235                      }
1236                    }
1237                | DELIM line_item
1238                    { gedcom_debug_print("==Val: %s==", $2);
1239                      $$ = $2; }
1240                ;
1241
1242 note_subs   : /* empty */
1243             | note_subs note_sub
1244             ;
1245
1246 note_sub    : continuation_sub  /* 0:M */
1247             | source_cit_sub  /* 0:M */
1248             | ident_struc_sub  /* 0:1 */
1249             | change_date_sub  /* 0:1 */
1250             | no_std_sub
1251             ;
1252
1253 /*********************************************************************/
1254 /**** Repository record                                           ****/
1255 /*********************************************************************/
1256 repos_rec   : OPEN DELIM POINTER DELIM TAG_REPO
1257               { $<ctxt>$ = start_record(REC_REPO, $1, $3, $5);
1258                 START(REPO, $<ctxt>$) }
1259               repo_subs
1260               { CHECK0 }
1261               CLOSE
1262               { end_record(REC_REPO, $<ctxt>6); }
1263             ;
1264
1265 repo_subs   : /* empty */
1266             | repo_subs repo_sub
1267             ;
1268
1269 repo_sub    : repo_name_sect  { OCCUR2(NAME, 0, 1) }
1270             | addr_struc_sub  /* 0:1 */
1271             | note_struc_sub  /* 0:M */
1272             | ident_struc_sub  /* 0:1 */
1273             | change_date_sub  /* 0:1 */
1274             | no_std_sub
1275             ;
1276
1277 /* REPO.NAME */
1278 repo_name_sect : OPEN DELIM TAG_NAME mand_line_item         
1279                  { $<ctxt>$ = start_element(ELT_REPO_NAME,
1280                                             PARENT, $1, $3, $4, 
1281                                             GEDCOM_MAKE_STRING($4));
1282                    START(NAME, $<ctxt>$)          
1283                  }          
1284                  no_std_subs          
1285                  { CHECK0 }          
1286                  CLOSE          
1287                  { end_element(ELT_REPO_NAME, PARENT, $<ctxt>5, NULL);
1288                  }
1289                ;
1290
1291 /*********************************************************************/
1292 /**** Source record                                               ****/
1293 /*********************************************************************/
1294 source_rec  : OPEN DELIM POINTER DELIM TAG_SOUR
1295               { $<ctxt>$ = start_record(REC_SOUR, $1, $3, $5);
1296                 START(SOUR, $<ctxt>$) }
1297               sour_subs
1298               { CHECK0 }
1299               CLOSE
1300               { end_record(REC_SOUR, $<ctxt>6); }
1301             ;
1302
1303 sour_subs   : /* empty */
1304             | sour_subs sour_sub
1305             ;
1306
1307 sour_sub    : sour_data_sect  { OCCUR2(DATA, 0, 1) }
1308             | sour_auth_sect  { OCCUR2(AUTH, 0, 1) }
1309             | sour_titl_sect  { OCCUR2(TITL, 0, 1) }
1310             | sour_abbr_sect  { OCCUR2(ABBR, 0, 1) }
1311             | sour_publ_sect  { OCCUR2(PUBL, 0, 1) }
1312             | sour_text_sect  { OCCUR2(TEXT, 0, 1) }
1313             | source_repos_cit_sub  /* 0:1 */
1314             | multim_link_sub  /* 0:M */
1315             | note_struc_sub  /* 0:M */
1316             | ident_struc_sub  /* 0:1 */
1317             | change_date_sub  /* 0:1 */
1318             | no_std_sub
1319             ;
1320
1321 /* SOUR.DATA */
1322 sour_data_sect : OPEN DELIM TAG_DATA
1323                  { $<ctxt>$ = start_element(ELT_SOUR_DATA,
1324                                             PARENT, $1, $3, NULL,
1325                                             GEDCOM_MAKE_NULL());
1326                    START(DATA, $<ctxt>$) 
1327                  }
1328                  sour_data_subs
1329                  { CHECK0 }
1330                  CLOSE 
1331                  { end_element(ELT_SOUR_DATA, PARENT, $<ctxt>4, NULL);
1332                  }
1333                ;
1334
1335 sour_data_subs : /* empty */
1336                | sour_data_subs sour_data_sub
1337                ;
1338
1339 sour_data_sub  : sour_data_even_sect  /* 0:M */
1340                | sour_data_agnc_sect  { OCCUR2(AGNC, 0, 1) }
1341                | note_struc_sub  /* 0:M */
1342                | no_std_sub
1343                ;
1344
1345 sour_data_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
1346                       { $<ctxt>$ = start_element(ELT_SOUR_DATA_EVEN,
1347                                                  PARENT, $1, $3, $4, 
1348                                                  GEDCOM_MAKE_STRING($4));
1349                         START(EVEN, $<ctxt>$)  
1350                       }
1351                       sour_data_even_subs
1352                       { CHECK0 }
1353                       CLOSE  
1354                       { end_element(ELT_SOUR_DATA_EVEN, PARENT,
1355                                     $<ctxt>5, NULL);
1356                       }
1357                     ;
1358
1359 sour_data_even_subs : /* empty */
1360                     | sour_data_even_subs sour_data_even_sub
1361                     ;
1362
1363 sour_data_even_sub  : sour_data_even_date_sect { OCCUR2(DATE, 0, 1) }
1364                     | sour_data_even_plac_sect { OCCUR2(PLAC, 0, 1) }
1365                     | no_std_sub
1366                     ;
1367
1368 sour_data_even_date_sect : OPEN DELIM TAG_DATE mand_line_item          
1369                            { struct date_value dv = gedcom_parse_date($4);
1370                              $<ctxt>$ = start_element(ELT_SOUR_DATA_EVEN_DATE,
1371                                                       PARENT, $1, $3, $4, 
1372                                                       GEDCOM_MAKE_DATE(dv));
1373                              START(DATE, $<ctxt>$)           
1374                            }           
1375                            no_std_subs           
1376                            { CHECK0 }           
1377                            CLOSE           
1378                            { end_element(ELT_SOUR_DATA_EVEN_DATE, PARENT,
1379                                          $<ctxt>5, NULL);
1380                            }
1381                          ;
1382
1383 sour_data_even_plac_sect : OPEN DELIM TAG_PLAC mand_line_item          
1384                            { $<ctxt>$ = start_element(ELT_SOUR_DATA_EVEN_PLAC,
1385                                                       PARENT, $1, $3, $4, 
1386                                                       GEDCOM_MAKE_STRING($4));
1387                              START(PLAC, $<ctxt>$)           
1388                            }           
1389                            no_std_subs           
1390                            { CHECK0 }           
1391                            CLOSE           
1392                            { end_element(ELT_SOUR_DATA_EVEN_PLAC, PARENT,
1393                                          $<ctxt>5, NULL);
1394                            }
1395                          ;
1396
1397 sour_data_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item          
1398                       { $<ctxt>$ = start_element(ELT_SOUR_DATA_AGNC,
1399                                                  PARENT, $1, $3, $4, 
1400                                                  GEDCOM_MAKE_STRING($4));
1401                         START(AGNC, $<ctxt>$)           
1402                       }           
1403                       no_std_subs           
1404                       { CHECK0 }           
1405                       CLOSE           
1406                       { end_element(ELT_SOUR_DATA_AGNC, PARENT,
1407                                     $<ctxt>5, NULL);
1408                       }
1409                     ;
1410
1411 /* SOUR.AUTH */
1412 sour_auth_sect : OPEN DELIM TAG_AUTH mand_line_item
1413                  { $<ctxt>$ = start_element(ELT_SOUR_AUTH,
1414                                             PARENT, $1, $3, $4, 
1415                                             GEDCOM_MAKE_STRING($4));
1416                    START(AUTH, $<ctxt>$) 
1417                  }
1418                  sour_auth_subs
1419                  { CHECK0 }
1420                  CLOSE 
1421                  { end_element(ELT_SOUR_AUTH, PARENT, $<ctxt>5, NULL);
1422                  }
1423                ;
1424
1425 sour_auth_subs : /* empty */
1426                | sour_auth_subs sour_auth_sub
1427                ;
1428
1429 sour_auth_sub  : continuation_sub  /* 0:M */
1430                | no_std_sub
1431                ;
1432
1433 /* SOUR.TITL */
1434 sour_titl_sect : OPEN DELIM TAG_TITL mand_line_item  
1435                  { $<ctxt>$ = start_element(ELT_SOUR_TITL,
1436                                             PARENT, $1, $3, $4, 
1437                                             GEDCOM_MAKE_STRING($4));
1438                    START(TITL, $<ctxt>$)   
1439                  }
1440                  sour_titl_subs 
1441                  { CHECK0 }
1442                  CLOSE   
1443                  { end_element(ELT_SOUR_TITL, PARENT, $<ctxt>5, NULL);
1444                  }
1445                ;
1446
1447 sour_titl_subs : /* empty */
1448                | sour_titl_subs sour_titl_sub
1449                ;
1450
1451 sour_titl_sub  : continuation_sub  /* 0:M */
1452                | no_std_sub
1453                ;
1454
1455 /* SOUR.ABBR */
1456 sour_abbr_sect : OPEN DELIM TAG_ABBR mand_line_item           
1457                  { $<ctxt>$ = start_element(ELT_SOUR_ABBR,
1458                                             PARENT, $1, $3, $4, 
1459                                             GEDCOM_MAKE_STRING($4));
1460                    START(ABBR, $<ctxt>$)            
1461                  }            
1462                  no_std_subs            
1463                  { CHECK0 }            
1464                  CLOSE            
1465                  { end_element(ELT_SOUR_ABBR, PARENT, $<ctxt>5, NULL);
1466                  }
1467                ;
1468
1469 /* SOUR.PUBL */
1470 sour_publ_sect : OPEN DELIM TAG_PUBL mand_line_item  
1471                  { $<ctxt>$ = start_element(ELT_SOUR_PUBL,
1472                                             PARENT, $1, $3, $4, 
1473                                             GEDCOM_MAKE_STRING($4));
1474                    START(PUBL, $<ctxt>$)            
1475                  }
1476                  sour_publ_subs  
1477                  { CHECK0 }
1478                  CLOSE            
1479                  { end_element(ELT_SOUR_PUBL, PARENT, $<ctxt>5, NULL);
1480                  }
1481                ;
1482
1483 sour_publ_subs : /* empty */
1484                | sour_publ_subs sour_publ_sub
1485                ;
1486
1487 sour_publ_sub  : continuation_sub  /* 0:M */
1488                | no_std_sub
1489                ;
1490
1491 /* SOUR.TEXT */
1492 sour_text_sect : OPEN DELIM TAG_TEXT mand_line_item   
1493                  { $<ctxt>$ = start_element(ELT_SOUR_TEXT,
1494                                             PARENT, $1, $3, $4, 
1495                                             GEDCOM_MAKE_STRING($4));
1496                    START(TEXT, $<ctxt>$)    
1497                  }
1498                  sour_text_subs  
1499                  { CHECK0 }
1500                  CLOSE    
1501                  { end_element(ELT_SOUR_TEXT, PARENT, $<ctxt>5, NULL);
1502                  }
1503                ;
1504
1505 sour_text_subs : /* empty */
1506                | sour_text_subs sour_text_sub
1507                ;
1508
1509 sour_text_sub  : continuation_sub  /* 0:M */
1510                | no_std_sub
1511                ;
1512
1513 /*********************************************************************/
1514 /**** Submission record                                           ****/
1515 /*********************************************************************/
1516 submis_rec  : OPEN DELIM POINTER DELIM TAG_SUBN    
1517               { $<ctxt>$ = start_record(REC_SUBN, $1, $3, $5);
1518                 START(SUBN, $<ctxt>$) }
1519               subn_subs
1520               { CHECK0 }
1521               CLOSE
1522               { end_record(REC_SUBN, $<ctxt>6); }
1523             ;
1524
1525 subn_subs   : /* empty */
1526             | subn_subs subn_sub
1527             ;
1528
1529 subn_sub    : subn_subm_sect  { OCCUR2(SUBM, 0, 1) }
1530             | subn_famf_sect  { OCCUR2(FAMF, 0, 1) }
1531             | subn_temp_sect  { OCCUR2(TEMP, 0, 1) }
1532             | subn_ance_sect  { OCCUR2(ANCE, 0, 1) }
1533             | subn_desc_sect  { OCCUR2(DESC, 0, 1) }
1534             | subn_ordi_sect  { OCCUR2(ORDI, 0, 1) }
1535             | subn_rin_sect  { OCCUR2(RIN, 0, 1) }
1536             | no_std_sub
1537             ;
1538
1539 /* SUBN.SUBM */
1540 subn_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
1541                  { $<ctxt>$ = start_element(ELT_SUBN_SUBM,
1542                                             PARENT, $1, $3, $4, 
1543                                             GEDCOM_MAKE_STRING($4));
1544                    START(SUBM, $<ctxt>$) 
1545                  } 
1546                  no_std_subs 
1547                  { CHECK0 } 
1548                  CLOSE 
1549                  { end_element(ELT_SUBN_SUBM, PARENT, $<ctxt>5, NULL);
1550                  }
1551                ;
1552
1553 /* SUBN.FAMF */
1554 subn_famf_sect : OPEN DELIM TAG_FAMF mand_line_item            
1555                  { $<ctxt>$ = start_element(ELT_SUBN_FAMF,
1556                                             PARENT, $1, $3, $4, 
1557                                             GEDCOM_MAKE_STRING($4));
1558                    START(FAMF, $<ctxt>$)             
1559                  }             
1560                  no_std_subs             
1561                  { CHECK0 }             
1562                  CLOSE             
1563                  { end_element(ELT_SUBN_FAMF, PARENT, $<ctxt>5, NULL);
1564                  }
1565                ;
1566
1567 /* SUBN.TEMP */
1568 subn_temp_sect : OPEN DELIM TAG_TEMP mand_line_item            
1569                  { $<ctxt>$ = start_element(ELT_SUBN_TEMP,
1570                                             PARENT, $1, $3, $4, 
1571                                             GEDCOM_MAKE_STRING($4));
1572                    START(TEMP, $<ctxt>$)             
1573                  }             
1574                  no_std_subs             
1575                  { CHECK0 }             
1576                  CLOSE             
1577                  { end_element(ELT_SUBN_TEMP, PARENT, $<ctxt>5, NULL);
1578                  }
1579                ;
1580
1581 /* SUBN.ANCE */
1582 subn_ance_sect : OPEN DELIM TAG_ANCE mand_line_item            
1583                  { $<ctxt>$ = start_element(ELT_SUBN_ANCE,
1584                                             PARENT, $1, $3, $4, 
1585                                             GEDCOM_MAKE_STRING($4));
1586                    START(ANCE, $<ctxt>$)             
1587                  }             
1588                  no_std_subs             
1589                  { CHECK0 }             
1590                  CLOSE             
1591                  { end_element(ELT_SUBN_ANCE, PARENT, $<ctxt>5, NULL);
1592                  }
1593                ;
1594
1595 /* SUBN.DESC */
1596 subn_desc_sect : OPEN DELIM TAG_DESC mand_line_item            
1597                  { $<ctxt>$ = start_element(ELT_SUBN_DESC,
1598                                             PARENT, $1, $3, $4, 
1599                                             GEDCOM_MAKE_STRING($4));
1600                    START(DESC, $<ctxt>$)             
1601                  }             
1602                  no_std_subs             
1603                  { CHECK0 }             
1604                  CLOSE             
1605                  { end_element(ELT_SUBN_DESC, PARENT, $<ctxt>5, NULL);
1606                  }
1607                ;
1608
1609 /* SUBN.ORDI */
1610 subn_ordi_sect : OPEN DELIM TAG_ORDI mand_line_item            
1611                  { $<ctxt>$ = start_element(ELT_SUBN_ORDI,
1612                                             PARENT, $1, $3, $4, 
1613                                             GEDCOM_MAKE_STRING($4));
1614                    START(ORDI, $<ctxt>$)             
1615                  }             
1616                  no_std_subs             
1617                  { CHECK0 }             
1618                  CLOSE             
1619                  { end_element(ELT_SUBN_ORDI, PARENT, $<ctxt>5, NULL);
1620                  }
1621                ;
1622
1623 /* SUBN.RIN */
1624 subn_rin_sect  : OPEN DELIM TAG_RIN mand_line_item            
1625                  { $<ctxt>$ = start_element(ELT_SUBN_RIN,
1626                                             PARENT, $1, $3, $4, 
1627                                             GEDCOM_MAKE_STRING($4));
1628                    START(RIN, $<ctxt>$)             
1629                  }             
1630                  no_std_subs             
1631                  { CHECK0 }             
1632                  CLOSE             
1633                  { end_element(ELT_SUBN_RIN, PARENT, $<ctxt>5, NULL);
1634                  }
1635                ;
1636
1637 /*********************************************************************/
1638 /**** Submitter record                                            ****/
1639 /*********************************************************************/
1640 submit_rec : OPEN DELIM POINTER DELIM TAG_SUBM    
1641              { $<ctxt>$ = start_record(REC_SUBM, $1, $3, $5);
1642                 START(SUBM, $<ctxt>$) }
1643              subm_subs
1644              { CHECK1(NAME) }
1645              CLOSE
1646              { end_record(REC_SUBM, $<ctxt>6); }
1647            ;
1648
1649 subm_subs  : /* empty */
1650            | subm_subs subm_sub
1651            ;
1652
1653 subm_sub   : subm_name_sect  { OCCUR2(NAME, 0, 1) }
1654            | addr_struc_sub  /* 0:1 */
1655            | multim_link_sub  /* 0:M */
1656            | subm_lang_sect  { OCCUR2(LANG, 0, 3) }
1657            | subm_rfn_sect  { OCCUR2(RFN, 0, 1) }
1658            | subm_rin_sect  { OCCUR2(RIN, 0, 1) }
1659            | change_date_sub  /* 0:1 */
1660            | no_std_sub
1661            ;
1662
1663 /* SUBM.NAME */
1664 subm_name_sect : OPEN DELIM TAG_NAME mand_line_item             
1665                  { $<ctxt>$ = start_element(ELT_SUBM_NAME,
1666                                             PARENT, $1, $3, $4, 
1667                                             GEDCOM_MAKE_STRING($4));
1668                    START(NAME, $<ctxt>$)              
1669                  }              
1670                  no_std_subs              
1671                  { CHECK0 }              
1672                  CLOSE              
1673                  { end_element(ELT_SUBM_NAME, PARENT, $<ctxt>5, NULL);
1674                  }
1675                ;
1676
1677 /* SUBM.LANG */
1678 subm_lang_sect : OPEN DELIM TAG_LANG mand_line_item             
1679                  { $<ctxt>$ = start_element(ELT_SUBM_LANG,
1680                                             PARENT, $1, $3, $4, 
1681                                             GEDCOM_MAKE_STRING($4));
1682                    START(LANG, $<ctxt>$)              
1683                  }              
1684                  no_std_subs              
1685                  { CHECK0 }              
1686                  CLOSE              
1687                  { end_element(ELT_SUBM_LANG, PARENT, $<ctxt>5, NULL);
1688                  }
1689                ;
1690
1691 /* SUBM.RFN */
1692 subm_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item             
1693                  { $<ctxt>$ = start_element(ELT_SUBM_RFN,
1694                                             PARENT, $1, $3, $4, 
1695                                             GEDCOM_MAKE_STRING($4));
1696                    START(RFN, $<ctxt>$)              
1697                  }              
1698                  no_std_subs              
1699                  { CHECK0 }              
1700                  CLOSE              
1701                  { end_element(ELT_SUBM_RFN, PARENT, $<ctxt>5, NULL);
1702                  }
1703                ;
1704
1705 /* SUBM.RIN */
1706 subm_rin_sect  : OPEN DELIM TAG_RIN mand_line_item             
1707                  { $<ctxt>$ = start_element(ELT_SUBM_RIN,
1708                                             PARENT, $1, $3, $4, 
1709                                             GEDCOM_MAKE_STRING($4));
1710                    START(RIN, $<ctxt>$)              
1711                  }              
1712                  no_std_subs              
1713                  { CHECK0 }              
1714                  CLOSE              
1715                  { end_element(ELT_SUBM_RIN, PARENT, $<ctxt>5, NULL);
1716                  }
1717                ;
1718
1719 /*********************************************************************/
1720 /**** Substructures                                               ****/
1721 /*********************************************************************/
1722
1723 /* ADDRESS STRUCTURE */
1724 addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) }
1725                | phon_sect { OCCUR2(PHON, 0, 3) }
1726                ;
1727
1728 addr_sect   : OPEN DELIM TAG_ADDR mand_line_item 
1729               { $<ctxt>$ = start_element(ELT_SUB_ADDR,
1730                                          PARENT, $1, $3, $4, 
1731                                          GEDCOM_MAKE_STRING($4));
1732                 START(ADDR, $<ctxt>$)  
1733               }
1734               addr_subs
1735               { CHECK0 }
1736               CLOSE  
1737               { end_element(ELT_SUB_ADDR, PARENT, $<ctxt>5, NULL);
1738               }
1739             ;
1740
1741 addr_subs   : /* empty */
1742             | addr_subs addr_sub
1743             ;
1744
1745 addr_sub    : addr_cont_sect  /* 0:M */
1746             | addr_adr1_sect  { OCCUR2(ADR1, 0, 1) }
1747             | addr_adr2_sect  { OCCUR2(ADR2, 0, 1) }
1748             | addr_city_sect  { OCCUR2(CITY, 0, 1) }
1749             | addr_stae_sect  { OCCUR2(STAE, 0, 1) }
1750             | addr_post_sect  { OCCUR2(POST, 0, 1) }
1751             | addr_ctry_sect  { OCCUR2(CTRY, 0, 1) }
1752             | no_std_sub
1753             ;
1754
1755 addr_cont_sect : OPEN DELIM TAG_CONT mand_line_item              
1756                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_CONT,
1757                                             PARENT, $1, $3, $4, 
1758                                             GEDCOM_MAKE_STRING($4));
1759                    START(CONT, $<ctxt>$)               
1760                  }               
1761                  no_std_subs               
1762                  { CHECK0 }               
1763                  CLOSE               
1764                  { end_element(ELT_SUB_ADDR_CONT, PARENT, $<ctxt>5, NULL);
1765                  }
1766                ;
1767 addr_adr1_sect : OPEN DELIM TAG_ADR1 mand_line_item              
1768                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_ADR1,
1769                                             PARENT, $1, $3, $4, 
1770                                             GEDCOM_MAKE_STRING($4));
1771                    START(ADR1, $<ctxt>$)               
1772                  }               
1773                  no_std_subs               
1774                  { CHECK0 }               
1775                  CLOSE               
1776                  { end_element(ELT_SUB_ADDR_ADR1, PARENT, $<ctxt>5, NULL);
1777                  }
1778                ;
1779 addr_adr2_sect : OPEN DELIM TAG_ADR2 mand_line_item              
1780                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_ADR2,
1781                                             PARENT, $1, $3, $4, 
1782                                             GEDCOM_MAKE_STRING($4));
1783                    START(ADR2, $<ctxt>$)               
1784                  }               
1785                  no_std_subs               
1786                  { CHECK0 }               
1787                  CLOSE               
1788                  { end_element(ELT_SUB_ADDR_ADR2, PARENT, $<ctxt>5, NULL);
1789                  }
1790                ;
1791 addr_city_sect : OPEN DELIM TAG_CITY mand_line_item              
1792                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_CITY,
1793                                             PARENT, $1, $3, $4, 
1794                                             GEDCOM_MAKE_STRING($4));
1795                    START(CITY, $<ctxt>$)               
1796                  }               
1797                  no_std_subs               
1798                  { CHECK0 }               
1799                  CLOSE               
1800                  { end_element(ELT_SUB_ADDR_CITY, PARENT, $<ctxt>5, NULL);
1801                  }
1802                ;
1803 addr_stae_sect : OPEN DELIM TAG_STAE mand_line_item              
1804                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_STAE,
1805                                             PARENT, $1, $3, $4, 
1806                                             GEDCOM_MAKE_STRING($4));
1807                    START(STAE, $<ctxt>$)               
1808                  }               
1809                  no_std_subs               
1810                  { CHECK0 }               
1811                  CLOSE               
1812                  { end_element(ELT_SUB_ADDR_STAE, PARENT, $<ctxt>5, NULL);
1813                  }
1814                ;
1815 addr_post_sect : OPEN DELIM TAG_POST mand_line_item              
1816                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_POST,
1817                                             PARENT, $1, $3, $4, 
1818                                             GEDCOM_MAKE_STRING($4));
1819                    START(POST, $<ctxt>$)               
1820                  }               
1821                  no_std_subs               
1822                  { CHECK0 }               
1823                  CLOSE               
1824                  { end_element(ELT_SUB_ADDR_POST, PARENT, $<ctxt>5, NULL);
1825                  }
1826                ;
1827 addr_ctry_sect : OPEN DELIM TAG_CTRY mand_line_item              
1828                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_CTRY,
1829                                             PARENT, $1, $3, $4, 
1830                                             GEDCOM_MAKE_STRING($4));
1831                    START(CTRY, $<ctxt>$)               
1832                  }               
1833                  no_std_subs               
1834                  { CHECK0 }               
1835                  CLOSE               
1836                  { end_element(ELT_SUB_ADDR_CTRY, PARENT, $<ctxt>5, NULL);
1837                  }
1838                ;
1839
1840 phon_sect   : OPEN DELIM TAG_PHON mand_line_item              
1841               { $<ctxt>$ = start_element(ELT_SUB_PHON,
1842                                          PARENT, $1, $3, $4, 
1843                                          GEDCOM_MAKE_STRING($4));
1844                 START(PHON, $<ctxt>$)               
1845               }               
1846               no_std_subs               
1847               { CHECK0 }               
1848               CLOSE               
1849               { end_element(ELT_SUB_PHON, PARENT, $<ctxt>5, NULL);
1850               }
1851             ;
1852
1853 /* ASSOCIATION STRUCTURE */
1854 assoc_struc_sub : asso_sect /* 0:M */
1855                 ;
1856
1857 asso_sect : OPEN DELIM TAG_ASSO mand_pointer
1858             { $<ctxt>$ = start_element(ELT_SUB_ASSO,
1859                                        PARENT, $1, $3, $4, 
1860                                        GEDCOM_MAKE_STRING($4));
1861               START(ASSO, $<ctxt>$) 
1862             }
1863             asso_subs
1864             { CHECK2(TYPE,RELA) }
1865             CLOSE 
1866             { end_element(ELT_SUB_ASSO, PARENT, $<ctxt>5, NULL);
1867             }
1868           ;
1869
1870 asso_subs : /* empty */
1871           | asso_type_sect  { OCCUR2(TYPE, 1, 1) }
1872           | asso_rela_sect  { OCCUR2(RELA, 1, 1) }
1873           | note_struc_sub
1874           | source_cit_sub
1875           | no_std_sub
1876           ;
1877
1878 asso_type_sect : OPEN DELIM TAG_TYPE mand_line_item               
1879                  { $<ctxt>$ = start_element(ELT_SUB_ASSO_TYPE,
1880                                             PARENT, $1, $3, $4, 
1881                                             GEDCOM_MAKE_STRING($4));
1882                    START(TYPE, $<ctxt>$)                
1883                  }                
1884                  no_std_subs                
1885                  { CHECK0 }                
1886                  CLOSE                
1887                  { end_element(ELT_SUB_ASSO_TYPE, PARENT, $<ctxt>5, NULL);
1888                  }
1889                ;
1890
1891 asso_rela_sect : OPEN DELIM TAG_RELA mand_line_item               
1892                  { $<ctxt>$ = start_element(ELT_SUB_ASSO_RELA,
1893                                             PARENT, $1, $3, $4, 
1894                                             GEDCOM_MAKE_STRING($4));
1895                    START(RELA, $<ctxt>$)                
1896                  }                
1897                  no_std_subs                
1898                  { CHECK0 }                
1899                  CLOSE                
1900                  { end_element(ELT_SUB_ASSO_RELA, PARENT, $<ctxt>5, NULL);
1901                  }
1902                ;
1903
1904 /* CHANGE DATE */
1905 change_date_sub : change_date_chan_sect  { OCCUR2(CHAN, 0, 1) }
1906                 ;
1907
1908 change_date_chan_sect : OPEN DELIM TAG_CHAN
1909                         { $<ctxt>$ = start_element(ELT_SUB_CHAN,
1910                                                    PARENT, $1, $3, NULL, 
1911                                                    GEDCOM_MAKE_NULL());
1912                           START(CHAN, $<ctxt>$) 
1913                         }
1914                         change_date_chan_subs
1915                         { CHECK1(DATE) }
1916                         CLOSE 
1917                         { end_element(ELT_SUB_CHAN, PARENT, $<ctxt>4, NULL);
1918                         }
1919                       ;
1920
1921 change_date_chan_subs : /* empty */
1922                       | change_date_chan_subs change_date_chan_sub
1923                       ;
1924
1925 change_date_chan_sub  : change_date_date_sect  { OCCUR2(DATE, 1, 1) }
1926                       | note_struc_sub
1927                       | no_std_sub
1928                       ;
1929
1930 change_date_date_sect : OPEN DELIM TAG_DATE mand_line_item 
1931                         { struct date_value dv = gedcom_parse_date($4);
1932                           $<ctxt>$ = start_element(ELT_SUB_CHAN_DATE,
1933                                                    PARENT, $1, $3, $4, 
1934                                                    GEDCOM_MAKE_DATE(dv));
1935                           START(DATE, $<ctxt>$) }
1936                         change_date_date_subs
1937                         { CHECK0 }
1938                         CLOSE 
1939                         { end_element(ELT_SUB_CHAN_DATE, PARENT, $<ctxt>5,
1940                                       NULL);
1941                         }
1942                       ;
1943
1944 change_date_date_subs : /* empty */
1945                       | change_date_date_subs change_date_date_sub
1946                       ;
1947
1948 change_date_date_sub : change_date_date_time_sect  { OCCUR2(TIME, 0, 1) }
1949                      | no_std_sub
1950                      ;
1951
1952 change_date_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
1953                              { $<ctxt>$
1954                                  = start_element(ELT_SUB_CHAN_TIME,
1955                                                  PARENT, $1, $3, $4, 
1956                                                  GEDCOM_MAKE_STRING($4));
1957                                START(TIME, $<ctxt>$) 
1958                              } 
1959                              no_std_subs 
1960                              { CHECK0 } 
1961                              CLOSE 
1962                              { end_element(ELT_SUB_CHAN_TIME, PARENT, $<ctxt>5,
1963                                            NULL);
1964                              }
1965                            ;
1966
1967 /* CHILD TO FAMILY LINK */
1968 chi_fam_link_sub : famc_sect  /* 0:M */
1969                  ;
1970
1971 famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1972             { $<ctxt>$ = start_element(ELT_SUB_FAMC,
1973                                        PARENT, $1, $3, $4, 
1974                                        GEDCOM_MAKE_STRING($4));
1975               START(FAMC, $<ctxt>$) 
1976             }
1977             famc_subs
1978             { CHECK0 }
1979             CLOSE 
1980             { end_element(ELT_SUB_FAMC, PARENT, $<ctxt>5, NULL);
1981             }
1982           ;
1983
1984 famc_subs : /* empty */
1985           | famc_subs famc_sub
1986           ;
1987
1988 famc_sub  : famc_pedi_sect  /* 0:M */
1989           | note_struc_sub
1990           | no_std_sub
1991           ;
1992
1993 famc_pedi_sect : OPEN DELIM TAG_PEDI mand_line_item 
1994                  { $<ctxt>$ = start_element(ELT_SUB_FAMC_PEDI,
1995                                             PARENT, $1, $3, $4, 
1996                                             GEDCOM_MAKE_STRING($4));
1997                    START(PEDI, $<ctxt>$)  
1998                  }  
1999                  no_std_subs  
2000                  { CHECK0 }  
2001                  CLOSE  
2002                  { end_element(ELT_SUB_FAMC_PEDI, PARENT, $<ctxt>5, NULL);
2003                  }
2004                ;
2005
2006 /* CONTINUATION SUBSECTIONS */
2007 continuation_sub : cont_sect  /* 0:M */
2008                  | conc_sect  /* 0:M */
2009                  ;
2010
2011 cont_sect : OPEN DELIM TAG_CONT mand_line_item 
2012             { $<ctxt>$ = start_element(ELT_SUB_CONT,
2013                                        PARENT, $1, $3, $4, 
2014                                        GEDCOM_MAKE_STRING($4));
2015               START(CONT, $<ctxt>$)  
2016             }  
2017             no_std_subs  
2018             { CHECK0 }  
2019             CLOSE  
2020             { end_element(ELT_SUB_CONT, PARENT, $<ctxt>5, NULL);
2021             }
2022           ;
2023
2024 conc_sect : OPEN DELIM TAG_CONC mand_line_item 
2025             { $<ctxt>$ = start_element(ELT_SUB_CONC,
2026                                        PARENT, $1, $3, $4, 
2027                                        GEDCOM_MAKE_STRING($4));
2028               START(CONC, $<ctxt>$)  
2029             }  
2030             no_std_subs  
2031             { CHECK0 }  
2032             CLOSE  
2033             { end_element(ELT_SUB_CONC, PARENT, $<ctxt>5, NULL);
2034             }
2035           ; 
2036
2037 /* EVENT DETAIL */
2038 event_detail_sub : event_detail_type_sect  { OCCUR2(TYPE, 0, 1) }
2039                  | event_detail_date_sect  { OCCUR2(DATE, 0, 1) }
2040                  | place_struc_sub
2041                  | addr_struc_sub
2042                  | event_detail_age_sect  { OCCUR2(AGE, 0, 1) }
2043                  | event_detail_agnc_sect  { OCCUR2(AGNC, 0, 1) }
2044                  | event_detail_caus_sect  { OCCUR2(CAUS, 0, 1) }
2045                  | source_cit_sub
2046                  | multim_link_sub
2047                  | note_struc_sub
2048                  ;
2049
2050 event_detail_type_sect : OPEN DELIM TAG_TYPE mand_line_item 
2051                          { $<ctxt>$ = start_element(ELT_SUB_EVT_TYPE,
2052                                                     PARENT, $1, $3, $4, 
2053                                                     GEDCOM_MAKE_STRING($4));
2054                            START(TYPE, $<ctxt>$)  
2055                          }  
2056                          no_std_subs  
2057                          { CHECK0 }  
2058                          CLOSE  
2059                          { end_element(ELT_SUB_EVT_TYPE, PARENT, $<ctxt>5,
2060                                        NULL);
2061                          }
2062                        ;
2063 event_detail_date_sect : OPEN DELIM TAG_DATE mand_line_item 
2064                          { struct date_value dv = gedcom_parse_date($4);
2065                            $<ctxt>$ = start_element(ELT_SUB_EVT_DATE,
2066                                                     PARENT, $1, $3, $4, 
2067                                                     GEDCOM_MAKE_DATE(dv));
2068                            START(DATE, $<ctxt>$)  
2069                          }  
2070                          no_std_subs  
2071                          { CHECK0 }  
2072                          CLOSE  
2073                          { end_element(ELT_SUB_EVT_DATE, PARENT, $<ctxt>5,
2074                                        NULL);
2075                          }
2076                        ;
2077 event_detail_age_sect  : OPEN DELIM TAG_AGE mand_line_item 
2078                          { $<ctxt>$ = start_element(ELT_SUB_EVT_AGE,
2079                                                     PARENT, $1, $3, $4, 
2080                                                     GEDCOM_MAKE_STRING($4));
2081                            START(AGE, $<ctxt>$)  
2082                          }  
2083                          no_std_subs  
2084                          { CHECK0 }  
2085                          CLOSE  
2086                          { end_element(ELT_SUB_EVT_AGE, PARENT, $<ctxt>5,
2087                                        NULL);
2088                          }
2089                        ;
2090 event_detail_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item 
2091                          { $<ctxt>$ = start_element(ELT_SUB_EVT_AGNC,
2092                                                     PARENT, $1, $3, $4, 
2093                                                     GEDCOM_MAKE_STRING($4));
2094                            START(AGNC, $<ctxt>$)  
2095                          }  
2096                          no_std_subs  
2097                          { CHECK0 }  
2098                          CLOSE  
2099                          { end_element(ELT_SUB_EVT_AGNC, PARENT, $<ctxt>5,
2100                                        NULL);
2101                          }
2102                        ;
2103 event_detail_caus_sect : OPEN DELIM TAG_CAUS mand_line_item 
2104                          { $<ctxt>$ = start_element(ELT_SUB_EVT_CAUS,
2105                                                     PARENT, $1, $3, $4, 
2106                                                     GEDCOM_MAKE_STRING($4));
2107                            START(CAUS, $<ctxt>$)  
2108                          }  
2109                          no_std_subs  
2110                          { CHECK0 }  
2111                          CLOSE  
2112                          { end_element(ELT_SUB_EVT_CAUS, PARENT, $<ctxt>5,
2113                                        NULL);
2114                          }
2115                        ;
2116
2117 /* FAMILY EVENT STRUCTURE */
2118 fam_event_struc_sub : fam_event_sect
2119                     | fam_gen_even_sect  /* 0:M */
2120                     ;
2121
2122 fam_event_sect : OPEN DELIM fam_event_tag opt_value  
2123                  { 
2124                    $<ctxt>$ = start_element(ELT_SUB_FAM_EVT,
2125                                             PARENT, $1, $3, $4,
2126                                             GEDCOM_MAKE_NULL_OR_STRING($4));
2127                    /* set the parent context separately from START here */
2128                    set_parentctxt($<ctxt>$);
2129                  }
2130                  fam_event_subs
2131                  { CHECK0 }
2132                  CLOSE 
2133                  { end_element(ELT_SUB_FAM_EVT, PARENT, $<ctxt>5, NULL);
2134                  }
2135                ;
2136
2137 fam_event_tag : TAG_ANUL { $$ = $1; START(ANUL, NULL) }
2138               | TAG_CENS { $$ = $1; START(CENS, NULL) }
2139               | TAG_DIV { $$ = $1; START(DIV, NULL) }
2140               | TAG_DIVF { $$ = $1; START(DIVF, NULL) }
2141               | TAG_ENGA { $$ = $1; START(ENGA, NULL) }
2142               | TAG_MARR { $$ = $1; START(MARR, NULL) }
2143               | TAG_MARB { $$ = $1; START(MARB, NULL) }
2144               | TAG_MARC { $$ = $1; START(MARC, NULL) }
2145               | TAG_MARL { $$ = $1; START(MARL, NULL) }
2146               | TAG_MARS { $$ = $1; START(MARS, NULL) }
2147               ;
2148
2149 fam_event_subs : /* empty */
2150                | fam_event_subs fam_event_sub
2151                ;
2152
2153 fam_event_sub : event_detail_sub
2154               | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
2155               | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
2156               | no_std_sub
2157               ;
2158
2159 fam_even_husb_sect : OPEN DELIM TAG_HUSB
2160                      { $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_HUSB,
2161                                                 PARENT, $1, $3, NULL,
2162                                                 GEDCOM_MAKE_NULL());
2163                        START(HUSB, $<ctxt>$) 
2164                      }
2165                      fam_even_husb_subs
2166                      { CHECK1(AGE) }
2167                      CLOSE 
2168                      { end_element(ELT_SUB_FAM_EVT_HUSB, PARENT, $<ctxt>4,
2169                                    NULL);
2170                      }
2171                    ;
2172
2173 fam_even_husb_subs : /* empty */
2174                    | fam_even_husb_subs fam_even_husb_sub
2175                    ;
2176
2177 fam_even_husb_sub : fam_even_age_sect  { OCCUR2(AGE, 1, 1) }
2178                   | no_std_sub
2179                   ;
2180
2181 fam_even_age_sect : OPEN DELIM TAG_AGE mand_line_item  
2182                     { $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_AGE,
2183                                                PARENT, $1, $3, $4,
2184                                                GEDCOM_MAKE_STRING($4));
2185                       START(AGE, $<ctxt>$)   
2186                     }   
2187                     no_std_subs   
2188                     { CHECK0 }   
2189                     CLOSE   
2190                     { end_element(ELT_SUB_FAM_EVT_AGE, PARENT, $<ctxt>5,
2191                                   NULL);
2192                     }
2193                   ;
2194
2195 fam_even_wife_sect : OPEN DELIM TAG_WIFE
2196                      { $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_WIFE,
2197                                                 PARENT, $1, $3, NULL,
2198                                                 GEDCOM_MAKE_NULL());
2199                        START(WIFE, $<ctxt>$) 
2200                      }
2201                      fam_even_husb_subs
2202                      { CHECK1(AGE) }
2203                      CLOSE 
2204                      { end_element(ELT_SUB_FAM_EVT_WIFE, PARENT, $<ctxt>4,
2205                                    NULL);
2206                      }
2207                    ;
2208
2209 fam_gen_even_sect : OPEN DELIM TAG_EVEN
2210                     { $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_EVEN,
2211                                                 PARENT, $1, $3, NULL,
2212                                                 GEDCOM_MAKE_NULL());
2213                        START(EVEN, $<ctxt>$) 
2214                     }
2215                     fam_gen_even_subs
2216                     { CHECK0 }
2217                     CLOSE 
2218                     { end_element(ELT_SUB_FAM_EVT_EVEN, PARENT, $<ctxt>4,
2219                                   NULL);
2220                     }
2221                   ;
2222
2223 fam_gen_even_subs : /* empty */
2224                   | fam_gen_even_subs fam_gen_even_sub
2225                   ;
2226
2227 fam_gen_even_sub : event_detail_sub
2228                  | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
2229                  | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
2230                  | no_std_sub
2231                  ;
2232
2233 /* IDENTIFICATION STRUCTURE */
2234 ident_struc_sub : ident_refn_sect  /* 0:M */
2235                 | ident_rin_sect  { OCCUR2(RIN, 0, 1) }
2236                 ;
2237
2238 ident_refn_sect : OPEN DELIM TAG_REFN mand_line_item 
2239                   { $<ctxt>$ = start_element(ELT_SUB_IDENT_REFN,
2240                                              PARENT, $1, $3, $4,
2241                                              GEDCOM_MAKE_STRING($4));
2242                     START(REFN, $<ctxt>$)  
2243                   }
2244                   ident_refn_subs
2245                   { CHECK0 }
2246                   CLOSE  
2247                   { end_element(ELT_SUB_IDENT_REFN, PARENT, $<ctxt>5,
2248                                 NULL);
2249                   }
2250                 ;
2251
2252 ident_refn_subs : /* empty */
2253                 | ident_refn_subs ident_refn_sub
2254                 ;
2255
2256 ident_refn_sub  : ident_refn_type_sect  { OCCUR2(TYPE, 0, 1) }
2257                 | no_std_sub
2258                 ;
2259
2260 ident_refn_type_sect : OPEN DELIM TAG_TYPE mand_line_item   
2261                        { $<ctxt>$ = start_element(ELT_SUB_IDENT_REFN_TYPE,
2262                                                   PARENT, $1, $3, $4,
2263                                                   GEDCOM_MAKE_STRING($4));
2264                          START(TYPE, $<ctxt>$)    
2265                        }    
2266                        no_std_subs    
2267                        { CHECK0 }    
2268                        CLOSE    
2269                        { end_element(ELT_SUB_IDENT_REFN_TYPE, PARENT, $<ctxt>5,
2270                                      NULL);
2271                        }
2272                      ;
2273
2274 ident_rin_sect  : OPEN DELIM TAG_RIN mand_line_item   
2275                   { $<ctxt>$ = start_element(ELT_SUB_IDENT_RIN,
2276                                              PARENT, $1, $3, $4,
2277                                              GEDCOM_MAKE_STRING($4));
2278                     START(RIN, $<ctxt>$)    
2279                   }    
2280                   no_std_subs    
2281                   { CHECK0 }    
2282                   CLOSE    
2283                   { end_element(ELT_SUB_IDENT_RIN, PARENT, $<ctxt>5,
2284                                 NULL);
2285                   }
2286                 ;
2287
2288 /* INDIVIDUAL ATTRIBUTE STRUCTURE */
2289 indiv_attr_struc_sub : indiv_attr_sect   /* 0:M */
2290                      | indiv_resi_sect  /* 0:M */
2291                      ;
2292
2293 indiv_attr_sect : OPEN DELIM indiv_attr_tag mand_line_item
2294                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_ATTR,
2295                                              PARENT, $1, $3, $4,
2296                                              GEDCOM_MAKE_STRING($4));
2297                     /* set the parent context separately from START here */
2298                     set_parentctxt($<ctxt>$);
2299                   }
2300                   indiv_attr_event_subs
2301                   { CHECK0 }
2302                   CLOSE
2303                   { end_element(ELT_SUB_INDIV_ATTR, PARENT, $<ctxt>5, NULL);
2304                   }
2305
2306 indiv_attr_tag  : TAG_CAST { $$ = $1; START(CAST, NULL) }
2307                 | TAG_DSCR { $$ = $1; START(DSCR, NULL) }
2308                 | TAG_EDUC { $$ = $1; START(EDUC, NULL) }
2309                 | TAG_IDNO { $$ = $1; START(IDNO, NULL) }
2310                 | TAG_NATI { $$ = $1; START(NATI, NULL) }
2311                 | TAG_NCHI { $$ = $1; START(NCHI, NULL) }
2312                 | TAG_NMR  { $$ = $1; START(NMR, NULL) }
2313                 | TAG_OCCU { $$ = $1; START(OCCU, NULL) }
2314                 | TAG_PROP { $$ = $1; START(PROP, NULL) }
2315                 | TAG_RELI { $$ = $1; START(RELI, NULL) }
2316                 | TAG_SSN  { $$ = $1; START(SSN, NULL) }
2317                 | TAG_TITL { $$ = $1; START(TITL, NULL) }
2318
2319 indiv_resi_sect : OPEN DELIM TAG_RESI 
2320                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_RESI,
2321                                              PARENT, $1, $3, NULL,
2322                                              GEDCOM_MAKE_NULL());
2323                     START(RESI, $<ctxt>$)  
2324                   }
2325                   indiv_attr_event_subs 
2326                   { CHECK0 }
2327                   CLOSE  
2328                   { end_element(ELT_SUB_INDIV_RESI, PARENT, $<ctxt>4, NULL);
2329                   }
2330                 ;
2331
2332 indiv_attr_event_subs : /* empty */
2333                       | indiv_attr_event_subs indiv_attr_event_sub
2334                       ;
2335
2336 indiv_attr_event_sub  : event_detail_sub
2337                       | no_std_sub
2338                       ;
2339
2340 /* INDIVIDUAL EVENT STRUCTURE */
2341 indiv_even_struc_sub : indiv_birt_sect
2342                      | indiv_gen_sect
2343                      | indiv_adop_sect  /* 0:M */
2344                      | indiv_even_sect  /* 0:M */
2345                      ;
2346
2347 indiv_birt_sect : OPEN DELIM indiv_birt_tag opt_value 
2348                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_BIRT,
2349                                              PARENT, $1, $3, $4,
2350                                              GEDCOM_MAKE_NULL_OR_STRING($4));
2351                     /* set the parent context separately from START here */
2352                     set_parentctxt($<ctxt>$);
2353                   }
2354                   indiv_birt_subs
2355                   { CHECK0 }
2356                   CLOSE 
2357                   { end_element(ELT_SUB_INDIV_BIRT, PARENT, $<ctxt>5, NULL);
2358                   }
2359                 ;
2360
2361 indiv_birt_tag  : TAG_BIRT { $$ = $1; START(BIRT, NULL) }
2362                 | TAG_CHR { $$ = $1; START(CHR, NULL) }
2363                 ;
2364
2365 indiv_birt_subs : /* empty */
2366                 | indiv_birt_subs indiv_birt_sub
2367                 ;
2368
2369 indiv_birt_sub  : event_detail_sub
2370                 | indiv_birt_famc_sect  { OCCUR2(FAMC,0, 1) }
2371                 | no_std_sub
2372                 ;
2373
2374 indiv_birt_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2375                        { $<ctxt>$ = start_element(ELT_SUB_INDIV_BIRT_FAMC,
2376                                                   PARENT, $1, $3, $4,
2377                                                   GEDCOM_MAKE_STRING($4));
2378                          START(FAMC, $<ctxt>$) 
2379                        } 
2380                        no_std_subs 
2381                        { CHECK0 } 
2382                        CLOSE 
2383                        { end_element(ELT_SUB_INDIV_BIRT_FAMC, PARENT, $<ctxt>5,
2384                                      NULL);
2385                        }
2386                      ;
2387
2388 indiv_gen_sect  : OPEN DELIM indiv_gen_tag opt_value 
2389                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_GEN,
2390                                              PARENT, $1, $3, $4,
2391                                              GEDCOM_MAKE_NULL_OR_STRING($4));
2392                     /* set the parent context separately from START here */
2393                     set_parentctxt($<ctxt>$);
2394                   }
2395                   indiv_gen_subs
2396                   { CHECK0 }
2397                   CLOSE 
2398                   { end_element(ELT_SUB_INDIV_GEN, PARENT, $<ctxt>5, NULL);
2399                   }
2400                 ;
2401
2402 indiv_gen_tag   : TAG_DEAT { $$ = $1; START(DEAT, NULL) }
2403                 | TAG_BURI { $$ = $1; START(BURI, NULL) }
2404                 | TAG_CREM { $$ = $1; START(CREM, NULL) }
2405                 | TAG_BAPM { $$ = $1; START(BAPM, NULL) }
2406                 | TAG_BARM { $$ = $1; START(BARM, NULL) }
2407                 | TAG_BASM { $$ = $1; START(BASM, NULL) }
2408                 | TAG_BLES { $$ = $1; START(BLES, NULL) }
2409                 | TAG_CHRA { $$ = $1; START(CHRA, NULL) }
2410                 | TAG_CONF { $$ = $1; START(CONF, NULL) }
2411                 | TAG_FCOM { $$ = $1; START(FCOM, NULL) }
2412                 | TAG_ORDN { $$ = $1; START(ORDN, NULL) }
2413                 | TAG_NATU { $$ = $1; START(NATU, NULL) }
2414                 | TAG_EMIG { $$ = $1; START(EMIG, NULL) }
2415                 | TAG_IMMI { $$ = $1; START(IMMI, NULL) }
2416                 | TAG_CENS { $$ = $1; START(CENS, NULL) }
2417                 | TAG_PROB { $$ = $1; START(PROB, NULL) }
2418                 | TAG_WILL { $$ = $1; START(WILL, NULL) }
2419                 | TAG_GRAD { $$ = $1; START(GRAD, NULL) }
2420                 | TAG_RETI { $$ = $1; START(RETI, NULL) }
2421                 ;
2422
2423 indiv_gen_subs  : /* empty */
2424                 | indiv_gen_subs indiv_gen_sub
2425                 ;
2426
2427 indiv_gen_sub   : event_detail_sub
2428                 | no_std_sub
2429                 ;
2430
2431 indiv_adop_sect : OPEN DELIM TAG_ADOP opt_value 
2432                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_ADOP,
2433                                              PARENT, $1, $3, $4,
2434                                              GEDCOM_MAKE_NULL_OR_STRING($4));
2435                     START(ADOP, $<ctxt>$) }
2436                   indiv_adop_subs
2437                   { CHECK0 }
2438                   CLOSE 
2439                   { end_element(ELT_SUB_INDIV_ADOP, PARENT, $<ctxt>5, NULL);
2440                   }
2441                 ;
2442
2443 indiv_adop_subs : /* empty */
2444                 | indiv_adop_subs indiv_adop_sub
2445                 ;
2446
2447 indiv_adop_sub  : event_detail_sub
2448                 | indiv_adop_famc_sect  { OCCUR2(FAMC,0, 1) }
2449                 | no_std_sub
2450                 ;
2451
2452 indiv_adop_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2453                        { $<ctxt>$ = start_element(ELT_SUB_INDIV_ADOP_FAMC,
2454                                                   PARENT, $1, $3, $4,
2455                                                   GEDCOM_MAKE_STRING($4));
2456                          START(FAMC, $<ctxt>$) }
2457                        indiv_adop_famc_subs
2458                        { CHECK0 }
2459                        CLOSE 
2460                        { end_element(ELT_SUB_INDIV_ADOP_FAMC, PARENT, $<ctxt>5,
2461                                      NULL);
2462                        }
2463                      ;
2464
2465 indiv_adop_famc_subs : /* empty */
2466                      | indiv_adop_famc_subs indiv_adop_famc_sub
2467                      ;
2468
2469 indiv_adop_famc_sub  : indiv_adop_famc_adop_sect  { OCCUR2(ADOP,0, 1) }
2470                      | no_std_sub
2471                      ;
2472
2473 indiv_adop_famc_adop_sect : OPEN DELIM TAG_ADOP mand_line_item   
2474                             { $<ctxt>$
2475                                 = start_element(ELT_SUB_INDIV_ADOP_FAMC_ADOP,
2476                                                 PARENT, $1, $3, $4,
2477                                                 GEDCOM_MAKE_STRING($4));
2478                               START(ADOP, $<ctxt>$) }    
2479                             no_std_subs    
2480                             { CHECK0 }    
2481                             CLOSE    
2482                             { end_element(ELT_SUB_INDIV_ADOP_FAMC_ADOP,
2483                                           PARENT, $<ctxt>5, NULL);
2484                             }
2485                           ;
2486
2487 indiv_even_sect : OPEN DELIM TAG_EVEN
2488                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_EVEN,
2489                                              PARENT, $1, $3, NULL,
2490                                              GEDCOM_MAKE_NULL());
2491                     START(EVEN, $<ctxt>$) }
2492                   indiv_gen_subs
2493                   { CHECK0 }
2494                   CLOSE    
2495                   { end_element(ELT_SUB_INDIV_EVEN, PARENT, $<ctxt>4, NULL);
2496                   }
2497                 ;
2498
2499 /* LDS INDIVIDUAL ORDINANCE */
2500 lds_indiv_ord_sub : lio_bapl_sect  /* 0:M */
2501                   | lio_slgc_sect  /* 0:M */
2502                   ;
2503
2504 lio_bapl_sect : OPEN DELIM lio_bapl_tag 
2505                 { $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL,
2506                                            PARENT, $1, $3, NULL,
2507                                            GEDCOM_MAKE_NULL());
2508                   /* set the parent context separately from START here */
2509                   set_parentctxt($<ctxt>$);
2510                 }
2511                 lio_bapl_subs
2512                 { CHECK0 }
2513                 CLOSE 
2514                 { end_element(ELT_SUB_LIO_BAPL, PARENT, $<ctxt>4, NULL);
2515                 }
2516               ;
2517
2518 lio_bapl_tag  : TAG_BAPL { $$ = $1; START(BAPL, NULL) }
2519               | TAG_CONL { $$ = $1; START(CONL, NULL) }
2520               | TAG_ENDL { $$ = $1; START(ENDL, NULL) }
2521               ;
2522
2523 lio_bapl_subs : /* empty */
2524               | lio_bapl_subs lio_bapl_sub
2525               ;
2526
2527 lio_bapl_sub  : lio_bapl_stat_sect  { OCCUR2(STAT, 0, 1) }
2528               | lio_bapl_date_sect  { OCCUR2(DATE, 0, 1) }
2529               | lio_bapl_temp_sect  { OCCUR2(TEMP, 0, 1) }
2530               | lio_bapl_plac_sect  { OCCUR2(PLAC, 0, 1) }
2531               | source_cit_sub
2532               | note_struc_sub
2533               | no_std_sub
2534               ;
2535
2536 lio_bapl_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
2537                      { $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL_STAT,
2538                                                 PARENT, $1, $3, $4,
2539                                                 GEDCOM_MAKE_STRING($4));
2540                        START(STAT, $<ctxt>$)    
2541                      }    
2542                      no_std_subs    
2543                      { CHECK0 }    
2544                      CLOSE    
2545                      { end_element(ELT_SUB_LIO_BAPL_STAT, PARENT, $<ctxt>5,
2546                                    NULL);
2547                      }
2548                    ;
2549 lio_bapl_date_sect : OPEN DELIM TAG_DATE mand_line_item   
2550                      { struct date_value dv = gedcom_parse_date($4);
2551                        $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL_DATE,
2552                                                 PARENT, $1, $3, $4,
2553                                                 GEDCOM_MAKE_DATE(dv));
2554                        START(DATE, $<ctxt>$)    
2555                      }    
2556                      no_std_subs    
2557                      { CHECK0 }    
2558                      CLOSE    
2559                      { end_element(ELT_SUB_LIO_BAPL_DATE, PARENT, $<ctxt>5,
2560                                    NULL);
2561                      }
2562                    ;
2563 lio_bapl_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
2564                      { $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL_TEMP,
2565                                                 PARENT, $1, $3, $4,
2566                                                 GEDCOM_MAKE_STRING($4));
2567                        START(TEMP, $<ctxt>$)    
2568                      }    
2569                      no_std_subs    
2570                      { CHECK0 }    
2571                      CLOSE    
2572                      { end_element(ELT_SUB_LIO_BAPL_TEMP, PARENT, $<ctxt>5,
2573                                    NULL);
2574                      }
2575                    ;
2576 lio_bapl_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
2577                      { $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL_PLAC,
2578                                                 PARENT, $1, $3, $4,
2579                                                 GEDCOM_MAKE_STRING($4));
2580                        START(PLAC, $<ctxt>$)    
2581                      }    
2582                      no_std_subs    
2583                      { CHECK0 }    
2584                      CLOSE    
2585                      { end_element(ELT_SUB_LIO_BAPL_PLAC, PARENT, $<ctxt>5,
2586                                    NULL);
2587                      }
2588                    ;
2589
2590 lio_slgc_sect : OPEN DELIM TAG_SLGC
2591                 { $<ctxt>$ = start_element(ELT_SUB_LIO_SLGC,
2592                                            PARENT, $1, $3, NULL,
2593                                            GEDCOM_MAKE_NULL());
2594                   START(SLGC, $<ctxt>$) 
2595                 }
2596                 lio_slgc_subs
2597                 { CHECK1(FAMC) }
2598                 CLOSE 
2599                 { end_element(ELT_SUB_LIO_SLGC, PARENT, $<ctxt>4, NULL);
2600                 }
2601               ;
2602
2603 lio_slgc_subs : /* empty */
2604               | lio_slgc_subs lio_slgc_sub
2605               ;
2606
2607 lio_slgc_sub  : lio_bapl_sub
2608               | lio_slgc_famc_sect  { OCCUR2(FAMC, 1, 1) }
2609               ;
2610
2611 lio_slgc_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2612                      { $<ctxt>$ = start_element(ELT_SUB_LIO_SLGC_FAMC,
2613                                                 PARENT, $1, $3, $4,
2614                                                 GEDCOM_MAKE_STRING($4));
2615                        START(FAMC, $<ctxt>$) 
2616                      } 
2617                      no_std_subs 
2618                      { CHECK0 } 
2619                      CLOSE 
2620                      { end_element(ELT_SUB_LIO_SLGC_FAMC, PARENT, $<ctxt>5,
2621                                    NULL);
2622                      }
2623                    ;
2624
2625 /* LDS SPOUSE SEALING */
2626 lds_spouse_seal_sub : lss_slgs_sect
2627                     ;
2628
2629 lss_slgs_sect : OPEN DELIM TAG_SLGS
2630                 { $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS,
2631                                            PARENT, $1, $3, NULL,
2632                                            GEDCOM_MAKE_NULL());
2633                   START(SLGS, $<ctxt>$) }
2634                 lss_slgs_subs
2635                 { CHECK0 }
2636                 CLOSE 
2637                 { end_element(ELT_SUB_LIO_SLGC, PARENT, $<ctxt>4, NULL);
2638                 }
2639               ;
2640
2641 lss_slgs_subs : /* empty */
2642               | lss_slgs_subs lss_slgs_sub
2643               ;
2644
2645 lss_slgs_sub  : lss_slgs_stat_sect  { OCCUR2(STAT, 0, 1) }
2646               | lss_slgs_date_sect  { OCCUR2(DATE, 0, 1) }
2647               | lss_slgs_temp_sect  { OCCUR2(TEMP, 0, 1) }
2648               | lss_slgs_plac_sect  { OCCUR2(PLAC, 0, 1) }
2649               | source_cit_sub
2650               | note_struc_sub
2651               | no_std_sub
2652               ;
2653
2654 lss_slgs_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
2655                      { $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS_STAT,
2656                                                 PARENT, $1, $3, $4,
2657                                                 GEDCOM_MAKE_STRING($4));
2658                        START(STAT, $<ctxt>$)    
2659                      }    
2660                      no_std_subs    
2661                      { CHECK0 }    
2662                      CLOSE    
2663                      { end_element(ELT_SUB_LSS_SLGS_STAT, PARENT, $<ctxt>5,
2664                                    NULL);
2665                      }
2666                    ;
2667 lss_slgs_date_sect : OPEN DELIM TAG_DATE mand_line_item   
2668                      { struct date_value dv = gedcom_parse_date($4);
2669                        $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS_DATE,
2670                                                 PARENT, $1, $3, $4,
2671                                                 GEDCOM_MAKE_DATE(dv));
2672                        START(DATE, $<ctxt>$)    
2673                      }    
2674                      no_std_subs    
2675                      { CHECK0 }    
2676                      CLOSE    
2677                      { end_element(ELT_SUB_LSS_SLGS_DATE, PARENT, $<ctxt>5,
2678                                    NULL);
2679                      }
2680                    ;
2681 lss_slgs_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
2682                      { $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS_TEMP,
2683                                                 PARENT, $1, $3, $4,
2684                                                 GEDCOM_MAKE_STRING($4));
2685                        START(TEMP, $<ctxt>$)    
2686                      }    
2687                      no_std_subs    
2688                      { CHECK0 }    
2689                      CLOSE    
2690                      { end_element(ELT_SUB_LSS_SLGS_TEMP, PARENT, $<ctxt>5,
2691                                    NULL);
2692                      }
2693                    ;
2694 lss_slgs_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
2695                      { $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS_PLAC,
2696                                                 PARENT, $1, $3, $4,
2697                                                 GEDCOM_MAKE_STRING($4));
2698                        START(PLAC, $<ctxt>$)    
2699                      }    
2700                      no_std_subs    
2701                      { CHECK0 }    
2702                      CLOSE    
2703                      { end_element(ELT_SUB_LSS_SLGS_PLAC, PARENT, $<ctxt>5,
2704                                    NULL);
2705                      }
2706                    ;
2707
2708 /* MULTIMEDIA LINK */
2709 multim_link_sub : multim_obje_link_sect
2710                 | multim_obje_emb_sect
2711                 ;
2712
2713 multim_obje_link_sect : OPEN DELIM TAG_OBJE DELIM POINTER    
2714                         { $<ctxt>$ = start_element(ELT_SUB_MULTIM_OBJE,
2715                                                    PARENT, $1, $3, $5,
2716                                                    GEDCOM_MAKE_STRING($5));
2717                           START(OBJE, $<ctxt>$)     
2718                         }     
2719                         no_std_subs     
2720                         { CHECK0 }     
2721                         CLOSE     
2722                         { end_element(ELT_SUB_MULTIM_OBJE, PARENT, $<ctxt>6,
2723                                       NULL);
2724                         }
2725                       ;
2726
2727 multim_obje_emb_sect : OPEN DELIM TAG_OBJE
2728                        { $<ctxt>$ = start_element(ELT_SUB_MULTIM_OBJE,
2729                                                   PARENT, $1, $3, NULL,
2730                                                   GEDCOM_MAKE_NULL());
2731                          START(OBJE, $<ctxt>$) 
2732                        }
2733                        multim_obje_emb_subs
2734                        { CHECK2(FORM,FILE) }
2735                        CLOSE 
2736                        { end_element(ELT_SUB_MULTIM_OBJE, PARENT, $<ctxt>4,
2737                                      NULL);
2738                        }
2739                      ;
2740
2741 multim_obje_emb_subs : /* empty */
2742                      | multim_obje_emb_subs multim_obje_emb_sub
2743                      ;
2744
2745 multim_obje_emb_sub : multim_obje_form_sect  { OCCUR2(FORM, 1, 1) }
2746                     | multim_obje_titl_sect  { OCCUR2(TITL, 0, 1) }
2747                     | multim_obje_file_sect  { OCCUR2(FILE, 1, 1) }
2748                     | note_struc_sub
2749                     | no_std_sub
2750                     ;
2751
2752 multim_obje_form_sect : OPEN DELIM TAG_FORM mand_line_item    
2753                         { $<ctxt>$ = start_element(ELT_SUB_MULTIM_OBJE_FORM,
2754                                                    PARENT, $1, $3, $4,
2755                                                    GEDCOM_MAKE_STRING($4));
2756                           START(FORM, $<ctxt>$)     
2757                         }     
2758                         no_std_subs     
2759                         { CHECK0 }     
2760                         CLOSE     
2761                         { end_element(ELT_SUB_MULTIM_OBJE_FORM,
2762                                       PARENT, $<ctxt>5, NULL);
2763                         }
2764                       ;
2765 multim_obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item    
2766                         { $<ctxt>$ = start_element(ELT_SUB_MULTIM_OBJE_TITL,
2767                                                    PARENT, $1, $3, $4,
2768                                                    GEDCOM_MAKE_STRING($4));
2769                           START(TITL, $<ctxt>$)     
2770                         }     
2771                         no_std_subs     
2772                         { CHECK0 }     
2773                         CLOSE     
2774                         { end_element(ELT_SUB_MULTIM_OBJE_TITL,
2775                                       PARENT, $<ctxt>5, NULL);
2776                         }
2777                       ;
2778 multim_obje_file_sect : OPEN DELIM TAG_FILE mand_line_item    
2779                         { $<ctxt>$ = start_element(ELT_SUB_MULTIM_OBJE_FILE,
2780                                                    PARENT, $1, $3, $4,
2781                                                    GEDCOM_MAKE_STRING($4));
2782                           START(FILE, $<ctxt>$)     
2783                         }     
2784                         no_std_subs     
2785                         { CHECK0 }     
2786                         CLOSE     
2787                         { end_element(ELT_SUB_MULTIM_OBJE_FILE,
2788                                       PARENT, $<ctxt>5, NULL);
2789                         }
2790                       ;
2791
2792 /* NOTE STRUCTURE */
2793 note_struc_sub : note_struc_link_sect  /* 0:M */
2794                | note_struc_emb_sect  /* 0:M */
2795                ;
2796
2797 note_struc_link_sect : OPEN DELIM TAG_NOTE DELIM POINTER
2798                        { $<ctxt>$ = start_element(ELT_SUB_NOTE,
2799                                                   PARENT, $1, $3, $5,
2800                                                   GEDCOM_MAKE_STRING($5));
2801                          START(NOTE, $<ctxt>$) 
2802                        }
2803                        note_struc_link_subs
2804                        { CHECK0 }
2805                        CLOSE 
2806                        { end_element(ELT_SUB_NOTE, PARENT, $<ctxt>6, NULL);
2807                        }
2808                      ;
2809
2810 note_struc_link_subs : /* empty */
2811                      | note_struc_link_subs note_struc_link_sub
2812                      ;
2813
2814 note_struc_link_sub : source_cit_sub
2815                     | no_std_sub
2816                     ;
2817
2818 note_struc_emb_sect : OPEN DELIM TAG_NOTE opt_line_item
2819                       { $<ctxt>$
2820                           = start_element(ELT_SUB_NOTE,
2821                                           PARENT, $1, $3, $4,
2822                                           GEDCOM_MAKE_NULL_OR_STRING($4));
2823                         START(NOTE, $<ctxt>$) 
2824                       }
2825                       note_struc_emb_subs
2826                       { CHECK0 }
2827                       CLOSE 
2828                       { end_element(ELT_SUB_NOTE, PARENT, $<ctxt>5, NULL);
2829                       }
2830                     ;
2831
2832 note_struc_emb_subs : /* empty */
2833                     | note_struc_emb_subs note_struc_emb_sub
2834                     ;
2835
2836 note_struc_emb_sub  : continuation_sub
2837                     | source_cit_sub
2838                     | no_std_sub
2839                     ;
2840
2841 /* PERSONAL NAME STRUCTURE */
2842 pers_name_struc_sub : pers_name_sect /* 0:M */
2843                     ;
2844
2845 pers_name_sect : OPEN DELIM TAG_NAME mand_line_item 
2846                  { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME,
2847                                             PARENT, $1, $3, $4,
2848                                             GEDCOM_MAKE_STRING($4));
2849                    START(NAME, $<ctxt>$)  
2850                  }
2851                  pers_name_subs
2852                  { CHECK0 }
2853                  CLOSE  
2854                  { end_element(ELT_SUB_PERS_NAME, PARENT, $<ctxt>5, NULL);
2855                  }
2856                ;
2857
2858 pers_name_subs : /* empty */
2859                | pers_name_subs pers_name_sub
2860                ;
2861
2862 pers_name_sub  : pers_name_npfx_sect  { OCCUR2(NPFX, 0, 1) }
2863                | pers_name_givn_sect  { OCCUR2(GIVN, 0, 1) }
2864                | pers_name_nick_sect  { OCCUR2(NICK, 0, 1) }
2865                | pers_name_spfx_sect  { OCCUR2(SPFX, 0, 1) }
2866                | pers_name_surn_sect  { OCCUR2(SURN, 0, 1) }
2867                | pers_name_nsfx_sect  { OCCUR2(NSFX, 0, 1) }
2868                | source_cit_sub
2869                | note_struc_sub
2870                | no_std_sub
2871                ;
2872
2873 pers_name_npfx_sect : OPEN DELIM TAG_NPFX mand_line_item    
2874                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_NPFX,
2875                                                  PARENT, $1, $3, $4,
2876                                                  GEDCOM_MAKE_STRING($4));
2877                         START(NPFX, $<ctxt>$)     
2878                       }     
2879                       no_std_subs     
2880                       { CHECK0 }     
2881                       CLOSE     
2882                       { end_element(ELT_SUB_PERS_NAME_NPFX, PARENT, $<ctxt>5,
2883                                     NULL);
2884                       }
2885                     ;
2886 pers_name_givn_sect : OPEN DELIM TAG_GIVN mand_line_item    
2887                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_GIVN,
2888                                                  PARENT, $1, $3, $4,
2889                                                  GEDCOM_MAKE_STRING($4));
2890                         START(GIVN, $<ctxt>$)     
2891                       }     
2892                       no_std_subs     
2893                       { CHECK0 }     
2894                       CLOSE     
2895                       { end_element(ELT_SUB_PERS_NAME_GIVN, PARENT, $<ctxt>5,
2896                                     NULL);
2897                       }
2898                     ;
2899 pers_name_nick_sect : OPEN DELIM TAG_NICK mand_line_item    
2900                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_NICK,
2901                                                  PARENT, $1, $3, $4,
2902                                                  GEDCOM_MAKE_STRING($4));
2903                         START(NICK, $<ctxt>$)     
2904                       }     
2905                       no_std_subs     
2906                       { CHECK0 }     
2907                       CLOSE     
2908                       { end_element(ELT_SUB_PERS_NAME_NICK, PARENT, $<ctxt>5,
2909                                     NULL);
2910                       }
2911                     ;
2912 pers_name_spfx_sect : OPEN DELIM TAG_SPFX mand_line_item    
2913                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_SPFX,
2914                                                  PARENT, $1, $3, $4,
2915                                                  GEDCOM_MAKE_STRING($4));
2916                         START(SPFX, $<ctxt>$)     
2917                       }     
2918                       no_std_subs     
2919                       { CHECK0 }     
2920                       CLOSE     
2921                       { end_element(ELT_SUB_PERS_NAME_SPFX, PARENT, $<ctxt>5,
2922                                     NULL);
2923                       }
2924                     ;
2925 pers_name_surn_sect : OPEN DELIM TAG_SURN mand_line_item    
2926                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_SURN,
2927                                                  PARENT, $1, $3, $4,
2928                                                  GEDCOM_MAKE_STRING($4));
2929                         START(SURN, $<ctxt>$)     
2930                       }     
2931                       no_std_subs     
2932                       { CHECK0 }     
2933                       CLOSE     
2934                       { end_element(ELT_SUB_PERS_NAME_SURN, PARENT, $<ctxt>5,
2935                                     NULL);
2936                       }
2937                     ;
2938 pers_name_nsfx_sect : OPEN DELIM TAG_NSFX mand_line_item    
2939                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_NSFX,
2940                                                  PARENT, $1, $3, $4,
2941                                                  GEDCOM_MAKE_STRING($4));
2942                         START(NSFX, $<ctxt>$)     
2943                       }     
2944                       no_std_subs     
2945                       { CHECK0 }     
2946                       CLOSE     
2947                       { end_element(ELT_SUB_PERS_NAME_NSFX, PARENT, $<ctxt>5,
2948                                     NULL);
2949                       }
2950                     ;
2951
2952 /* PLACE STRUCTURE */
2953 place_struc_sub : place_struc_plac_sect /* 0:M */
2954                 ;
2955
2956 place_struc_plac_sect : OPEN DELIM TAG_PLAC mand_line_item 
2957                         { $<ctxt>$ = start_element(ELT_SUB_PLAC,
2958                                                    PARENT, $1, $3, $4,
2959                                                    GEDCOM_MAKE_STRING($4));
2960                           START(PLAC, $<ctxt>$)  
2961                         }
2962                         place_struc_plac_subs
2963                         { CHECK0 }
2964                         CLOSE  
2965                         { end_element(ELT_SUB_PLAC, PARENT, $<ctxt>5, NULL);
2966                         }
2967                       ;
2968
2969 place_struc_plac_subs : /* empty */
2970                       | place_struc_plac_subs place_struc_plac_sub
2971                       ;
2972
2973 place_struc_plac_sub : place_plac_form_sect  { OCCUR2(FORM, 0, 1) }
2974                      | source_cit_sub
2975                      | note_struc_sub
2976                      | no_std_sub
2977                      ;
2978
2979 place_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item    
2980                        { $<ctxt>$ = start_element(ELT_SUB_PLAC_FORM,
2981                                                   PARENT, $1, $3, $4,
2982                                                   GEDCOM_MAKE_STRING($4));
2983                          START(FORM, $<ctxt>$)     
2984                        }     
2985                        no_std_subs     
2986                        { CHECK0 }     
2987                        CLOSE     
2988                        { end_element(ELT_SUB_PLAC_FORM, PARENT, $<ctxt>5,
2989                                      NULL);
2990                        }
2991                      ;
2992
2993 /* SOURCE_CITATION */
2994 source_cit_sub : source_cit_link_sect /* 0:M */
2995                | source_cit_emb_sect /* 0:M */
2996                ;
2997
2998 source_cit_link_sect : OPEN DELIM TAG_SOUR DELIM POINTER
2999                        { $<ctxt>$ = start_element(ELT_SUB_SOUR,
3000                                                   PARENT, $1, $3, $5,
3001                                                   GEDCOM_MAKE_STRING($5));
3002                          START(SOUR, $<ctxt>$) 
3003                        }
3004                        source_cit_link_subs
3005                        { CHECK0 }
3006                        CLOSE 
3007                        { end_element(ELT_SUB_SOUR, PARENT, $<ctxt>6, NULL);
3008                        }
3009                      ;
3010
3011 source_cit_link_subs : /* empty */
3012                      | source_cit_link_subs source_cit_link_sub
3013                      ;
3014
3015 source_cit_link_sub : source_cit_page_sect  { OCCUR2(PAGE, 0, 1) }
3016                     | source_cit_even_sect  { OCCUR2(EVEN, 0, 1) }
3017                     | source_cit_data_sect  { OCCUR2(DATA, 0, 1) }
3018                     | source_cit_quay_sect  { OCCUR2(QUAY, 0, 1) }
3019                     | multim_link_sub
3020                     | note_struc_sub
3021                     | no_std_sub
3022                     ;
3023
3024 source_cit_page_sect : OPEN DELIM TAG_PAGE mand_line_item    
3025                        { $<ctxt>$ = start_element(ELT_SUB_SOUR_PAGE,
3026                                                   PARENT, $1, $3, $4,
3027                                                   GEDCOM_MAKE_STRING($4));
3028                          START(PAGE, $<ctxt>$)     
3029                        }     
3030                        no_std_subs     
3031                        { CHECK0 }     
3032                        CLOSE     
3033                        { end_element(ELT_SUB_SOUR_PAGE, PARENT, $<ctxt>5,
3034                                      NULL);
3035                        }
3036                      ;
3037
3038 source_cit_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
3039                        { $<ctxt>$ = start_element(ELT_SUB_SOUR_EVEN,
3040                                                   PARENT, $1, $3, $4,
3041                                                   GEDCOM_MAKE_STRING($4));
3042                          START(EVEN, $<ctxt>$)     
3043                        }
3044                        source_cit_even_subs
3045                        { CHECK0 }
3046                        CLOSE     
3047                        { end_element(ELT_SUB_SOUR_EVEN, PARENT, $<ctxt>5,
3048                                      NULL);
3049                        }
3050                      ;
3051
3052 source_cit_even_subs : /* empty */
3053                      | source_cit_even_subs source_cit_even_sub
3054                      ;
3055
3056 source_cit_even_sub  : source_cit_even_role_sect  { OCCUR2(ROLE, 0, 1) }
3057                      | no_std_sub
3058                      ;
3059
3060 source_cit_even_role_sect : OPEN DELIM TAG_ROLE mand_line_item    
3061                           { $<ctxt>$ = start_element(ELT_SUB_SOUR_EVEN_ROLE,
3062                                                      PARENT, $1, $3, $4,
3063                                                      GEDCOM_MAKE_STRING($4));
3064                             START(ROLE, $<ctxt>$)     
3065                           }     
3066                           no_std_subs     
3067                           { CHECK0 }     
3068                           CLOSE     
3069                           { end_element(ELT_SUB_SOUR_EVEN_ROLE,
3070                                         PARENT, $<ctxt>5, NULL);
3071                           }
3072                           ;
3073
3074 source_cit_data_sect : OPEN DELIM TAG_DATA
3075                        { $<ctxt>$ = start_element(ELT_SUB_SOUR_DATA,
3076                                                   PARENT, $1, $3, NULL,
3077                                                   GEDCOM_MAKE_NULL());
3078                          START(DATA, $<ctxt>$) 
3079                        }
3080                        source_cit_data_subs
3081                        { CHECK0 }
3082                        CLOSE 
3083                        { end_element(ELT_SUB_SOUR_DATA, PARENT, $<ctxt>4,
3084                                      NULL);
3085                        }
3086                      ;
3087
3088 source_cit_data_subs : /* empty */
3089                      | source_cit_data_subs source_cit_data_sub
3090                      ;
3091
3092 source_cit_data_sub : source_cit_data_date_sect  { OCCUR2(DATE, 0, 1) }
3093                     | source_cit_text_sect  /* 0:M */
3094                     | no_std_sub
3095                     ;
3096
3097 source_cit_data_date_sect : OPEN DELIM TAG_DATE mand_line_item    
3098                             { struct date_value dv = gedcom_parse_date($4);
3099                               $<ctxt>$ = start_element(ELT_SUB_SOUR_DATA_DATE,
3100                                                        PARENT, $1, $3, $4,
3101                                                        GEDCOM_MAKE_DATE(dv));
3102                               START(DATE, $<ctxt>$)     
3103                             }     
3104                             no_std_subs     
3105                             { CHECK0 }     
3106                             CLOSE     
3107                             { end_element(ELT_SUB_SOUR_DATA_DATE,
3108                                           PARENT, $<ctxt>5, NULL);
3109                             }
3110                           ;
3111
3112 source_cit_text_sect : OPEN DELIM TAG_TEXT mand_line_item 
3113                        { $<ctxt>$ = start_element(ELT_SUB_SOUR_TEXT,
3114                                                   PARENT, $1, $3, $4,
3115                                                   GEDCOM_MAKE_STRING($4));
3116                          START(TEXT, $<ctxt>$)  
3117                        }
3118                        source_cit_text_subs
3119                        { CHECK0 }
3120                        CLOSE  
3121                        { end_element(ELT_SUB_SOUR_TEXT, PARENT, $<ctxt>5,
3122                                      NULL);
3123                        }
3124                      ;
3125
3126 source_cit_text_subs : /* empty */
3127                      | source_cit_text_subs source_cit_text_sub
3128                      ;
3129
3130 source_cit_text_sub : continuation_sub
3131                     | no_std_sub
3132                     ;
3133
3134 source_cit_quay_sect : OPEN DELIM TAG_QUAY mand_line_item    
3135                        { $<ctxt>$ = start_element(ELT_SUB_SOUR_QUAY,
3136                                                   PARENT, $1, $3, $4,
3137                                                   GEDCOM_MAKE_STRING($4));
3138                          START(QUAY, $<ctxt>$)     
3139                        }     
3140                        no_std_subs     
3141                        { CHECK0 }     
3142                        CLOSE     
3143                        { end_element(ELT_SUB_SOUR_QUAY, PARENT, $<ctxt>5,
3144                                      NULL);
3145                        }
3146                      ;
3147
3148 source_cit_emb_sect : OPEN DELIM TAG_SOUR mand_line_item
3149                       { $<ctxt>$ = start_element(ELT_SUB_SOUR,
3150                                                  PARENT, $1, $3, $4,
3151                                                  GEDCOM_MAKE_STRING($4));
3152                         START(SOUR, $<ctxt>$) 
3153                       }
3154                       source_cit_emb_subs
3155                       { CHECK0 }
3156                       CLOSE 
3157                       { end_element(ELT_SUB_SOUR, PARENT, $<ctxt>5, NULL);
3158                       }
3159                     ;
3160
3161 source_cit_emb_subs : /* empty */
3162                     | source_cit_emb_subs source_cit_emb_sub
3163                     ;
3164
3165 source_cit_emb_sub : continuation_sub
3166                    | source_cit_text_sect  /* 0:M */
3167                    | note_struc_sub
3168                    | no_std_sub
3169                    ;
3170
3171 /* SOURCE REPOSITORY CITATION */
3172 source_repos_cit_sub : source_repos_repo_sect  { OCCUR2(REPO, 0, 1) }
3173                      ;
3174
3175 source_repos_repo_sect : OPEN DELIM TAG_REPO mand_pointer
3176                          { $<ctxt>$ = start_element(ELT_SUB_REPO,
3177                                                     PARENT, $1, $3, $4,
3178                                                     GEDCOM_MAKE_STRING($4));
3179                            START(REPO, $<ctxt>$) 
3180                          }
3181                          source_repos_repo_subs
3182                          { CHECK0 }
3183                          CLOSE 
3184                          { end_element(ELT_SUB_REPO, PARENT, $<ctxt>5, NULL);
3185                          }
3186                        ;
3187
3188 source_repos_repo_subs : /* empty */
3189                        | source_repos_repo_subs source_repos_repo_sub
3190                        ;
3191
3192 source_repos_repo_sub  : note_struc_sub
3193                        | caln_sect  /* 0:M */
3194                        | no_std_sub
3195                        ;
3196
3197 caln_sect : OPEN DELIM TAG_CALN mand_line_item 
3198             { $<ctxt>$ = start_element(ELT_SUB_REPO_CALN,
3199                                        PARENT, $1, $3, $4,
3200                                        GEDCOM_MAKE_STRING($4));
3201               START(CALN, $<ctxt>$) 
3202             }
3203             caln_subs
3204             { CHECK0 }
3205             CLOSE  
3206             { end_element(ELT_SUB_REPO_CALN, PARENT, $<ctxt>5, NULL);
3207             }
3208           ;
3209
3210 caln_subs : /* empty */
3211           | caln_subs caln_sub
3212           ;
3213
3214 caln_sub  : caln_medi_sect  { OCCUR2(MEDI, 0, 1) }
3215           | no_std_sub
3216           ;
3217
3218 caln_medi_sect : OPEN DELIM TAG_MEDI mand_line_item    
3219                  { $<ctxt>$ = start_element(ELT_SUB_REPO_CALN_MEDI,
3220                                             PARENT, $1, $3, $4,
3221                                             GEDCOM_MAKE_STRING($4));
3222                    START(MEDI, $<ctxt>$)  
3223                  }   
3224                  no_std_subs   
3225                  { CHECK0 }   
3226                  CLOSE   
3227                  { end_element(ELT_SUB_REPO_CALN_MEDI, PARENT, $<ctxt>5, NULL);
3228                  }
3229                ;
3230  
3231 /* SPOUSE TO FAMILY LINK */
3232 spou_fam_link_sub : spou_fam_fams_sect  /* 0:M */
3233                   ;
3234
3235 spou_fam_fams_sect : OPEN DELIM TAG_FAMS mand_pointer
3236                      { $<ctxt>$ = start_element(ELT_SUB_FAMS,
3237                                                 PARENT, $1, $3, $4,
3238                                                 GEDCOM_MAKE_STRING($4));
3239                        START(FAMS, $<ctxt>$) 
3240                      }
3241                      spou_fam_fams_subs
3242                      { CHECK0 }
3243                      CLOSE 
3244                      { end_element(ELT_SUB_FAMS, PARENT, $<ctxt>5, NULL);
3245                      }
3246                    ;
3247
3248 spou_fam_fams_subs : /* empty */
3249                    | spou_fam_fams_subs spou_fam_fams_sub
3250                    ;
3251
3252 spou_fam_fams_sub  : note_struc_sub
3253                    | no_std_sub
3254                    ;
3255
3256 /*********************************************************************/
3257 /**** General                                                     ****/
3258 /*********************************************************************/
3259
3260 no_std_subs : /* empty */
3261             | no_std_subs no_std_sub
3262             ;
3263
3264 no_std_sub  : user_sect /* 0:M */
3265             | gen_sect
3266             | error error_subs CLOSE  { HANDLE_ERROR }
3267             ;
3268
3269 no_std_rec  : user_rec /* 0:M */
3270             | gen_rec
3271             | error error_subs CLOSE  { HANDLE_ERROR }
3272             ;
3273
3274 user_rec    : OPEN DELIM opt_xref USERTAG 
3275               { if ($4[0] != '_') {
3276                   gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
3277                                $4);
3278                   YYERROR;
3279                 }
3280               }
3281               opt_value
3282               { $<ctxt>$ = start_record(REC_USER, $1, $3, $4);
3283                 START($4, $<ctxt>$)
3284               }
3285               user_sects
3286               { CHECK0 }
3287               CLOSE
3288               { end_record(REC_USER, $<ctxt>7); }
3289             ;
3290 user_sect   : OPEN DELIM opt_xref USERTAG 
3291               { if ($4[0] != '_') {
3292                   gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
3293                                $4);
3294                   YYERROR;
3295                 }
3296               }
3297               opt_value
3298               { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6,  
3299                                          GEDCOM_MAKE_NULL_OR_STRING($6));
3300                 START($4, $<ctxt>$);
3301               }
3302               user_sects
3303               { CHECK0 }
3304               CLOSE
3305               { end_element(ELT_USER, PARENT, $<ctxt>7, NULL);
3306               }
3307             ;
3308
3309 user_sects   : /* empty */     { }
3310             | user_sects user_sect { }
3311             ;
3312
3313 opt_xref    : /* empty */        { $$ = NULL; }
3314             | POINTER DELIM        { $$ = $1; }
3315             ;
3316
3317 opt_value   : /* empty */        { $$ = NULL; }
3318             | DELIM line_value        { $$ = $2; }
3319             ;
3320
3321 line_value  : POINTER        { $$ = $1; }
3322             | line_item        { $$ = $1; }
3323             ;
3324
3325 mand_pointer : /* empty */ { gedcom_error(_("Missing pointer")); YYERROR; }
3326              | DELIM POINTER { gedcom_debug_print("==Ptr: %s==", $2);
3327                                $$ = $2; }
3328              ;
3329
3330 mand_line_item : /* empty */ { gedcom_error(_("Missing value")); YYERROR; }
3331                | DELIM line_item { gedcom_debug_print("==Val: %s==", $2);
3332                                    $$ = $2; }
3333                ;
3334
3335 opt_line_item : /* empty */ { }
3336               | DELIM line_item { }
3337               ;
3338
3339 line_item   : anychar  { size_t i;
3340                          CLEAR_BUFFER(line_item_buf);
3341                          line_item_buf_ptr = line_item_buf;
3342                          /* The following also takes care of '@@' */
3343                          if (!strncmp($1, "@@", 3))
3344                            *line_item_buf_ptr++ = '@';
3345                          else
3346                            for (i=0; i < strlen($1); i++)
3347                              *line_item_buf_ptr++ = $1[i];
3348                          $$ = line_item_buf;
3349                        }
3350             | ESCAPE   { size_t i;
3351                          CLEAR_BUFFER(line_item_buf);
3352                          line_item_buf_ptr = line_item_buf;
3353                          for (i=0; i < strlen($1); i++)
3354                            *line_item_buf_ptr++ = $1[i];
3355                          $$ = line_item_buf;
3356                        }
3357             | line_item anychar
3358                   { size_t i;
3359                     /* The following also takes care of '@@' */
3360                     if (!strncmp($2, "@@", 3))
3361                       *line_item_buf_ptr++ = '@';
3362                     else
3363                       for (i=0; i < strlen($2); i++)
3364                         *line_item_buf_ptr++ = $2[i];
3365                     $$ = line_item_buf;
3366                   }
3367             | line_item ESCAPE
3368                   { size_t i;
3369                     for (i=0; i < strlen($2); i++)
3370                       *line_item_buf_ptr++ = $2[i];
3371                     $$ = line_item_buf;
3372                   }
3373             ;
3374
3375 anychar     : ANYCHAR        { }
3376             | DELIM        { }
3377             ;
3378
3379 error_subs  : /* empty */
3380             | error_subs error_sect
3381             ;
3382
3383 error_sect  : OPEN DELIM opt_xref anytag opt_value error_subs CLOSE { }
3384
3385 gen_sect    : OPEN DELIM opt_xref anystdtag
3386               { INVALID_TAG($4); }
3387               opt_value opt_sects CLOSE
3388               { }
3389             ;
3390
3391 gen_rec : gen_rec_top
3392         | gen_rec_norm
3393         ;
3394
3395 gen_rec_norm : OPEN DELIM opt_xref anystdtag
3396                { INVALID_TOP_TAG($4) }
3397                opt_value opt_sects CLOSE
3398                { }
3399              ;
3400
3401 gen_rec_top : OPEN DELIM anytoptag
3402               { gedcom_error(_("Missing cross-reference")); YYERROR; }
3403               opt_value opt_sects CLOSE
3404                 { }
3405             ;
3406
3407 opt_sects   : /* empty */     { }
3408             | opt_sects gen_sect { }
3409             ;
3410
3411 anytag      : USERTAG { }
3412             | anystdtag { }
3413             ;
3414
3415 anytoptag   : TAG_FAM
3416             | TAG_INDI
3417             | TAG_OBJE
3418             | TAG_NOTE
3419             | TAG_REPO
3420             | TAG_SOUR
3421             | TAG_SUBN
3422             | TAG_SUBM
3423             ;
3424
3425 anystdtag   : TAG_ABBR
3426             | TAG_ADDR
3427             | TAG_ADR1
3428             | TAG_ADR2   { }
3429             | TAG_ADOP   { }
3430             | TAG_AFN   { }
3431             | TAG_AGE   { }
3432             | TAG_AGNC   { }
3433             | TAG_ALIA   { }
3434             | TAG_ANCE   { }
3435             | TAG_ANCI   { }
3436             | TAG_ANUL   { }
3437             | TAG_ASSO   { }
3438             | TAG_AUTH   { }
3439             | TAG_BAPL   { }
3440             | TAG_BAPM   { }
3441             | TAG_BARM   { }
3442             | TAG_BASM   { }
3443             | TAG_BIRT   { }
3444             | TAG_BLES   { }
3445             | TAG_BLOB   { }
3446             | TAG_BURI   { }
3447             | TAG_CALN   { }
3448             | TAG_CAST   { }
3449             | TAG_CAUS   { }
3450             | TAG_CENS   { }
3451             | TAG_CHAN   { }
3452             | TAG_CHAR   { }
3453             | TAG_CHIL   { }
3454             | TAG_CHR   { }
3455             | TAG_CHRA   { }
3456             | TAG_CITY   { }
3457             | TAG_CONC   { }
3458             | TAG_CONF   { }
3459             | TAG_CONL   { }
3460             | TAG_CONT   { }
3461             | TAG_COPR   { }
3462             | TAG_CORP   { }
3463             | TAG_CREM   { }
3464             | TAG_CTRY   { }
3465             | TAG_DATA   { }
3466             | TAG_DATE   { }
3467             | TAG_DEAT   { }
3468             | TAG_DESC   { }
3469             | TAG_DESI   { }
3470             | TAG_DEST   { }
3471             | TAG_DIV   { }
3472             | TAG_DIVF   { }
3473             | TAG_DSCR   { }
3474             | TAG_EDUC   { }
3475             | TAG_EMIG   { }
3476             | TAG_ENDL   { }
3477             | TAG_ENGA   { }
3478             | TAG_EVEN   { }
3479             | TAG_FAM    { }
3480             | TAG_FAMC   { }
3481             | TAG_FAMS   { }
3482             | TAG_FCOM   { }
3483             | TAG_FILE   { }
3484             | TAG_FORM   { }
3485             | TAG_GEDC   { }
3486             | TAG_GIVN   { }
3487             | TAG_GRAD   { }
3488             | TAG_HEAD   { }
3489             | TAG_HUSB   { }
3490             | TAG_IDNO   { }
3491             | TAG_IMMI   { }
3492             | TAG_INDI   { }
3493             | TAG_LANG   { }
3494             | TAG_LEGA   { }
3495             | TAG_MARB   { }
3496             | TAG_MARC   { }
3497             | TAG_MARL   { }
3498             | TAG_MARR   { }
3499             | TAG_MARS   { }
3500             | TAG_MEDI   { }
3501             | TAG_NAME   { }
3502             | TAG_NATI   { }
3503             | TAG_NCHI   { }
3504             | TAG_NICK   { }
3505             | TAG_NMR   { }
3506             | TAG_NOTE   { }
3507             | TAG_NPFX   { }
3508             | TAG_NSFX   { }
3509             | TAG_OBJE   { }
3510             | TAG_OCCU   { }
3511             | TAG_ORDI   { }
3512             | TAG_ORDN   { }
3513             | TAG_PAGE   { }
3514             | TAG_PEDI   { }
3515             | TAG_PHON   { }
3516             | TAG_PLAC   { }
3517             | TAG_POST   { }
3518             | TAG_PROB   { }
3519             | TAG_PROP   { }
3520             | TAG_PUBL   { }
3521             | TAG_QUAY   { }
3522             | TAG_REFN   { }
3523             | TAG_RELA   { }
3524             | TAG_RELI   { }
3525             | TAG_REPO   { }
3526             | TAG_RESI   { }
3527             | TAG_RESN   { }
3528             | TAG_RETI   { }
3529             | TAG_RFN   { }
3530             | TAG_RIN   { }
3531             | TAG_ROLE   { }
3532             | TAG_SEX   { }
3533             | TAG_SLGC   { }
3534             | TAG_SLGS   { }
3535             | TAG_SOUR   { }
3536             | TAG_SPFX   { }
3537             | TAG_SSN   { }
3538             | TAG_STAE   { }
3539             | TAG_STAT   { }
3540             | TAG_SUBM   { }
3541             | TAG_SUBN   { }
3542             | TAG_SURN   { }
3543             | TAG_TEMP   { }
3544             | TAG_TEXT   { }
3545             | TAG_TIME   { }
3546             | TAG_TITL   { }
3547             | TAG_TRLR   { }
3548             | TAG_TYPE   { }
3549             | TAG_VERS   { }
3550             | TAG_WIFE   { }
3551             | TAG_WILL   { }
3552
3553 %%
3554
3555 /* Functions that handle the counting of subtags */
3556
3557 int* count_arrays[MAXGEDCLEVEL+1];
3558 char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLEN+1];
3559 Gedcom_ctxt ctxt_stack[MAXGEDCLEVEL+1];
3560
3561 void push_countarray()
3562 {
3563   int *count = NULL;
3564   if (count_level > MAXGEDCLEVEL) {
3565     gedcom_error(_("Internal error: count array overflow"));
3566     exit(1);
3567   }
3568   else {
3569     count = (int *)calloc(YYNTOKENS, sizeof(int));
3570     if (count == NULL) {
3571       gedcom_error(_("Internal error: count array calloc error"));
3572       exit(1);
3573     }
3574     else {
3575       count_arrays[count_level] = count;
3576     }
3577   }
3578 }
3579
3580 void set_parenttag(char* tag)
3581 {
3582   strncpy(tag_stack[count_level], tag, MAXSTDTAGLEN+1);
3583 }
3584
3585 void set_parentctxt(Gedcom_ctxt ctxt)
3586 {
3587   ctxt_stack[count_level] = ctxt;
3588 }
3589
3590 char* get_parenttag()
3591 {
3592   return tag_stack[count_level];
3593 }
3594
3595 Gedcom_ctxt get_parentctxt()
3596 {
3597   return ctxt_stack[count_level];
3598 }
3599
3600 int count_tag(int tag)
3601 {
3602   int *count = count_arrays[count_level];
3603   return ++count[tag - GEDCOMTAGOFFSET];
3604 }
3605
3606 int check_occurrence(int tag)
3607 {
3608   int *count = count_arrays[count_level];
3609   return (count[tag - GEDCOMTAGOFFSET] > 0);
3610 }
3611
3612 void pop_countarray()
3613 {
3614   int *count;
3615   if (count_level < 0) {
3616     gedcom_error(_("Internal error: count array underflow"));
3617     exit(1);
3618   }
3619   else {
3620     count = count_arrays[count_level];
3621     free(count);
3622     count_arrays[count_level] = NULL;
3623   }
3624 }
3625
3626 /* Enabling debug mode */
3627 /* level 0: no debugging */
3628 /* level 1: only internal */
3629 /* level 2: also bison */
3630 FILE* trace_output;
3631
3632 void gedcom_set_debug_level(int level, FILE* f)
3633 {
3634   if (f != NULL)
3635     trace_output = f;
3636   else
3637     trace_output = stderr;
3638   if (level > 0) {
3639     gedcom_high_level_debug = 1;
3640   }
3641   if (level > 1) {
3642 #if YYDEBUG != 0
3643     gedcom_debug = 1;
3644 #endif
3645   }
3646 }
3647
3648 int gedcom_debug_print(char* s, ...)
3649 {
3650   int res = 0;
3651   if (gedcom_high_level_debug) {
3652     va_list ap;
3653     va_start(ap, s);
3654     res = vfprintf(trace_output, s, ap);
3655     va_end(ap);
3656     fprintf(trace_output, "\n");
3657   }
3658   return(res);
3659 }
3660
3661 /* Setting the error mechanism */
3662 void gedcom_set_error_handling(Gedcom_err_mech mechanism)
3663 {
3664   error_mechanism = mechanism;
3665 }
3666
3667 /* Compatibility handling */
3668
3669 void gedcom_set_compat_handling(int enable_compat)
3670 {
3671   compat_enabled = enable_compat;
3672 }
3673
3674 void set_compatibility(char* program)
3675 {
3676   if (compat_enabled) {
3677     if (! strncmp(program, "ftree", 6)) {
3678       gedcom_warning(_("Enabling compatibility with 'ftree'"));
3679       compatibility = C_FTREE;
3680     }
3681     else {
3682       compatibility = 0;
3683     }
3684   }
3685 }
3686
3687 int compat_mode(int compat_flags)
3688 {
3689   return (compat_flags & compatibility);
3690 }
3691