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