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