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