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