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