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