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