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