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