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