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