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