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