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