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