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