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