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