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