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