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