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