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