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