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