Added compatibility for PAF 4.
[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 310
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                if (compat_mode(C_SUBM_CTRY))
1928                  compat_free_ctry_parent_context();
1929              }
1930            ;
1931
1932 subm_subs  : /* empty */
1933            | subm_subs subm_sub
1934            ;
1935
1936 subm_sub   : subm_name_sect  { OCCUR2(NAME, 1, 1) }
1937            | addr_struc_sub  /* 0:1 */
1938            | multim_link_sub  /* 0:M */
1939            | subm_lang_sect  { OCCUR2(LANG, 0, 3) }
1940            | subm_rfn_sect  { OCCUR2(RFN, 0, 1) }
1941            | subm_rin_sect  { OCCUR2(RIN, 0, 1) }
1942            | change_date_sub  /* 0:1 */
1943            | subm_ctry_sect  { if (!compat_mode(C_SUBM_CTRY))
1944                                   INVALID_TAG("CTRY");
1945                                OCCUR2(CTRY, 0, 1) }
1946            | no_std_sub
1947            ;
1948
1949 /* SUBM.NAME */
1950 subm_name_sect : OPEN DELIM TAG_NAME mand_line_item             
1951                  { $<ctxt>$ = start_element(ELT_SUBM_NAME,
1952                                             PARENT, $1, $3, $4, 
1953                                             GEDCOM_MAKE_STRING(val1, $4));
1954                    START(NAME, $1, $<ctxt>$)              
1955                  }              
1956                  no_std_subs              
1957                  { CHECK0 }              
1958                  CLOSE              
1959                  { end_element(ELT_SUBM_NAME, PARENT, $<ctxt>5,
1960                                GEDCOM_MAKE_NULL(val1));
1961                  }
1962                ;
1963
1964 /* SUBM.LANG */
1965 subm_lang_sect : OPEN DELIM TAG_LANG mand_line_item             
1966                  { $<ctxt>$ = start_element(ELT_SUBM_LANG,
1967                                             PARENT, $1, $3, $4, 
1968                                             GEDCOM_MAKE_STRING(val1, $4));
1969                    START(LANG, $1, $<ctxt>$)              
1970                  }              
1971                  no_std_subs              
1972                  { CHECK0 }              
1973                  CLOSE              
1974                  { end_element(ELT_SUBM_LANG, PARENT, $<ctxt>5,
1975                                GEDCOM_MAKE_NULL(val1));
1976                  }
1977                ;
1978
1979 /* SUBM.RFN */
1980 subm_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item             
1981                  { $<ctxt>$ = start_element(ELT_SUBM_RFN,
1982                                             PARENT, $1, $3, $4, 
1983                                             GEDCOM_MAKE_STRING(val1, $4));
1984                    START(RFN, $1, $<ctxt>$)              
1985                  }              
1986                  no_std_subs              
1987                  { CHECK0 }              
1988                  CLOSE              
1989                  { end_element(ELT_SUBM_RFN, PARENT, $<ctxt>5,
1990                                GEDCOM_MAKE_NULL(val1));
1991                  }
1992                ;
1993
1994 /* SUBM.RIN */
1995 subm_rin_sect  : OPEN DELIM TAG_RIN mand_line_item             
1996                  { $<ctxt>$ = start_element(ELT_SUBM_RIN,
1997                                             PARENT, $1, $3, $4, 
1998                                             GEDCOM_MAKE_STRING(val1, $4));
1999                    START(RIN, $1, $<ctxt>$)              
2000                  }              
2001                  no_std_subs              
2002                  { CHECK0 }              
2003                  CLOSE              
2004                  { end_element(ELT_SUBM_RIN, PARENT, $<ctxt>5,
2005                                GEDCOM_MAKE_NULL(val1));
2006                  }
2007                ;
2008
2009 /* SUBM.CTRY (Only for compatibility) */
2010 subm_ctry_sect : OPEN DELIM TAG_CTRY opt_line_item
2011                  { if (compat_mode(C_SUBM_CTRY)) {
2012                      $<ctxt>$ = compat_generate_addr_ctry_start($1, $3, $4);
2013                    }
2014                  }
2015                  CLOSE
2016                  { if (compat_mode (C_SUBM_CTRY)) {
2017                      compat_generate_addr_ctry_end($<ctxt>5);
2018                    }
2019                  }
2020                ;
2021
2022 /*********************************************************************/
2023 /**** Substructures                                               ****/
2024 /*********************************************************************/
2025
2026 /* ADDRESS STRUCTURE */
2027 addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) }
2028                | phon_sect { OCCUR2(PHON, 0, 3) }
2029                ;
2030
2031 addr_sect   : OPEN DELIM TAG_ADDR mand_line_item 
2032               { $<ctxt>$ = start_element(ELT_SUB_ADDR,
2033                                          PARENT, $1, $3, $4, 
2034                                          GEDCOM_MAKE_STRING(val1, $4));
2035                 reset_buffer(&concat_buffer);
2036                 safe_buf_append(&concat_buffer, $4);
2037                 START(ADDR, $1, $<ctxt>$);
2038                 if (compat_mode(C_SUBM_CTRY))
2039                   compat_save_ctry_parent_context($<ctxt>$);
2040               }
2041               addr_subs
2042               { CHECK0 }
2043               CLOSE  
2044               { char* complete = get_buf_string(&concat_buffer);
2045                 end_element(ELT_SUB_ADDR, PARENT, $<ctxt>5,
2046                             GEDCOM_MAKE_STRING(val1, complete));
2047               }
2048             ;
2049
2050 addr_subs   : /* empty */
2051             | addr_subs addr_sub
2052             ;
2053
2054 addr_sub    : addr_cont_sect  /* 0:M */
2055             | addr_adr1_sect  { OCCUR2(ADR1, 0, 1) }
2056             | addr_adr2_sect  { OCCUR2(ADR2, 0, 1) }
2057             | addr_city_sect  { OCCUR2(CITY, 0, 1) }
2058             | addr_stae_sect  { OCCUR2(STAE, 0, 1) }
2059             | addr_post_sect  { OCCUR2(POST, 0, 1) }
2060             | addr_ctry_sect  { OCCUR2(CTRY, 0, 1) }
2061             | no_std_sub
2062             ;
2063
2064 addr_cont_sect : OPEN DELIM TAG_CONT mand_line_item              
2065                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_CONT,
2066                                             PARENT, $1, $3, $4, 
2067                                             GEDCOM_MAKE_STRING(val1, $4));
2068                    SAFE_BUF_ADDCHAR(&concat_buffer, '\n');
2069                    safe_buf_append(&concat_buffer, $4);
2070                    START(CONT, $1, $<ctxt>$)               
2071                  }               
2072                  no_std_subs               
2073                  { CHECK0 }               
2074                  CLOSE               
2075                  { end_element(ELT_SUB_ADDR_CONT, PARENT, $<ctxt>5,
2076                                GEDCOM_MAKE_NULL(val1));
2077                  }
2078                ;
2079 addr_adr1_sect : OPEN DELIM TAG_ADR1 mand_line_item              
2080                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_ADR1,
2081                                             PARENT, $1, $3, $4, 
2082                                             GEDCOM_MAKE_STRING(val1, $4));
2083                    START(ADR1, $1, $<ctxt>$)               
2084                  }               
2085                  no_std_subs               
2086                  { CHECK0 }               
2087                  CLOSE               
2088                  { end_element(ELT_SUB_ADDR_ADR1, PARENT, $<ctxt>5,
2089                                GEDCOM_MAKE_NULL(val1));
2090                  }
2091                ;
2092 addr_adr2_sect : OPEN DELIM TAG_ADR2 mand_line_item              
2093                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_ADR2,
2094                                             PARENT, $1, $3, $4, 
2095                                             GEDCOM_MAKE_STRING(val1, $4));
2096                    START(ADR2, $1, $<ctxt>$)               
2097                  }               
2098                  no_std_subs               
2099                  { CHECK0 }               
2100                  CLOSE               
2101                  { end_element(ELT_SUB_ADDR_ADR2, PARENT, $<ctxt>5,
2102                                GEDCOM_MAKE_NULL(val1));
2103                  }
2104                ;
2105 addr_city_sect : OPEN DELIM TAG_CITY mand_line_item              
2106                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_CITY,
2107                                             PARENT, $1, $3, $4, 
2108                                             GEDCOM_MAKE_STRING(val1, $4));
2109                    START(CITY, $1, $<ctxt>$)               
2110                  }               
2111                  no_std_subs               
2112                  { CHECK0 }               
2113                  CLOSE               
2114                  { end_element(ELT_SUB_ADDR_CITY, PARENT, $<ctxt>5,
2115                                GEDCOM_MAKE_NULL(val1));
2116                  }
2117                ;
2118 addr_stae_sect : OPEN DELIM TAG_STAE mand_line_item              
2119                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_STAE,
2120                                             PARENT, $1, $3, $4, 
2121                                             GEDCOM_MAKE_STRING(val1, $4));
2122                    START(STAE, $1, $<ctxt>$)               
2123                  }               
2124                  no_std_subs               
2125                  { CHECK0 }               
2126                  CLOSE               
2127                  { end_element(ELT_SUB_ADDR_STAE, PARENT, $<ctxt>5,
2128                                GEDCOM_MAKE_NULL(val1));
2129                  }
2130                ;
2131 addr_post_sect : OPEN DELIM TAG_POST mand_line_item              
2132                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_POST,
2133                                             PARENT, $1, $3, $4, 
2134                                             GEDCOM_MAKE_STRING(val1, $4));
2135                    START(POST, $1, $<ctxt>$)               
2136                  }               
2137                  no_std_subs               
2138                  { CHECK0 }               
2139                  CLOSE               
2140                  { end_element(ELT_SUB_ADDR_POST, PARENT, $<ctxt>5,
2141                                GEDCOM_MAKE_NULL(val1));
2142                  }
2143                ;
2144 addr_ctry_sect : OPEN DELIM TAG_CTRY mand_line_item              
2145                  { $<ctxt>$ = start_element(ELT_SUB_ADDR_CTRY,
2146                                             PARENT, $1, $3, $4, 
2147                                             GEDCOM_MAKE_STRING(val1, $4));
2148                    START(CTRY, $1, $<ctxt>$)               
2149                  }               
2150                  no_std_subs               
2151                  { CHECK0 }               
2152                  CLOSE               
2153                  { end_element(ELT_SUB_ADDR_CTRY, PARENT, $<ctxt>5,
2154                                GEDCOM_MAKE_NULL(val1));
2155                  }
2156                ;
2157
2158 phon_sect   : OPEN DELIM TAG_PHON mand_line_item              
2159               { $<ctxt>$ = start_element(ELT_SUB_PHON,
2160                                          PARENT, $1, $3, $4, 
2161                                          GEDCOM_MAKE_STRING(val1, $4));
2162                 START(PHON, $1, $<ctxt>$)               
2163               }               
2164               no_std_subs               
2165               { CHECK0 }               
2166               CLOSE               
2167               { end_element(ELT_SUB_PHON, PARENT, $<ctxt>5,
2168                             GEDCOM_MAKE_NULL(val1));
2169               }
2170             ;
2171
2172 /* ASSOCIATION STRUCTURE */
2173 assoc_struc_sub : asso_sect /* 0:M */
2174                 ;
2175
2176 asso_sect : OPEN DELIM TAG_ASSO mand_pointer
2177             { struct xref_value *xr = gedcom_parse_xref($4, XREF_USED,
2178                                                         XREF_ANY);
2179               if (xr == NULL) HANDLE_ERROR;
2180               $<ctxt>$ = start_element(ELT_SUB_ASSO,
2181                                        PARENT, $1, $3, $4, 
2182                                        GEDCOM_MAKE_XREF_PTR(val1, xr));
2183               START(ASSO, $1, $<ctxt>$) 
2184             }
2185             asso_subs
2186             { CHECK2(TYPE,RELA) }
2187             CLOSE 
2188             { end_element(ELT_SUB_ASSO, PARENT, $<ctxt>5,
2189                           GEDCOM_MAKE_NULL(val1));
2190             }
2191           ;
2192
2193 asso_subs : /* empty */
2194           | asso_type_sect  { OCCUR2(TYPE, 1, 1) }
2195           | asso_rela_sect  { OCCUR2(RELA, 1, 1) }
2196           | note_struc_sub
2197           | source_cit_sub
2198           | no_std_sub
2199           ;
2200
2201 asso_type_sect : OPEN DELIM TAG_TYPE mand_line_item               
2202                  { $<ctxt>$ = start_element(ELT_SUB_ASSO_TYPE,
2203                                             PARENT, $1, $3, $4, 
2204                                             GEDCOM_MAKE_STRING(val1, $4));
2205                    START(TYPE, $1, $<ctxt>$)                
2206                  }                
2207                  no_std_subs                
2208                  { CHECK0 }                
2209                  CLOSE                
2210                  { end_element(ELT_SUB_ASSO_TYPE, PARENT, $<ctxt>5,
2211                                GEDCOM_MAKE_NULL(val1));
2212                  }
2213                ;
2214
2215 asso_rela_sect : OPEN DELIM TAG_RELA mand_line_item               
2216                  { $<ctxt>$ = start_element(ELT_SUB_ASSO_RELA,
2217                                             PARENT, $1, $3, $4, 
2218                                             GEDCOM_MAKE_STRING(val1, $4));
2219                    START(RELA, $1, $<ctxt>$)                
2220                  }                
2221                  no_std_subs                
2222                  { CHECK0 }                
2223                  CLOSE                
2224                  { end_element(ELT_SUB_ASSO_RELA, PARENT, $<ctxt>5,
2225                                GEDCOM_MAKE_NULL(val1));
2226                  }
2227                ;
2228
2229 /* CHANGE DATE */
2230 change_date_sub : change_date_chan_sect  { OCCUR2(CHAN, 0, 1) }
2231                 ;
2232
2233 change_date_chan_sect : OPEN DELIM TAG_CHAN
2234                         { $<ctxt>$ = start_element(ELT_SUB_CHAN,
2235                                                    PARENT, $1, $3, NULL, 
2236                                                    GEDCOM_MAKE_NULL(val1));
2237                           START(CHAN, $1, $<ctxt>$) 
2238                         }
2239                         change_date_chan_subs
2240                         { CHECK1(DATE) }
2241                         CLOSE 
2242                         { end_element(ELT_SUB_CHAN, PARENT, $<ctxt>4,
2243                                       GEDCOM_MAKE_NULL(val1));
2244                         }
2245                       ;
2246
2247 change_date_chan_subs : /* empty */
2248                       | change_date_chan_subs change_date_chan_sub
2249                       ;
2250
2251 change_date_chan_sub  : change_date_date_sect  { OCCUR2(DATE, 1, 1) }
2252                       | note_struc_sub
2253                       | no_std_sub
2254                       ;
2255
2256 change_date_date_sect : OPEN DELIM TAG_DATE mand_line_item 
2257                         { struct date_value dv = gedcom_parse_date($4);
2258                           $<ctxt>$ = start_element(ELT_SUB_CHAN_DATE,
2259                                                    PARENT, $1, $3, $4, 
2260                                                    GEDCOM_MAKE_DATE(val1, dv));
2261                           START(DATE, $1, $<ctxt>$) }
2262                         change_date_date_subs
2263                         { CHECK0 }
2264                         CLOSE 
2265                         { end_element(ELT_SUB_CHAN_DATE, PARENT, $<ctxt>5,
2266                                       GEDCOM_MAKE_NULL(val1));
2267                         }
2268                       ;
2269
2270 change_date_date_subs : /* empty */
2271                       | change_date_date_subs change_date_date_sub
2272                       ;
2273
2274 change_date_date_sub : change_date_date_time_sect  { OCCUR2(TIME, 0, 1) }
2275                      | no_std_sub
2276                      ;
2277
2278 change_date_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
2279                              { $<ctxt>$
2280                                  = start_element(ELT_SUB_CHAN_TIME,
2281                                                  PARENT, $1, $3, $4, 
2282                                                  GEDCOM_MAKE_STRING(val1, $4));
2283                                START(TIME, $1, $<ctxt>$) 
2284                              } 
2285                              no_std_subs 
2286                              { CHECK0 } 
2287                              CLOSE 
2288                              { end_element(ELT_SUB_CHAN_TIME, PARENT, $<ctxt>5,
2289                                            GEDCOM_MAKE_NULL(val1));
2290                              }
2291                            ;
2292
2293 /* CHILD TO FAMILY LINK */
2294 chi_fam_link_sub : famc_sect  /* 0:M */
2295                  ;
2296
2297 famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2298             { struct xref_value *xr = gedcom_parse_xref($4, XREF_USED,
2299                                                           XREF_FAM);
2300               if (xr == NULL) HANDLE_ERROR;
2301               $<ctxt>$ = start_element(ELT_SUB_FAMC,
2302                                        PARENT, $1, $3, $4, 
2303                                        GEDCOM_MAKE_XREF_PTR(val1, xr));
2304               START(FAMC, $1, $<ctxt>$) 
2305             }
2306             famc_subs
2307             { CHECK0 }
2308             CLOSE 
2309             { end_element(ELT_SUB_FAMC, PARENT, $<ctxt>5,
2310                           GEDCOM_MAKE_NULL(val1));
2311             }
2312           ;
2313
2314 famc_subs : /* empty */
2315           | famc_subs famc_sub
2316           ;
2317
2318 famc_sub  : famc_pedi_sect  /* 0:M */
2319           | note_struc_sub
2320           | no_std_sub
2321           ;
2322
2323 famc_pedi_sect : OPEN DELIM TAG_PEDI mand_line_item 
2324                  { $<ctxt>$ = start_element(ELT_SUB_FAMC_PEDI,
2325                                             PARENT, $1, $3, $4, 
2326                                             GEDCOM_MAKE_STRING(val1, $4));
2327                    START(PEDI, $1, $<ctxt>$)  
2328                  }  
2329                  no_std_subs  
2330                  { CHECK0 }  
2331                  CLOSE  
2332                  { end_element(ELT_SUB_FAMC_PEDI, PARENT, $<ctxt>5,
2333                                GEDCOM_MAKE_NULL(val1));
2334                  }
2335                ;
2336
2337 /* CONTINUATION SUBSECTIONS */
2338 continuation_sub : cont_sect  /* 0:M */
2339                  | conc_sect  /* 0:M */
2340                  ;
2341
2342 cont_sect : OPEN DELIM TAG_CONT opt_line_item 
2343             { $<ctxt>$ = start_element(ELT_SUB_CONT,
2344                                        PARENT, $1, $3, $4, 
2345                                        GEDCOM_MAKE_NULL_OR_STRING(val1, $4));
2346               SAFE_BUF_ADDCHAR(&concat_buffer, '\n');
2347               if (GEDCOM_IS_STRING(&val1))
2348                 safe_buf_append(&concat_buffer, $4);
2349               START(CONT, $1, $<ctxt>$)  
2350             }  
2351             no_std_subs  
2352             { CHECK0 }  
2353             CLOSE  
2354             { end_element(ELT_SUB_CONT, PARENT, $<ctxt>5,
2355                           GEDCOM_MAKE_NULL(val1));
2356             }
2357           ;
2358
2359 conc_sect : OPEN DELIM TAG_CONC mand_line_item 
2360             { $<ctxt>$ = start_element(ELT_SUB_CONC,
2361                                        PARENT, $1, $3, $4, 
2362                                        GEDCOM_MAKE_STRING(val1, $4));
2363               if (compat_mode(C_CONC_NEEDS_SPACE)) {
2364                 safe_buf_append(&concat_buffer, " ");
2365               }
2366               safe_buf_append(&concat_buffer, $4);
2367               START(CONC, $1, $<ctxt>$)  
2368             }  
2369             no_std_subs  
2370             { CHECK0 }  
2371             CLOSE  
2372             { end_element(ELT_SUB_CONC, PARENT, $<ctxt>5,
2373                           GEDCOM_MAKE_NULL(val1));
2374             }
2375           ; 
2376
2377 /* EVENT DETAIL */
2378 event_detail_sub : event_detail_type_sect  { OCCUR2(TYPE, 0, 1) }
2379                  | event_detail_date_sect  { OCCUR2(DATE, 0, 1) }
2380                  | place_struc_sub
2381                  | addr_struc_sub
2382                  | event_detail_age_sect  { OCCUR2(AGE, 0, 1) }
2383                  | event_detail_agnc_sect  { OCCUR2(AGNC, 0, 1) }
2384                  | event_detail_caus_sect  { OCCUR2(CAUS, 0, 1) }
2385                  | source_cit_sub
2386                  | multim_link_sub
2387                  | note_struc_sub
2388                  ;
2389
2390 event_detail_type_sect : OPEN DELIM TAG_TYPE mand_line_item 
2391                          { $<ctxt>$
2392                              = start_element(ELT_SUB_EVT_TYPE,
2393                                              PARENT, $1, $3, $4, 
2394                                              GEDCOM_MAKE_STRING(val1, $4));
2395                            START(TYPE, $1, $<ctxt>$)  
2396                          }  
2397                          no_std_subs  
2398                          { CHECK0 }  
2399                          CLOSE  
2400                          { end_element(ELT_SUB_EVT_TYPE, PARENT, $<ctxt>5,
2401                                        GEDCOM_MAKE_NULL(val1));
2402                          }
2403                        ;
2404 event_detail_date_sect : OPEN DELIM TAG_DATE mand_line_item 
2405                          { struct date_value dv = gedcom_parse_date($4);
2406                            $<ctxt>$
2407                              = start_element(ELT_SUB_EVT_DATE,
2408                                              PARENT, $1, $3, $4, 
2409                                              GEDCOM_MAKE_DATE(val1, dv));
2410                            START(DATE, $1, $<ctxt>$)  
2411                          }  
2412                          no_std_subs  
2413                          { CHECK0 }  
2414                          CLOSE  
2415                          { end_element(ELT_SUB_EVT_DATE, PARENT, $<ctxt>5,
2416                                        GEDCOM_MAKE_NULL(val1));
2417                          }
2418                        ;
2419 event_detail_age_sect  : OPEN DELIM TAG_AGE mand_line_item 
2420                          { struct age_value age = gedcom_parse_age($4);
2421                            $<ctxt>$
2422                              = start_element(ELT_SUB_EVT_AGE,
2423                                              PARENT, $1, $3, $4, 
2424                                              GEDCOM_MAKE_AGE(val1, age));
2425                            START(AGE, $1, $<ctxt>$)  
2426                          }  
2427                          no_std_subs  
2428                          { CHECK0 }  
2429                          CLOSE  
2430                          { end_element(ELT_SUB_EVT_AGE, PARENT, $<ctxt>5,
2431                                        GEDCOM_MAKE_NULL(val1));
2432                          }
2433                        ;
2434 event_detail_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item 
2435                          { $<ctxt>$
2436                              = start_element(ELT_SUB_EVT_AGNC,
2437                                              PARENT, $1, $3, $4, 
2438                                              GEDCOM_MAKE_STRING(val1, $4));
2439                            START(AGNC, $1, $<ctxt>$)  
2440                          }  
2441                          no_std_subs  
2442                          { CHECK0 }  
2443                          CLOSE  
2444                          { end_element(ELT_SUB_EVT_AGNC, PARENT, $<ctxt>5,
2445                                        GEDCOM_MAKE_NULL(val1));
2446                          }
2447                        ;
2448 event_detail_caus_sect : OPEN DELIM TAG_CAUS mand_line_item 
2449                          { $<ctxt>$
2450                              = start_element(ELT_SUB_EVT_CAUS,
2451                                              PARENT, $1, $3, $4, 
2452                                              GEDCOM_MAKE_STRING(val1, $4));
2453                            START(CAUS, $1, $<ctxt>$)  
2454                          }  
2455                          no_std_subs  
2456                          { CHECK0 }  
2457                          CLOSE  
2458                          { end_element(ELT_SUB_EVT_CAUS, PARENT, $<ctxt>5,
2459                                        GEDCOM_MAKE_NULL(val1));
2460                          }
2461                        ;
2462
2463 /* FAMILY EVENT STRUCTURE */
2464 fam_event_struc_sub : fam_event_sect
2465                     | fam_gen_even_sect  /* 0:M */
2466                     ;
2467
2468 fam_event_sect : OPEN DELIM fam_event_tag opt_value  
2469                  { $<ctxt>$
2470                      = start_element(ELT_SUB_FAM_EVT,
2471                                      PARENT, $1, $3, $4,
2472                                      GEDCOM_MAKE_NULL_OR_STRING(val1, $4));
2473                    START2($1, $<ctxt>$);
2474                  }
2475                  fam_event_subs
2476                  { CHECK0 }
2477                  CLOSE 
2478                  { end_element(ELT_SUB_FAM_EVT, PARENT, $<ctxt>5,
2479                                GEDCOM_MAKE_NULL(val1));
2480                  }
2481                ;
2482
2483 fam_event_tag : TAG_ANUL { $$ = $1; START1(ANUL) }
2484               | TAG_CENS { $$ = $1; START1(CENS) }
2485               | TAG_DIV { $$ = $1; START1(DIV) }
2486               | TAG_DIVF { $$ = $1; START1(DIVF) }
2487               | TAG_ENGA { $$ = $1; START1(ENGA) }
2488               | TAG_MARR { $$ = $1; START1(MARR) }
2489               | TAG_MARB { $$ = $1; START1(MARB) }
2490               | TAG_MARC { $$ = $1; START1(MARC) }
2491               | TAG_MARL { $$ = $1; START1(MARL) }
2492               | TAG_MARS { $$ = $1; START1(MARS) }
2493               ;
2494
2495 fam_event_subs : /* empty */
2496                | fam_event_subs fam_event_sub
2497                ;
2498
2499 fam_event_sub : event_detail_sub
2500               | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
2501               | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
2502               | no_std_sub
2503               ;
2504
2505 fam_even_husb_sect : OPEN DELIM TAG_HUSB
2506                      { $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_HUSB,
2507                                                 PARENT, $1, $3, NULL,
2508                                                 GEDCOM_MAKE_NULL(val1));
2509                        START(HUSB, $1, $<ctxt>$) 
2510                      }
2511                      fam_even_husb_subs
2512                      { CHECK1(AGE) }
2513                      CLOSE 
2514                      { end_element(ELT_SUB_FAM_EVT_HUSB, PARENT, $<ctxt>4,
2515                                    GEDCOM_MAKE_NULL(val1));
2516                      }
2517                    ;
2518
2519 fam_even_husb_subs : /* empty */
2520                    | fam_even_husb_subs fam_even_husb_sub
2521                    ;
2522
2523 fam_even_husb_sub : fam_even_age_sect  { OCCUR2(AGE, 1, 1) }
2524                   | no_std_sub
2525                   ;
2526
2527 fam_even_age_sect : OPEN DELIM TAG_AGE mand_line_item  
2528                     { struct age_value age = gedcom_parse_age($4);
2529                       $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_AGE,
2530                                                PARENT, $1, $3, $4,
2531                                                GEDCOM_MAKE_AGE(val1, age));
2532                       START(AGE, $1, $<ctxt>$)   
2533                     }   
2534                     no_std_subs   
2535                     { CHECK0 }   
2536                     CLOSE   
2537                     { end_element(ELT_SUB_FAM_EVT_AGE, PARENT, $<ctxt>5,
2538                                   GEDCOM_MAKE_NULL(val1));
2539                     }
2540                   ;
2541
2542 fam_even_wife_sect : OPEN DELIM TAG_WIFE
2543                      { $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_WIFE,
2544                                                 PARENT, $1, $3, NULL,
2545                                                 GEDCOM_MAKE_NULL(val1));
2546                        START(WIFE, $1, $<ctxt>$) 
2547                      }
2548                      fam_even_husb_subs
2549                      { CHECK1(AGE) }
2550                      CLOSE 
2551                      { end_element(ELT_SUB_FAM_EVT_WIFE, PARENT, $<ctxt>4,
2552                                    GEDCOM_MAKE_NULL(val1));
2553                      }
2554                    ;
2555
2556 fam_gen_even_sect : OPEN DELIM TAG_EVEN
2557                     { $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_EVEN,
2558                                                 PARENT, $1, $3, NULL,
2559                                                 GEDCOM_MAKE_NULL(val1));
2560                        START(EVEN, $1, $<ctxt>$) 
2561                     }
2562                     fam_gen_even_subs
2563                     { CHECK0 }
2564                     CLOSE 
2565                     { end_element(ELT_SUB_FAM_EVT_EVEN, PARENT, $<ctxt>4,
2566                                   GEDCOM_MAKE_NULL(val1));
2567                     }
2568                   ;
2569
2570 fam_gen_even_subs : /* empty */
2571                   | fam_gen_even_subs fam_gen_even_sub
2572                   ;
2573
2574 fam_gen_even_sub : event_detail_sub
2575                  | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
2576                  | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
2577                  | no_std_sub
2578                  ;
2579
2580 /* IDENTIFICATION STRUCTURE */
2581 ident_struc_sub : ident_refn_sect  /* 0:M */
2582                 | ident_rin_sect  { OCCUR2(RIN, 0, 1) }
2583                 ;
2584
2585 ident_refn_sect : OPEN DELIM TAG_REFN mand_line_item 
2586                   { $<ctxt>$ = start_element(ELT_SUB_IDENT_REFN,
2587                                              PARENT, $1, $3, $4,
2588                                              GEDCOM_MAKE_STRING(val1, $4));
2589                     START(REFN, $1, $<ctxt>$)  
2590                   }
2591                   ident_refn_subs
2592                   { CHECK0 }
2593                   CLOSE  
2594                   { end_element(ELT_SUB_IDENT_REFN, PARENT, $<ctxt>5,
2595                                 GEDCOM_MAKE_NULL(val1));
2596                   }
2597                 ;
2598
2599 ident_refn_subs : /* empty */
2600                 | ident_refn_subs ident_refn_sub
2601                 ;
2602
2603 ident_refn_sub  : ident_refn_type_sect  { OCCUR2(TYPE, 0, 1) }
2604                 | no_std_sub
2605                 ;
2606
2607 ident_refn_type_sect : OPEN DELIM TAG_TYPE mand_line_item   
2608                        { $<ctxt>$
2609                            = start_element(ELT_SUB_IDENT_REFN_TYPE,
2610                                            PARENT, $1, $3, $4,
2611                                            GEDCOM_MAKE_STRING(val1, $4));
2612                          START(TYPE, $1, $<ctxt>$)    
2613                        }    
2614                        no_std_subs    
2615                        { CHECK0 }    
2616                        CLOSE    
2617                        { end_element(ELT_SUB_IDENT_REFN_TYPE, PARENT, $<ctxt>5,
2618                                      GEDCOM_MAKE_NULL(val1));
2619                        }
2620                      ;
2621
2622 ident_rin_sect  : OPEN DELIM TAG_RIN mand_line_item   
2623                   { $<ctxt>$ = start_element(ELT_SUB_IDENT_RIN,
2624                                              PARENT, $1, $3, $4,
2625                                              GEDCOM_MAKE_STRING(val1, $4));
2626                     START(RIN, $1, $<ctxt>$)    
2627                   }    
2628                   no_std_subs    
2629                   { CHECK0 }    
2630                   CLOSE    
2631                   { end_element(ELT_SUB_IDENT_RIN, PARENT, $<ctxt>5,
2632                                 GEDCOM_MAKE_NULL(val1));
2633                   }
2634                 ;
2635
2636 /* INDIVIDUAL ATTRIBUTE STRUCTURE */
2637 indiv_attr_struc_sub : indiv_attr_sect   /* 0:M */
2638                      | indiv_resi_sect  /* 0:M */
2639                      ;
2640
2641 indiv_attr_sect : OPEN DELIM indiv_attr_tag mand_line_item
2642                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_ATTR,
2643                                              PARENT, $1, $3, $4,
2644                                              GEDCOM_MAKE_STRING(val1, $4));
2645                     START2($1, $<ctxt>$);
2646                   }
2647                   indiv_attr_event_subs
2648                   { CHECK0 }
2649                   CLOSE
2650                   { end_element(ELT_SUB_INDIV_ATTR, PARENT, $<ctxt>5,
2651                                 GEDCOM_MAKE_NULL(val1));
2652                   }
2653                 ;
2654
2655 indiv_attr_tag  : TAG_CAST { $$ = $1; START1(CAST) }
2656                 | TAG_DSCR { $$ = $1; START1(DSCR) }
2657                 | TAG_EDUC { $$ = $1; START1(EDUC) }
2658                 | TAG_IDNO { $$ = $1; START1(IDNO) }
2659                 | TAG_NATI { $$ = $1; START1(NATI) }
2660                 | TAG_NCHI { $$ = $1; START1(NCHI) }
2661                 | TAG_NMR  { $$ = $1; START1(NMR) }
2662                 | TAG_OCCU { $$ = $1; START1(OCCU) }
2663                 | TAG_PROP { $$ = $1; START1(PROP) }
2664                 | TAG_RELI { $$ = $1; START1(RELI) }
2665                 | TAG_SSN  { $$ = $1; START1(SSN) }
2666                 | TAG_TITL { $$ = $1; START1(TITL) }
2667                 ;
2668
2669 indiv_resi_sect : OPEN DELIM TAG_RESI 
2670                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_RESI,
2671                                              PARENT, $1, $3, NULL,
2672                                              GEDCOM_MAKE_NULL(val1));
2673                     START(RESI, $1, $<ctxt>$)  
2674                   }
2675                   indiv_attr_event_subs 
2676                   { CHECK0 }
2677                   CLOSE  
2678                   { end_element(ELT_SUB_INDIV_RESI, PARENT, $<ctxt>4,
2679                                 GEDCOM_MAKE_NULL(val1));
2680                   }
2681                 ;
2682
2683 indiv_attr_event_subs : /* empty */
2684                       | indiv_attr_event_subs indiv_attr_event_sub
2685                       ;
2686
2687 indiv_attr_event_sub  : event_detail_sub
2688                       | no_std_sub
2689                       ;
2690
2691 /* INDIVIDUAL EVENT STRUCTURE */
2692 indiv_even_struc_sub : indiv_birt_sect
2693                      | indiv_gen_sect
2694                      | indiv_adop_sect  /* 0:M */
2695                      | indiv_even_sect  /* 0:M */
2696                      ;
2697
2698 indiv_birt_sect : OPEN DELIM indiv_birt_tag opt_value 
2699                   { $<ctxt>$
2700                       = start_element(ELT_SUB_INDIV_BIRT,
2701                                       PARENT, $1, $3, $4,
2702                                       GEDCOM_MAKE_NULL_OR_STRING(val1, $4));
2703                     START2($1, $<ctxt>$);
2704                   }
2705                   indiv_birt_subs
2706                   { CHECK0 }
2707                   CLOSE 
2708                   { end_element(ELT_SUB_INDIV_BIRT, PARENT, $<ctxt>5,
2709                                 GEDCOM_MAKE_NULL(val1));
2710                   }
2711                 ;
2712
2713 indiv_birt_tag  : TAG_BIRT { $$ = $1; START1(BIRT) }
2714                 | TAG_CHR { $$ = $1; START1(CHR) }
2715                 ;
2716
2717 indiv_birt_subs : /* empty */
2718                 | indiv_birt_subs indiv_birt_sub
2719                 ;
2720
2721 indiv_birt_sub  : event_detail_sub
2722                 | indiv_birt_famc_sect  { OCCUR2(FAMC,0, 1) }
2723                 | no_std_sub
2724                 ;
2725
2726 indiv_birt_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2727                        { struct xref_value *xr = gedcom_parse_xref($4,
2728                                                                    XREF_USED,
2729                                                                    XREF_FAM);
2730                          if (xr == NULL) HANDLE_ERROR;
2731                          $<ctxt>$
2732                            = start_element(ELT_SUB_INDIV_BIRT_FAMC,
2733                                            PARENT, $1, $3, $4,
2734                                            GEDCOM_MAKE_XREF_PTR(val1, xr));
2735                          START(FAMC, $1, $<ctxt>$) 
2736                        } 
2737                        no_std_subs 
2738                        { CHECK0 } 
2739                        CLOSE 
2740                        { end_element(ELT_SUB_INDIV_BIRT_FAMC, PARENT, $<ctxt>5,
2741                                      GEDCOM_MAKE_NULL(val1));
2742                        }
2743                      ;
2744
2745 indiv_gen_sect  : OPEN DELIM indiv_gen_tag opt_value 
2746                   { $<ctxt>$
2747                       = start_element(ELT_SUB_INDIV_GEN,
2748                                       PARENT, $1, $3, $4,
2749                                       GEDCOM_MAKE_NULL_OR_STRING(val1, $4));
2750                     START2($1, $<ctxt>$);
2751                   }
2752                   indiv_gen_subs
2753                   { CHECK0 }
2754                   CLOSE 
2755                   { end_element(ELT_SUB_INDIV_GEN, PARENT, $<ctxt>5, 
2756                                 GEDCOM_MAKE_NULL(val1));
2757                   }
2758                 ;
2759
2760 indiv_gen_tag   : TAG_DEAT { $$ = $1; START1(DEAT) }
2761                 | TAG_BURI { $$ = $1; START1(BURI) }
2762                 | TAG_CREM { $$ = $1; START1(CREM) }
2763                 | TAG_BAPM { $$ = $1; START1(BAPM) }
2764                 | TAG_BARM { $$ = $1; START1(BARM) }
2765                 | TAG_BASM { $$ = $1; START1(BASM) }
2766                 | TAG_BLES { $$ = $1; START1(BLES) }
2767                 | TAG_CHRA { $$ = $1; START1(CHRA) }
2768                 | TAG_CONF { $$ = $1; START1(CONF) }
2769                 | TAG_FCOM { $$ = $1; START1(FCOM) }
2770                 | TAG_ORDN { $$ = $1; START1(ORDN) }
2771                 | TAG_NATU { $$ = $1; START1(NATU) }
2772                 | TAG_EMIG { $$ = $1; START1(EMIG) }
2773                 | TAG_IMMI { $$ = $1; START1(IMMI) }
2774                 | TAG_CENS { $$ = $1; START1(CENS) }
2775                 | TAG_PROB { $$ = $1; START1(PROB) }
2776                 | TAG_WILL { $$ = $1; START1(WILL) }
2777                 | TAG_GRAD { $$ = $1; START1(GRAD) }
2778                 | TAG_RETI { $$ = $1; START1(RETI) }
2779                 ;
2780
2781 indiv_gen_subs  : /* empty */
2782                 | indiv_gen_subs indiv_gen_sub
2783                 ;
2784
2785 indiv_gen_sub   : event_detail_sub
2786                 | no_std_sub
2787                 ;
2788
2789 indiv_adop_sect : OPEN DELIM TAG_ADOP opt_value 
2790                   { $<ctxt>$
2791                       = start_element(ELT_SUB_INDIV_ADOP,
2792                                       PARENT, $1, $3, $4,
2793                                       GEDCOM_MAKE_NULL_OR_STRING(val1, $4));
2794                     START(ADOP, $1, $<ctxt>$) }
2795                   indiv_adop_subs
2796                   { CHECK0 }
2797                   CLOSE 
2798                   { end_element(ELT_SUB_INDIV_ADOP, PARENT, $<ctxt>5, 
2799                                 GEDCOM_MAKE_NULL(val1));
2800                   }
2801                 ;
2802
2803 indiv_adop_subs : /* empty */
2804                 | indiv_adop_subs indiv_adop_sub
2805                 ;
2806
2807 indiv_adop_sub  : event_detail_sub
2808                 | indiv_adop_famc_sect  { OCCUR2(FAMC,0, 1) }
2809                 | no_std_sub
2810                 ;
2811
2812 indiv_adop_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2813                        { struct xref_value *xr = gedcom_parse_xref($4,
2814                                                                    XREF_USED,
2815                                                                    XREF_FAM);
2816                          if (xr == NULL) HANDLE_ERROR;
2817                          $<ctxt>$
2818                            = start_element(ELT_SUB_INDIV_ADOP_FAMC,
2819                                            PARENT, $1, $3, $4,
2820                                            GEDCOM_MAKE_XREF_PTR(val1, xr));
2821                          START(FAMC, $1, $<ctxt>$) }
2822                        indiv_adop_famc_subs
2823                        { CHECK0 }
2824                        CLOSE 
2825                        { end_element(ELT_SUB_INDIV_ADOP_FAMC, PARENT, $<ctxt>5,
2826                                      GEDCOM_MAKE_NULL(val1));
2827                        }
2828                      ;
2829
2830 indiv_adop_famc_subs : /* empty */
2831                      | indiv_adop_famc_subs indiv_adop_famc_sub
2832                      ;
2833
2834 indiv_adop_famc_sub  : indiv_adop_famc_adop_sect  { OCCUR2(ADOP,0, 1) }
2835                      | no_std_sub
2836                      ;
2837
2838 indiv_adop_famc_adop_sect : OPEN DELIM TAG_ADOP mand_line_item   
2839                             { $<ctxt>$
2840                                 = start_element(ELT_SUB_INDIV_ADOP_FAMC_ADOP,
2841                                                 PARENT, $1, $3, $4,
2842                                                 GEDCOM_MAKE_STRING(val1, $4));
2843                               START(ADOP, $1, $<ctxt>$) }    
2844                             no_std_subs    
2845                             { CHECK0 }    
2846                             CLOSE    
2847                             { end_element(ELT_SUB_INDIV_ADOP_FAMC_ADOP,
2848                                           PARENT, $<ctxt>5, 
2849                                           GEDCOM_MAKE_NULL(val1));
2850                             }
2851                           ;
2852
2853 indiv_even_sect : OPEN DELIM TAG_EVEN
2854                   { $<ctxt>$ = start_element(ELT_SUB_INDIV_EVEN,
2855                                              PARENT, $1, $3, NULL,
2856                                              GEDCOM_MAKE_NULL(val1));
2857                     START(EVEN, $1, $<ctxt>$) }
2858                   indiv_gen_subs
2859                   { CHECK0 }
2860                   CLOSE    
2861                   { end_element(ELT_SUB_INDIV_EVEN, PARENT, $<ctxt>4, 
2862                                 GEDCOM_MAKE_NULL(val1));
2863                   }
2864                 ;
2865
2866 /* LDS INDIVIDUAL ORDINANCE */
2867 lds_indiv_ord_sub : lio_bapl_sect  /* 0:M */
2868                   | lio_slgc_sect  /* 0:M */
2869                   ;
2870
2871 lio_bapl_sect : OPEN DELIM lio_bapl_tag 
2872                 { $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL,
2873                                            PARENT, $1, $3, NULL,
2874                                            GEDCOM_MAKE_NULL(val1));
2875                   START2($1, $<ctxt>$);
2876                 }
2877                 lio_bapl_subs
2878                 { CHECK0 }
2879                 CLOSE 
2880                 { end_element(ELT_SUB_LIO_BAPL, PARENT, $<ctxt>4, 
2881                               GEDCOM_MAKE_NULL(val1));
2882                 }
2883               ;
2884
2885 lio_bapl_tag  : TAG_BAPL { $$ = $1; START1(BAPL) }
2886               | TAG_CONL { $$ = $1; START1(CONL) }
2887               | TAG_ENDL { $$ = $1; START1(ENDL) }
2888               ;
2889
2890 lio_bapl_subs : /* empty */
2891               | lio_bapl_subs lio_bapl_sub
2892               ;
2893
2894 lio_bapl_sub  : lio_bapl_stat_sect  { OCCUR2(STAT, 0, 1) }
2895               | lio_bapl_date_sect  { OCCUR2(DATE, 0, 1) }
2896               | lio_bapl_temp_sect  { OCCUR2(TEMP, 0, 1) }
2897               | lio_bapl_plac_sect  { OCCUR2(PLAC, 0, 1) }
2898               | source_cit_sub
2899               | note_struc_sub
2900               | no_std_sub
2901               ;
2902
2903 lio_bapl_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
2904                      { $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL_STAT,
2905                                                 PARENT, $1, $3, $4,
2906                                                 GEDCOM_MAKE_STRING(val1, $4));
2907                        START(STAT, $1, $<ctxt>$)    
2908                      }    
2909                      no_std_subs    
2910                      { CHECK0 }    
2911                      CLOSE    
2912                      { end_element(ELT_SUB_LIO_BAPL_STAT, PARENT, $<ctxt>5,
2913                                    GEDCOM_MAKE_NULL(val1));
2914                      }
2915                    ;
2916 lio_bapl_date_sect : OPEN DELIM TAG_DATE mand_line_item   
2917                      { struct date_value dv = gedcom_parse_date($4);
2918                        $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL_DATE,
2919                                                 PARENT, $1, $3, $4,
2920                                                 GEDCOM_MAKE_DATE(val1, dv));
2921                        START(DATE, $1, $<ctxt>$)    
2922                      }    
2923                      no_std_subs    
2924                      { CHECK0 }    
2925                      CLOSE    
2926                      { end_element(ELT_SUB_LIO_BAPL_DATE, PARENT, $<ctxt>5,
2927                                    GEDCOM_MAKE_NULL(val1));
2928                      }
2929                    ;
2930 lio_bapl_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
2931                      { $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL_TEMP,
2932                                                 PARENT, $1, $3, $4,
2933                                                 GEDCOM_MAKE_STRING(val1, $4));
2934                        START(TEMP, $1, $<ctxt>$)    
2935                      }    
2936                      no_std_subs    
2937                      { CHECK0 }    
2938                      CLOSE    
2939                      { end_element(ELT_SUB_LIO_BAPL_TEMP, PARENT, $<ctxt>5,
2940                                    GEDCOM_MAKE_NULL(val1));
2941                      }
2942                    ;
2943 lio_bapl_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
2944                      { $<ctxt>$ = start_element(ELT_SUB_LIO_BAPL_PLAC,
2945                                                 PARENT, $1, $3, $4,
2946                                                 GEDCOM_MAKE_STRING(val1, $4));
2947                        START(PLAC, $1, $<ctxt>$)    
2948                      }    
2949                      no_std_subs    
2950                      { CHECK0 }    
2951                      CLOSE    
2952                      { end_element(ELT_SUB_LIO_BAPL_PLAC, PARENT, $<ctxt>5,
2953                                    GEDCOM_MAKE_NULL(val1));
2954                      }
2955                    ;
2956
2957 lio_slgc_sect : OPEN DELIM TAG_SLGC
2958                 { $<ctxt>$ = start_element(ELT_SUB_LIO_SLGC,
2959                                            PARENT, $1, $3, NULL,
2960                                            GEDCOM_MAKE_NULL(val1));
2961                   START(SLGC, $1, $<ctxt>$) 
2962                 }
2963                 lio_slgc_subs
2964                 { if (compat_mode(C_NO_SLGC_FAMC) && ! CHK_COND(FAMC))
2965                     compat_generate_slgc_famc_link($<ctxt>4);
2966                   else CHK(FAMC);
2967                   CHECK0;
2968                 }
2969                 CLOSE 
2970                 { end_element(ELT_SUB_LIO_SLGC, PARENT, $<ctxt>4, 
2971                               GEDCOM_MAKE_NULL(val1));
2972                 }
2973               ;
2974
2975 lio_slgc_subs : /* empty */
2976               | lio_slgc_subs lio_slgc_sub
2977               ;
2978
2979 lio_slgc_sub  : lio_bapl_sub
2980               | lio_slgc_famc_sect  { OCCUR2(FAMC, 1, 1) }
2981               ;
2982
2983 lio_slgc_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2984                      { struct xref_value *xr = gedcom_parse_xref($4, XREF_USED,
2985                                                                  XREF_FAM);
2986                        if (xr == NULL) HANDLE_ERROR;
2987                        $<ctxt>$
2988                          = start_element(ELT_SUB_LIO_SLGC_FAMC,
2989                                          PARENT, $1, $3, $4,
2990                                          GEDCOM_MAKE_XREF_PTR(val1, xr));
2991                        START(FAMC, $1, $<ctxt>$) 
2992                      } 
2993                      no_std_subs 
2994                      { CHECK0 } 
2995                      CLOSE 
2996                      { end_element(ELT_SUB_LIO_SLGC_FAMC, PARENT, $<ctxt>5,
2997                                    GEDCOM_MAKE_NULL(val1));
2998                      }
2999                    ;
3000
3001 /* LDS SPOUSE SEALING */
3002 lds_spouse_seal_sub : lss_slgs_sect
3003                     ;
3004
3005 lss_slgs_sect : OPEN DELIM TAG_SLGS
3006                 { $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS,
3007                                            PARENT, $1, $3, NULL,
3008                                            GEDCOM_MAKE_NULL(val1));
3009                   START(SLGS, $1, $<ctxt>$) }
3010                 lss_slgs_subs
3011                 { CHECK0 }
3012                 CLOSE 
3013                 { end_element(ELT_SUB_LIO_SLGC, PARENT, $<ctxt>4, 
3014                               GEDCOM_MAKE_NULL(val1));
3015                 }
3016               ;
3017
3018 lss_slgs_subs : /* empty */
3019               | lss_slgs_subs lss_slgs_sub
3020               ;
3021
3022 lss_slgs_sub  : lss_slgs_stat_sect  { OCCUR2(STAT, 0, 1) }
3023               | lss_slgs_date_sect  { OCCUR2(DATE, 0, 1) }
3024               | lss_slgs_temp_sect  { OCCUR2(TEMP, 0, 1) }
3025               | lss_slgs_plac_sect  { OCCUR2(PLAC, 0, 1) }
3026               | source_cit_sub
3027               | note_struc_sub
3028               | no_std_sub
3029               ;
3030
3031 lss_slgs_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
3032                      { $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS_STAT,
3033                                                 PARENT, $1, $3, $4,
3034                                                 GEDCOM_MAKE_STRING(val1, $4));
3035                        START(STAT, $1, $<ctxt>$)    
3036                      }    
3037                      no_std_subs    
3038                      { CHECK0 }    
3039                      CLOSE    
3040                      { end_element(ELT_SUB_LSS_SLGS_STAT, PARENT, $<ctxt>5,
3041                                    GEDCOM_MAKE_NULL(val1));
3042                      }
3043                    ;
3044 lss_slgs_date_sect : OPEN DELIM TAG_DATE mand_line_item   
3045                      { struct date_value dv = gedcom_parse_date($4);
3046                        $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS_DATE,
3047                                                 PARENT, $1, $3, $4,
3048                                                 GEDCOM_MAKE_DATE(val1, dv));
3049                        START(DATE, $1, $<ctxt>$)    
3050                      }    
3051                      no_std_subs    
3052                      { CHECK0 }    
3053                      CLOSE    
3054                      { end_element(ELT_SUB_LSS_SLGS_DATE, PARENT, $<ctxt>5,
3055                                    GEDCOM_MAKE_NULL(val1));
3056                      }
3057                    ;
3058 lss_slgs_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
3059                      { $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS_TEMP,
3060                                                 PARENT, $1, $3, $4,
3061                                                 GEDCOM_MAKE_STRING(val1, $4));
3062                        START(TEMP, $1, $<ctxt>$)    
3063                      }    
3064                      no_std_subs    
3065                      { CHECK0 }    
3066                      CLOSE    
3067                      { end_element(ELT_SUB_LSS_SLGS_TEMP, PARENT, $<ctxt>5,
3068                                    GEDCOM_MAKE_NULL(val1));
3069                      }
3070                    ;
3071 lss_slgs_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
3072                      { $<ctxt>$ = start_element(ELT_SUB_LSS_SLGS_PLAC,
3073                                                 PARENT, $1, $3, $4,
3074                                                 GEDCOM_MAKE_STRING(val1, $4));
3075                        START(PLAC, $1, $<ctxt>$)    
3076                      }    
3077                      no_std_subs    
3078                      { CHECK0 }    
3079                      CLOSE    
3080                      { end_element(ELT_SUB_LSS_SLGS_PLAC, PARENT, $<ctxt>5,
3081                                    GEDCOM_MAKE_NULL(val1));
3082                      }
3083                    ;
3084
3085 /* MULTIMEDIA LINK */
3086 multim_link_sub : multim_obje_link_sect
3087                 | multim_obje_emb_sect
3088                 ;
3089
3090 multim_obje_link_sect : OPEN DELIM TAG_OBJE DELIM POINTER    
3091                         { struct xref_value *xr = gedcom_parse_xref($5,
3092                                                                     XREF_USED,
3093                                                                     XREF_OBJE);
3094                           if (xr == NULL) HANDLE_ERROR;
3095                           $<ctxt>$
3096                             = start_element(ELT_SUB_MULTIM_OBJE,
3097                                             PARENT, $1, $3, $5,
3098                                             GEDCOM_MAKE_XREF_PTR(val1, xr));
3099                           START(OBJE, $1, $<ctxt>$)     
3100                         }     
3101                         no_std_subs     
3102                         { CHECK0 }     
3103                         CLOSE     
3104                         { end_element(ELT_SUB_MULTIM_OBJE, PARENT, $<ctxt>6,
3105                                       GEDCOM_MAKE_NULL(val1));
3106                         }
3107                       ;
3108
3109 multim_obje_emb_sect : OPEN DELIM TAG_OBJE
3110                        { $<ctxt>$ = start_element(ELT_SUB_MULTIM_OBJE,
3111                                                   PARENT, $1, $3, NULL,
3112                                                   GEDCOM_MAKE_NULL(val1));
3113                          START(OBJE, $1, $<ctxt>$) 
3114                        }
3115                        multim_obje_emb_subs
3116                        { CHECK2(FORM,FILE) }
3117                        CLOSE 
3118                        { end_element(ELT_SUB_MULTIM_OBJE, PARENT, $<ctxt>4,
3119                                      GEDCOM_MAKE_NULL(val1));
3120                        }
3121                      ;
3122
3123 multim_obje_emb_subs : /* empty */
3124                      | multim_obje_emb_subs multim_obje_emb_sub
3125                      ;
3126
3127 multim_obje_emb_sub : multim_obje_form_sect  { OCCUR2(FORM, 1, 1) }
3128                     | multim_obje_titl_sect  { OCCUR2(TITL, 0, 1) }
3129                     | multim_obje_file_sect  { OCCUR2(FILE, 1, 1) }
3130                     | note_struc_sub
3131                     | no_std_sub
3132                     ;
3133
3134 multim_obje_form_sect : OPEN DELIM TAG_FORM mand_line_item    
3135                         { $<ctxt>$
3136                             = start_element(ELT_SUB_MULTIM_OBJE_FORM,
3137                                             PARENT, $1, $3, $4,
3138                                             GEDCOM_MAKE_STRING(val1, $4));
3139                           START(FORM, $1, $<ctxt>$)     
3140                         }     
3141                         no_std_subs     
3142                         { CHECK0 }     
3143                         CLOSE     
3144                         { end_element(ELT_SUB_MULTIM_OBJE_FORM,
3145                                       PARENT, $<ctxt>5, 
3146                                       GEDCOM_MAKE_NULL(val1));
3147                         }
3148                       ;
3149 multim_obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item    
3150                         { $<ctxt>$
3151                             = start_element(ELT_SUB_MULTIM_OBJE_TITL,
3152                                             PARENT, $1, $3, $4,
3153                                             GEDCOM_MAKE_STRING(val1, $4));
3154                           START(TITL, $1, $<ctxt>$)     
3155                         }     
3156                         no_std_subs     
3157                         { CHECK0 }     
3158                         CLOSE     
3159                         { end_element(ELT_SUB_MULTIM_OBJE_TITL,
3160                                       PARENT, $<ctxt>5, 
3161                                       GEDCOM_MAKE_NULL(val1));
3162                         }
3163                       ;
3164 multim_obje_file_sect : OPEN DELIM TAG_FILE mand_line_item    
3165                         { $<ctxt>$
3166                             = start_element(ELT_SUB_MULTIM_OBJE_FILE,
3167                                             PARENT, $1, $3, $4,
3168                                             GEDCOM_MAKE_STRING(val1, $4));
3169                           START(FILE, $1, $<ctxt>$)     
3170                         }     
3171                         no_std_subs     
3172                         { CHECK0 }     
3173                         CLOSE     
3174                         { end_element(ELT_SUB_MULTIM_OBJE_FILE,
3175                                       PARENT, $<ctxt>5, 
3176                                       GEDCOM_MAKE_NULL(val1));
3177                         }
3178                       ;
3179
3180 /* NOTE STRUCTURE */
3181 note_struc_sub : note_struc_link_sect  /* 0:M */
3182                | note_struc_emb_sect  /* 0:M */
3183                ;
3184
3185 note_struc_link_sect : OPEN DELIM TAG_NOTE DELIM POINTER
3186                        { struct xref_value *xr = gedcom_parse_xref($5,
3187                                                                    XREF_USED,
3188                                                                    XREF_NOTE);
3189                          if (xr == NULL) HANDLE_ERROR;
3190                          $<ctxt>$
3191                            = start_element(ELT_SUB_NOTE,
3192                                            PARENT, $1, $3, $5,
3193                                            GEDCOM_MAKE_XREF_PTR(val1, xr));
3194                          START(NOTE, $1, $<ctxt>$) 
3195                        }
3196                        note_struc_link_subs
3197                        { CHECK0 }
3198                        CLOSE 
3199                        { end_element(ELT_SUB_NOTE, PARENT, $<ctxt>6, 
3200                                      GEDCOM_MAKE_NULL(val1));
3201                        }
3202                      ;
3203
3204 note_struc_link_subs : /* empty */
3205                      | note_struc_link_subs note_struc_link_sub
3206                      ;
3207
3208 note_struc_link_sub : source_cit_sub
3209                     | no_std_sub
3210                     ;
3211
3212 note_struc_emb_sect : OPEN DELIM TAG_NOTE opt_line_item
3213                       { char* str = $4;
3214                         if (compat_mode(C_NOTE_TOO_LONG))
3215                           str = compat_long_line_get_prefix($4);
3216                         $<ctxt>$
3217                           = start_element(ELT_SUB_NOTE,
3218                                           PARENT, $1, $3, str,
3219                                         GEDCOM_MAKE_NULL_OR_STRING(val1, str));
3220                         reset_buffer(&concat_buffer);
3221                         if ($4)
3222                           safe_buf_append(&concat_buffer, $4);
3223                         START(NOTE, $1, $<ctxt>$);
3224                         if (compat_mode(C_NOTE_TOO_LONG))
3225                           compat_long_line_finish($<ctxt>$, $1);
3226                       }
3227                       note_struc_emb_subs
3228                       { CHECK0 }
3229                       CLOSE 
3230                       { char* complete = get_buf_string(&concat_buffer);
3231                         end_element(ELT_SUB_NOTE, PARENT, $<ctxt>5,
3232                                     GEDCOM_MAKE_STRING(val1, complete));
3233                       }
3234                     ;
3235
3236 note_struc_emb_subs : /* empty */
3237                     | note_struc_emb_subs note_struc_emb_sub
3238                     ;
3239
3240 note_struc_emb_sub  : continuation_sub
3241                     | source_cit_sub
3242                     | no_std_sub
3243                     ;
3244
3245 /* PERSONAL NAME STRUCTURE */
3246 pers_name_struc_sub : pers_name_sect /* 0:M */
3247                     ;
3248
3249 pers_name_sect : OPEN DELIM TAG_NAME mand_line_item 
3250                  { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME,
3251                                             PARENT, $1, $3, $4,
3252                                             GEDCOM_MAKE_STRING(val1, $4));
3253                    START(NAME, $1, $<ctxt>$)  
3254                  }
3255                  pers_name_subs
3256                  { CHECK0 }
3257                  CLOSE  
3258                  { end_element(ELT_SUB_PERS_NAME, PARENT, $<ctxt>5, 
3259                                GEDCOM_MAKE_NULL(val1));
3260                  }
3261                ;
3262
3263 pers_name_subs : /* empty */
3264                | pers_name_subs pers_name_sub
3265                ;
3266
3267 pers_name_sub  : pers_name_npfx_sect  { OCCUR2(NPFX, 0, 1) }
3268                | pers_name_givn_sect  { OCCUR2(GIVN, 0, 1) }
3269                | pers_name_nick_sect  { OCCUR2(NICK, 0, 1) }
3270                | pers_name_spfx_sect  { OCCUR2(SPFX, 0, 1) }
3271                | pers_name_surn_sect  { OCCUR2(SURN, 0, 1) }
3272                | pers_name_nsfx_sect  { OCCUR2(NSFX, 0, 1) }
3273                | source_cit_sub
3274                | note_struc_sub
3275                | no_std_sub
3276                ;
3277
3278 pers_name_npfx_sect : OPEN DELIM TAG_NPFX mand_line_item    
3279                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_NPFX,
3280                                                  PARENT, $1, $3, $4,
3281                                                  GEDCOM_MAKE_STRING(val1, $4));
3282                         START(NPFX, $1, $<ctxt>$)     
3283                       }     
3284                       no_std_subs     
3285                       { CHECK0 }     
3286                       CLOSE     
3287                       { end_element(ELT_SUB_PERS_NAME_NPFX, PARENT, $<ctxt>5,
3288                                     GEDCOM_MAKE_NULL(val1));
3289                       }
3290                     ;
3291 pers_name_givn_sect : OPEN DELIM TAG_GIVN mand_line_item    
3292                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_GIVN,
3293                                                  PARENT, $1, $3, $4,
3294                                                  GEDCOM_MAKE_STRING(val1, $4));
3295                         START(GIVN, $1, $<ctxt>$)     
3296                       }     
3297                       no_std_subs     
3298                       { CHECK0 }     
3299                       CLOSE     
3300                       { end_element(ELT_SUB_PERS_NAME_GIVN, PARENT, $<ctxt>5,
3301                                     GEDCOM_MAKE_NULL(val1));
3302                       }
3303                     ;
3304 pers_name_nick_sect : OPEN DELIM TAG_NICK mand_line_item    
3305                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_NICK,
3306                                                  PARENT, $1, $3, $4,
3307                                                  GEDCOM_MAKE_STRING(val1, $4));
3308                         START(NICK, $1, $<ctxt>$)     
3309                       }     
3310                       no_std_subs     
3311                       { CHECK0 }     
3312                       CLOSE     
3313                       { end_element(ELT_SUB_PERS_NAME_NICK, PARENT, $<ctxt>5,
3314                                     GEDCOM_MAKE_NULL(val1));
3315                       }
3316                     ;
3317 pers_name_spfx_sect : OPEN DELIM TAG_SPFX mand_line_item    
3318                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_SPFX,
3319                                                  PARENT, $1, $3, $4,
3320                                                  GEDCOM_MAKE_STRING(val1, $4));
3321                         START(SPFX, $1, $<ctxt>$)     
3322                       }     
3323                       no_std_subs     
3324                       { CHECK0 }     
3325                       CLOSE     
3326                       { end_element(ELT_SUB_PERS_NAME_SPFX, PARENT, $<ctxt>5,
3327                                     GEDCOM_MAKE_NULL(val1));
3328                       }
3329                     ;
3330 pers_name_surn_sect : OPEN DELIM TAG_SURN mand_line_item    
3331                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_SURN,
3332                                                  PARENT, $1, $3, $4,
3333                                                  GEDCOM_MAKE_STRING(val1, $4));
3334                         START(SURN, $1, $<ctxt>$)     
3335                       }     
3336                       no_std_subs     
3337                       { CHECK0 }     
3338                       CLOSE     
3339                       { end_element(ELT_SUB_PERS_NAME_SURN, PARENT, $<ctxt>5,
3340                                     GEDCOM_MAKE_NULL(val1));
3341                       }
3342                     ;
3343 pers_name_nsfx_sect : OPEN DELIM TAG_NSFX mand_line_item    
3344                       { $<ctxt>$ = start_element(ELT_SUB_PERS_NAME_NSFX,
3345                                                  PARENT, $1, $3, $4,
3346                                                  GEDCOM_MAKE_STRING(val1, $4));
3347                         START(NSFX, $1, $<ctxt>$)     
3348                       }     
3349                       no_std_subs     
3350                       { CHECK0 }     
3351                       CLOSE     
3352                       { end_element(ELT_SUB_PERS_NAME_NSFX, PARENT, $<ctxt>5,
3353                                     GEDCOM_MAKE_NULL(val1));
3354                       }
3355                     ;
3356
3357 /* PLACE STRUCTURE */
3358 place_struc_sub : place_struc_plac_sect /* 0:M */
3359                 ;
3360
3361 place_struc_plac_sect : OPEN DELIM TAG_PLAC mand_line_item 
3362                         { $<ctxt>$
3363                             = start_element(ELT_SUB_PLAC,
3364                                             PARENT, $1, $3, $4,
3365                                             GEDCOM_MAKE_STRING(val1, $4));
3366                           START(PLAC, $1, $<ctxt>$)  
3367                         }
3368                         place_struc_plac_subs
3369                         { CHECK0 }
3370                         CLOSE  
3371                         { end_element(ELT_SUB_PLAC, PARENT, $<ctxt>5, 
3372                                       GEDCOM_MAKE_NULL(val1));
3373                         }
3374                       ;
3375
3376 place_struc_plac_subs : /* empty */
3377                       | place_struc_plac_subs place_struc_plac_sub
3378                       ;
3379
3380 place_struc_plac_sub : place_plac_form_sect  { OCCUR2(FORM, 0, 1) }
3381                      | source_cit_sub
3382                      | note_struc_sub
3383                      | no_std_sub
3384                      ;
3385
3386 place_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item    
3387                        { $<ctxt>$
3388                            = start_element(ELT_SUB_PLAC_FORM,
3389                                            PARENT, $1, $3, $4,
3390                                            GEDCOM_MAKE_STRING(val1, $4));
3391                          START(FORM, $1, $<ctxt>$)     
3392                        }     
3393                        no_std_subs     
3394                        { CHECK0 }     
3395                        CLOSE     
3396                        { end_element(ELT_SUB_PLAC_FORM, PARENT, $<ctxt>5,
3397                                      GEDCOM_MAKE_NULL(val1));
3398                        }
3399                      ;
3400
3401 /* SOURCE_CITATION */
3402 source_cit_sub : source_cit_link_sect /* 0:M */
3403                | source_cit_emb_sect /* 0:M */
3404                ;
3405
3406 source_cit_link_sect : OPEN DELIM TAG_SOUR DELIM POINTER
3407                        { struct xref_value *xr = gedcom_parse_xref($5,
3408                                                                    XREF_USED,
3409                                                                    XREF_SOUR);
3410                          if (xr == NULL) HANDLE_ERROR;
3411                          $<ctxt>$
3412                            = start_element(ELT_SUB_SOUR,
3413                                            PARENT, $1, $3, $5,
3414                                            GEDCOM_MAKE_XREF_PTR(val1, xr));
3415                          START(SOUR, $1, $<ctxt>$) 
3416                        }
3417                        source_cit_link_subs
3418                        { CHECK0 }
3419                        CLOSE 
3420                        { end_element(ELT_SUB_SOUR, PARENT, $<ctxt>6, 
3421                                      GEDCOM_MAKE_NULL(val1));
3422                        }
3423                      ;
3424
3425 source_cit_link_subs : /* empty */
3426                      | source_cit_link_subs source_cit_link_sub
3427                      ;
3428
3429 source_cit_link_sub : source_cit_page_sect  { OCCUR2(PAGE, 0, 1) }
3430                     | source_cit_even_sect  { OCCUR2(EVEN, 0, 1) }
3431                     | source_cit_data_sect  { OCCUR2(DATA, 0, 1) }
3432                     | source_cit_quay_sect  { OCCUR2(QUAY, 0, 1) }
3433                     | multim_link_sub
3434                     | note_struc_sub
3435                     | no_std_sub
3436                     ;
3437
3438 source_cit_page_sect : OPEN DELIM TAG_PAGE mand_line_item    
3439                        { $<ctxt>$
3440                            = start_element(ELT_SUB_SOUR_PAGE,
3441                                            PARENT, $1, $3, $4,
3442                                            GEDCOM_MAKE_STRING(val1, $4));
3443                          START(PAGE, $1, $<ctxt>$)     
3444                        }     
3445                        no_std_subs     
3446                        { CHECK0 }     
3447                        CLOSE     
3448                        { end_element(ELT_SUB_SOUR_PAGE, PARENT, $<ctxt>5,
3449                                      GEDCOM_MAKE_NULL(val1));
3450                        }
3451                      ;
3452
3453 source_cit_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
3454                        { $<ctxt>$
3455                            = start_element(ELT_SUB_SOUR_EVEN,
3456                                            PARENT, $1, $3, $4,
3457                                            GEDCOM_MAKE_STRING(val1, $4));
3458                          START(EVEN, $1, $<ctxt>$)     
3459                        }
3460                        source_cit_even_subs
3461                        { CHECK0 }
3462                        CLOSE     
3463                        { end_element(ELT_SUB_SOUR_EVEN, PARENT, $<ctxt>5,
3464                                      GEDCOM_MAKE_NULL(val1));
3465                        }
3466                      ;
3467
3468 source_cit_even_subs : /* empty */
3469                      | source_cit_even_subs source_cit_even_sub
3470                      ;
3471
3472 source_cit_even_sub  : source_cit_even_role_sect  { OCCUR2(ROLE, 0, 1) }
3473                      | no_std_sub
3474                      ;
3475
3476 source_cit_even_role_sect : OPEN DELIM TAG_ROLE mand_line_item    
3477                           { $<ctxt>$
3478                               = start_element(ELT_SUB_SOUR_EVEN_ROLE,
3479                                               PARENT, $1, $3, $4,
3480                                               GEDCOM_MAKE_STRING(val1, $4));
3481                             START(ROLE, $1, $<ctxt>$)     
3482                           }     
3483                           no_std_subs     
3484                           { CHECK0 }     
3485                           CLOSE     
3486                           { end_element(ELT_SUB_SOUR_EVEN_ROLE,
3487                                         PARENT, $<ctxt>5, 
3488                                         GEDCOM_MAKE_NULL(val1));
3489                           }
3490                           ;
3491
3492 source_cit_data_sect : OPEN DELIM TAG_DATA
3493                        { $<ctxt>$ = start_element(ELT_SUB_SOUR_DATA,
3494                                                   PARENT, $1, $3, NULL,
3495                                                   GEDCOM_MAKE_NULL(val1));
3496                          START(DATA, $1, $<ctxt>$) 
3497                        }
3498                        source_cit_data_subs
3499                        { CHECK0 }
3500                        CLOSE 
3501                        { end_element(ELT_SUB_SOUR_DATA, PARENT, $<ctxt>4,
3502                                      GEDCOM_MAKE_NULL(val1));
3503                        }
3504                      ;
3505
3506 source_cit_data_subs : /* empty */
3507                      | source_cit_data_subs source_cit_data_sub
3508                      ;
3509
3510 source_cit_data_sub : source_cit_data_date_sect  { OCCUR2(DATE, 0, 1) }
3511                     | source_cit_text_sect  /* 0:M */
3512                     | no_std_sub
3513                     ;
3514
3515 source_cit_data_date_sect : OPEN DELIM TAG_DATE mand_line_item    
3516                             { struct date_value dv = gedcom_parse_date($4);
3517                               $<ctxt>$
3518                                 = start_element(ELT_SUB_SOUR_DATA_DATE,
3519                                                 PARENT, $1, $3, $4,
3520                                                 GEDCOM_MAKE_DATE(val1, dv));
3521                               START(DATE, $1, $<ctxt>$)     
3522                             }     
3523                             no_std_subs     
3524                             { CHECK0 }     
3525                             CLOSE     
3526                             { end_element(ELT_SUB_SOUR_DATA_DATE,
3527                                           PARENT, $<ctxt>5, 
3528                                           GEDCOM_MAKE_NULL(val1));
3529                             }
3530                           ;
3531
3532 source_cit_text_sect : OPEN DELIM TAG_TEXT mand_line_item 
3533                        { $<ctxt>$
3534                            = start_element(ELT_SUB_SOUR_TEXT,
3535                                            PARENT, $1, $3, $4,
3536                                            GEDCOM_MAKE_STRING(val1, $4));
3537                         reset_buffer(&concat_buffer);
3538                         safe_buf_append(&concat_buffer, $4);
3539                         START(TEXT, $1, $<ctxt>$)  
3540                        }
3541                        source_cit_text_subs
3542                        { CHECK0 }
3543                        CLOSE  
3544                        { char* complete = get_buf_string(&concat_buffer);
3545                          end_element(ELT_SUB_SOUR_TEXT, PARENT, $<ctxt>5,
3546                                      GEDCOM_MAKE_STRING(val1, complete));
3547                        }
3548                      ;
3549
3550 source_cit_text_subs : /* empty */
3551                      | source_cit_text_subs source_cit_text_sub
3552                      ;
3553
3554 source_cit_text_sub : continuation_sub
3555                     | no_std_sub
3556                     ;
3557
3558 source_cit_quay_sect : OPEN DELIM TAG_QUAY mand_line_item    
3559                        { $<ctxt>$
3560                            = start_element(ELT_SUB_SOUR_QUAY,
3561                                            PARENT, $1, $3, $4,
3562                                            GEDCOM_MAKE_STRING(val1, $4));
3563                          START(QUAY, $1, $<ctxt>$)     
3564                        }     
3565                        no_std_subs     
3566                        { CHECK0 }     
3567                        CLOSE     
3568                        { end_element(ELT_SUB_SOUR_QUAY, PARENT, $<ctxt>5,
3569                                      GEDCOM_MAKE_NULL(val1));
3570                        }
3571                      ;
3572
3573 source_cit_emb_sect : OPEN DELIM TAG_SOUR mand_line_item
3574                       { $<ctxt>$ = start_element(ELT_SUB_SOUR,
3575                                                  PARENT, $1, $3, $4,
3576                                                  GEDCOM_MAKE_STRING(val1, $4));
3577                         reset_buffer(&concat_buffer);
3578                         safe_buf_append(&concat_buffer, $4);
3579                         START(SOUR, $1, $<ctxt>$) 
3580                       }
3581                       source_cit_emb_subs
3582                       { CHECK0 }
3583                       CLOSE 
3584                       { char* complete = get_buf_string(&concat_buffer);
3585                         end_element(ELT_SUB_SOUR, PARENT, $<ctxt>5,
3586                                     GEDCOM_MAKE_STRING(val1, complete));
3587                       }
3588                     ;
3589
3590 source_cit_emb_subs : /* empty */
3591                     | source_cit_emb_subs source_cit_emb_sub
3592                     ;
3593
3594 source_cit_emb_sub : continuation_sub
3595                    | source_cit_text_sect  /* 0:M */
3596                    | note_struc_sub
3597                    | no_std_sub
3598                    ;
3599
3600 /* SOURCE REPOSITORY CITATION */
3601 source_repos_cit_sub : source_repos_repo_sect  { OCCUR2(REPO, 0, 1) }
3602                      ;
3603
3604 source_repos_repo_sect : OPEN DELIM TAG_REPO mand_pointer
3605                          { struct xref_value *xr
3606                              = gedcom_parse_xref($4, XREF_USED, XREF_REPO);
3607                            if (xr == NULL) HANDLE_ERROR;
3608                            $<ctxt>$
3609                              = start_element(ELT_SUB_REPO,
3610                                              PARENT, $1, $3, $4,
3611                                              GEDCOM_MAKE_XREF_PTR(val1, xr));
3612                            START(REPO, $1, $<ctxt>$) 
3613                          }
3614                          source_repos_repo_subs
3615                          { CHECK0 }
3616                          CLOSE 
3617                          { end_element(ELT_SUB_REPO, PARENT, $<ctxt>5, 
3618                                        GEDCOM_MAKE_NULL(val1));
3619                          }
3620                        ;
3621
3622 source_repos_repo_subs : /* empty */
3623                        | source_repos_repo_subs source_repos_repo_sub
3624                        ;
3625
3626 source_repos_repo_sub  : note_struc_sub
3627                        | caln_sect  /* 0:M */
3628                        | no_std_sub
3629                        ;
3630
3631 caln_sect : OPEN DELIM TAG_CALN mand_line_item 
3632             { $<ctxt>$ = start_element(ELT_SUB_REPO_CALN,
3633                                        PARENT, $1, $3, $4,
3634                                        GEDCOM_MAKE_STRING(val1, $4));
3635               START(CALN, $1, $<ctxt>$) 
3636             }
3637             caln_subs
3638             { CHECK0 }
3639             CLOSE  
3640             { end_element(ELT_SUB_REPO_CALN, PARENT, $<ctxt>5, 
3641                           GEDCOM_MAKE_NULL(val1));
3642             }
3643           ;
3644
3645 caln_subs : /* empty */
3646           | caln_subs caln_sub
3647           ;
3648
3649 caln_sub  : caln_medi_sect  { OCCUR2(MEDI, 0, 1) }
3650           | no_std_sub
3651           ;
3652
3653 caln_medi_sect : OPEN DELIM TAG_MEDI mand_line_item    
3654                  { $<ctxt>$ = start_element(ELT_SUB_REPO_CALN_MEDI,
3655                                             PARENT, $1, $3, $4,
3656                                             GEDCOM_MAKE_STRING(val1, $4));
3657                    START(MEDI, $1, $<ctxt>$)  
3658                  }   
3659                  no_std_subs   
3660                  { CHECK0 }   
3661                  CLOSE   
3662                  { end_element(ELT_SUB_REPO_CALN_MEDI, PARENT, $<ctxt>5, 
3663                                GEDCOM_MAKE_NULL(val1));
3664                  }
3665                ;
3666  
3667 /* SPOUSE TO FAMILY LINK */
3668 spou_fam_link_sub : spou_fam_fams_sect  /* 0:M */
3669                   ;
3670
3671 spou_fam_fams_sect : OPEN DELIM TAG_FAMS mand_pointer
3672                      { struct xref_value *xr = gedcom_parse_xref($4, XREF_USED,
3673                                                                  XREF_FAM);
3674                        if (xr == NULL) HANDLE_ERROR;
3675                        $<ctxt>$
3676                          = start_element(ELT_SUB_FAMS,
3677                                          PARENT, $1, $3, $4,
3678                                          GEDCOM_MAKE_XREF_PTR(val1, xr));
3679                        START(FAMS, $1, $<ctxt>$) 
3680                      }
3681                      spou_fam_fams_subs
3682                      { CHECK0 }
3683                      CLOSE 
3684                      { end_element(ELT_SUB_FAMS, PARENT, $<ctxt>5, 
3685                                    GEDCOM_MAKE_NULL(val1));
3686                      }
3687                    ;
3688
3689 spou_fam_fams_subs : /* empty */
3690                    | spou_fam_fams_subs spou_fam_fams_sub
3691                    ;
3692
3693 spou_fam_fams_sub  : note_struc_sub
3694                    | no_std_sub
3695                    ;
3696
3697 /*********************************************************************/
3698 /**** General                                                     ****/
3699 /*********************************************************************/
3700
3701 no_std_subs : /* empty */
3702             | no_std_subs no_std_sub
3703             ;
3704
3705 no_std_sub  : user_sect /* 0:M */
3706             | gen_sect
3707             | error error_subs
3708               CLOSE  { HANDLE_ERROR }
3709             ;
3710
3711 no_std_rec  : user_rec /* 0:M */
3712             | gen_rec
3713             | error error_subs
3714               CLOSE  { HANDLE_ERROR }
3715             ;
3716
3717 user_rec    : OPEN DELIM opt_xref USERTAG
3718               { if ($4.string[0] != '_') {
3719                   if (compat_mode(C_551_TAGS)
3720                       && compat_check_551_tag($4.string, &usertag_buffer)) {
3721                     $4.string = get_buf_string(&usertag_buffer);
3722                   }
3723                   else {                  
3724                     gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
3725                                  $4);
3726                     YYERROR;
3727                   }
3728                 }
3729               }
3730               opt_value
3731               { struct xref_value *xr = NULL;
3732                 if ($3 != NULL) {
3733                   xr = gedcom_parse_xref($3, XREF_DEFINED, XREF_USER);
3734                   if (xr == NULL) HANDLE_ERROR;
3735                 }
3736                 $<ctxt>$ = start_record(REC_USER,
3737                                         $1,
3738                                         GEDCOM_MAKE_NULL_OR_XREF_PTR(val1, xr),
3739                                         $4, $6, &val2);
3740                 START($4, $1, $<ctxt>$)
3741               }
3742               user_sects
3743               { CHECK0 }
3744               CLOSE
3745               { end_record(REC_USER, $<ctxt>7, GEDCOM_MAKE_NULL(val1)); }
3746             ;
3747 user_sect   : OPEN DELIM opt_xref USERTAG
3748               { if ($4.string[0] != '_') {
3749                   if (compat_mode(C_551_TAGS)
3750                       && compat_check_551_tag($4.string, &usertag_buffer)) {
3751                     $4.string = get_buf_string(&usertag_buffer);
3752                   }
3753                   else if (compat_mode(C_SUBM_COMM) &&
3754                            compat_check_subm_comm($4.string, get_parenttag(0),
3755                                                   &usertag_buffer)) {
3756                     $4.string = get_buf_string(&usertag_buffer);
3757                   }
3758                   else {
3759                     gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
3760                                  $4);
3761                     YYERROR;
3762                   }
3763                 }
3764               }
3765               opt_value
3766               { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6, &val2);
3767                 START($4, $1, $<ctxt>$);
3768               }
3769               user_sects
3770               { CHECK0 }
3771               CLOSE
3772               { end_element(ELT_USER, PARENT, $<ctxt>7, 
3773                             GEDCOM_MAKE_NULL(val1));
3774                 if (compat_mode(C_SUBM_COMM))
3775                   compat_close_subm_comm();
3776               }
3777             ;
3778
3779 user_sects   : /* empty */     { }
3780             | user_sects user_sect { }
3781             | user_sects gen_sect
3782               { if (compat_mode(C_SUBM_COMM)) {
3783                 }
3784                 else {
3785                   gedcom_error(_("Standard tag not allowed in user section"));
3786                   YYERROR;
3787                 }
3788               }
3789             ;
3790
3791 opt_xref    : /* empty */        { $$ = NULL; }
3792             | POINTER DELIM        { $$ = $1; }
3793             ;
3794
3795 opt_value   : /* empty */        { GEDCOM_MAKE_NULL(val2);
3796                                    $$ = NULL; }
3797             | DELIM POINTER      { struct xref_value *xr
3798                                      = gedcom_parse_xref($2, XREF_USED,
3799                                                          XREF_USER);
3800                                    GEDCOM_MAKE_XREF_PTR(val2, xr);
3801                                    $$ = $2; }
3802             | DELIM line_item    { GEDCOM_MAKE_STRING(val2, $2);
3803                                    $$ = $2; }
3804             ;
3805
3806 mand_pointer : /* empty */ { gedcom_error(_("Missing pointer")); YYERROR; }
3807              | DELIM POINTER { gedcom_debug_print("==Ptr: %s==", $2);
3808                                $$ = $2; }
3809              ;
3810
3811 mand_line_item : /* empty */
3812                  { if (compat_mode(C_NO_REQUIRED_VALUES)) {
3813                      gedcom_debug_print("==Val: ==");
3814                      $$ = VALUE_IF_MISSING;
3815                    }
3816                    else {
3817                      gedcom_error(_("Missing value")); YYERROR;
3818                    }
3819                  }
3820                | DELIM line_item { gedcom_debug_print("==Val: %s==", $2);
3821                                    $$ = $2; }
3822                ;
3823
3824 opt_line_item : /* empty */     { $$ = NULL; }
3825               | DELIM line_item { gedcom_debug_print("==Val: %s==", $2);
3826                                   $$ = $2; }
3827               ;
3828
3829 line_item   : anychar  { size_t i;
3830                          reset_buffer(&line_item_buffer); 
3831                          /* The following also takes care of '@@' */
3832                          if (!strncmp($1, "@@", 3))
3833                            SAFE_BUF_ADDCHAR(&line_item_buffer, '@')
3834                          else
3835                            for (i=0; i < strlen($1); i++)
3836                              SAFE_BUF_ADDCHAR(&line_item_buffer, $1[i])
3837                          $$ = get_buf_string(&line_item_buffer);
3838                        }
3839             | ESCAPE   { size_t i;
3840                          reset_buffer(&line_item_buffer); 
3841                          for (i=0; i < strlen($1); i++)
3842                            SAFE_BUF_ADDCHAR(&line_item_buffer, $1[i])
3843                          $$ = get_buf_string(&line_item_buffer);
3844                        }
3845             | line_item anychar
3846                   { size_t i;
3847                     /* The following also takes care of '@@' */
3848                     if (!strncmp($2, "@@", 3))
3849                       SAFE_BUF_ADDCHAR(&line_item_buffer, '@')
3850                     else
3851                       for (i=0; i < strlen($2); i++)
3852                         SAFE_BUF_ADDCHAR(&line_item_buffer, $2[i])
3853                     $$ = get_buf_string(&line_item_buffer);
3854                   }
3855             | line_item ESCAPE
3856                   { size_t i;
3857                     for (i=0; i < strlen($2); i++)
3858                       SAFE_BUF_ADDCHAR(&line_item_buffer, $2[i])
3859                     $$ = get_buf_string(&line_item_buffer);
3860                   }
3861             | line_item error anychar { HANDLE_ERROR; }
3862             | line_item error ESCAPE  { HANDLE_ERROR; }
3863             ;
3864
3865 anychar     : ANYCHAR        { }
3866             | DELIM        { }
3867             ;
3868
3869 error_subs  : /* empty */
3870             | error_subs error_sect
3871             ;
3872
3873 error_sect  : OPEN DELIM opt_xref anytag opt_value error_subs CLOSE { }
3874             ;
3875
3876 gen_sect    : OPEN DELIM opt_xref anystdtag
3877               { if (compat_mode(C_SUBM_COMM)
3878                     && compat_check_subm_comm_cont($4.string)) {
3879                   /* Will pass here */
3880                 }
3881                 else {
3882                   INVALID_TAG($4.string);
3883                 }
3884               }
3885               opt_value
3886               { if (compat_mode(C_SUBM_COMM)) {
3887                   $<ctxt>$ = compat_subm_comm_cont_start(PARENT, $6);
3888                 }
3889               }
3890               opt_sects CLOSE
3891               { if (compat_mode(C_SUBM_COMM))
3892                   compat_subm_comm_cont_end(PARENT, $<ctxt>7);
3893               }
3894             ;
3895
3896 gen_rec : gen_rec_top
3897         | gen_rec_norm
3898         ;
3899
3900 gen_rec_norm : OPEN DELIM opt_xref anystdtag
3901                { INVALID_TOP_TAG($4.string) }
3902                opt_value opt_sects CLOSE
3903                { }
3904              ;
3905
3906 gen_rec_top : OPEN DELIM anytoptag
3907               { gedcom_error(_("Missing cross-reference")); YYERROR; }
3908               opt_value opt_sects CLOSE
3909                 { }
3910             ;
3911
3912 opt_sects   : /* empty */     { }
3913             | opt_sects gen_sect { }
3914             ;
3915
3916 anytag      : USERTAG { }
3917             | anystdtag { }
3918             ;
3919
3920 anytoptag   : TAG_FAM
3921             | TAG_INDI
3922             | TAG_OBJE
3923             | TAG_NOTE
3924             | TAG_REPO
3925             | TAG_SOUR
3926             | TAG_SUBN
3927             | TAG_SUBM
3928             ;
3929
3930 anystdtag   : TAG_ABBR
3931             | TAG_ADDR
3932             | TAG_ADR1
3933             | TAG_ADR2   { }
3934             | TAG_ADOP   { }
3935             | TAG_AFN   { }
3936             | TAG_AGE   { }
3937             | TAG_AGNC   { }
3938             | TAG_ALIA   { }
3939             | TAG_ANCE   { }
3940             | TAG_ANCI   { }
3941             | TAG_ANUL   { }
3942             | TAG_ASSO   { }
3943             | TAG_AUTH   { }
3944             | TAG_BAPL   { }
3945             | TAG_BAPM   { }
3946             | TAG_BARM   { }
3947             | TAG_BASM   { }
3948             | TAG_BIRT   { }
3949             | TAG_BLES   { }
3950             | TAG_BLOB   { }
3951             | TAG_BURI   { }
3952             | TAG_CALN   { }
3953             | TAG_CAST   { }
3954             | TAG_CAUS   { }
3955             | TAG_CENS   { }
3956             | TAG_CHAN   { }
3957             | TAG_CHAR   { }
3958             | TAG_CHIL   { }
3959             | TAG_CHR   { }
3960             | TAG_CHRA   { }
3961             | TAG_CITY   { }
3962             | TAG_CONC   { }
3963             | TAG_CONF   { }
3964             | TAG_CONL   { }
3965             | TAG_CONT   { }
3966             | TAG_COPR   { }
3967             | TAG_CORP   { }
3968             | TAG_CREM   { }
3969             | TAG_CTRY   { }
3970             | TAG_DATA   { }
3971             | TAG_DATE   { }
3972             | TAG_DEAT   { }
3973             | TAG_DESC   { }
3974             | TAG_DESI   { }
3975             | TAG_DEST   { }
3976             | TAG_DIV   { }
3977             | TAG_DIVF   { }
3978             | TAG_DSCR   { }
3979             | TAG_EDUC   { }
3980             | TAG_EMIG   { }
3981             | TAG_ENDL   { }
3982             | TAG_ENGA   { }
3983             | TAG_EVEN   { }
3984             | TAG_FAM    { }
3985             | TAG_FAMC   { }
3986             | TAG_FAMS   { }
3987             | TAG_FCOM   { }
3988             | TAG_FILE   { }
3989             | TAG_FORM   { }
3990             | TAG_GEDC   { }
3991             | TAG_GIVN   { }
3992             | TAG_GRAD   { }
3993             | TAG_HEAD   { }
3994             | TAG_HUSB   { }
3995             | TAG_IDNO   { }
3996             | TAG_IMMI   { }
3997             | TAG_INDI   { }
3998             | TAG_LANG   { }
3999             | TAG_LEGA   { }
4000             | TAG_MARB   { }
4001             | TAG_MARC   { }
4002             | TAG_MARL   { }
4003             | TAG_MARR   { }
4004             | TAG_MARS   { }
4005             | TAG_MEDI   { }
4006             | TAG_NAME   { }
4007             | TAG_NATI   { }
4008             | TAG_NCHI   { }
4009             | TAG_NICK   { }
4010             | TAG_NMR   { }
4011             | TAG_NOTE   { }
4012             | TAG_NPFX   { }
4013             | TAG_NSFX   { }
4014             | TAG_OBJE   { }
4015             | TAG_OCCU   { }
4016             | TAG_ORDI   { }
4017             | TAG_ORDN   { }
4018             | TAG_PAGE   { }
4019             | TAG_PEDI   { }
4020             | TAG_PHON   { }
4021             | TAG_PLAC   { }
4022             | TAG_POST   { }
4023             | TAG_PROB   { }
4024             | TAG_PROP   { }
4025             | TAG_PUBL   { }
4026             | TAG_QUAY   { }
4027             | TAG_REFN   { }
4028             | TAG_RELA   { }
4029             | TAG_RELI   { }
4030             | TAG_REPO   { }
4031             | TAG_RESI   { }
4032             | TAG_RESN   { }
4033             | TAG_RETI   { }
4034             | TAG_RFN   { }
4035             | TAG_RIN   { }
4036             | TAG_ROLE   { }
4037             | TAG_SEX   { }
4038             | TAG_SLGC   { }
4039             | TAG_SLGS   { }
4040             | TAG_SOUR   { }
4041             | TAG_SPFX   { }
4042             | TAG_SSN   { }
4043             | TAG_STAE   { }
4044             | TAG_STAT   { }
4045             | TAG_SUBM   { }
4046             | TAG_SUBN   { }
4047             | TAG_SURN   { }
4048             | TAG_TEMP   { }
4049             | TAG_TEXT   { }
4050             | TAG_TIME   { }
4051             | TAG_TITL   { }
4052             | TAG_TRLR   { }
4053             | TAG_TYPE   { }
4054             | TAG_VERS   { }
4055             | TAG_WIFE   { }
4056             | TAG_WILL   { }
4057             ;
4058
4059 %%
4060
4061 /* Functions that handle the counting of subtags */
4062
4063 int* count_arrays[MAXGEDCLEVEL+1];
4064 char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLEN+1];
4065 Gedcom_ctxt ctxt_stack[MAXGEDCLEVEL+1];
4066
4067 void push_countarray(int level)
4068 {
4069   int *count = NULL;
4070   gedcom_debug_print("Push Count level: %d, level: %d", count_level, level);
4071   if (count_level != level + 1) {
4072     gedcom_error(_("Internal error: count level mismatch"));
4073     exit(1);
4074   }
4075   if (count_level > MAXGEDCLEVEL) {
4076     gedcom_error(_("Internal error: count array overflow"));
4077     exit(1);
4078   }
4079   else {
4080     gedcom_debug_print("calloc countarray %d", count_level);
4081     count = (int *)calloc(YYNTOKENS, sizeof(int));
4082     if (count == NULL) {
4083       gedcom_error(_("Internal error: count array calloc error"));
4084       exit(1);
4085     }
4086     else {
4087       count_arrays[count_level] = count;
4088     }
4089   }
4090 }
4091
4092 void set_parenttag(const char* tag)
4093 {
4094   strncpy(tag_stack[count_level+1], tag, MAXSTDTAGLEN+1);
4095 }
4096
4097 void set_parentctxt(Gedcom_ctxt ctxt)
4098 {
4099   ctxt_stack[count_level+1] = ctxt;
4100 }
4101
4102 char* get_parenttag(int offset)
4103 {
4104   return tag_stack[count_level - offset];
4105 }
4106
4107 Gedcom_ctxt get_parentctxt(int offset)
4108 {
4109   return ctxt_stack[count_level - offset];
4110 }
4111
4112 int count_tag(int tag)
4113 {
4114   int *count = count_arrays[count_level];
4115   return ++count[tag - GEDCOMTAGOFFSET];
4116 }
4117
4118 int check_occurrence(int tag)
4119 {
4120   int *count = count_arrays[count_level];
4121   return (count[tag - GEDCOMTAGOFFSET] > 0);
4122 }
4123
4124 void pop_countarray()
4125 {
4126   int *count;
4127   gedcom_debug_print("Pop Count level: %d", count_level);
4128   if (count_level < 0) {
4129     gedcom_error(_("Internal error: count array underflow"));
4130     exit(1);
4131   }
4132   else {
4133     count = count_arrays[count_level];
4134     gedcom_debug_print("free countarray %d", count_level);
4135     free(count);
4136     count_arrays[count_level] = NULL;
4137   }
4138 }
4139
4140 void clean_up()
4141 {
4142   gedcom_debug_print("Cleanup countarrays");
4143   while (count_level > 0) {
4144     pop_countarray();
4145     --count_level;
4146   }
4147 }
4148
4149 void cleanup_concat_buffer()
4150 {
4151   cleanup_buffer(&concat_buffer);
4152 }
4153
4154 void cleanup_line_item_buffer()
4155 {
4156   cleanup_buffer(&line_item_buffer);
4157 }
4158
4159 void cleanup_usertag_buffer()
4160 {
4161   cleanup_buffer(&usertag_buffer);
4162 }
4163
4164 /* Enabling debug mode */
4165 /* level 0: no debugging */
4166 /* level 1: only internal */
4167 /* level 2: also bison */
4168 FILE* trace_output;
4169
4170 void gedcom_set_debug_level(int level, FILE* f)
4171 {
4172   if (f != NULL)
4173     trace_output = f;
4174   else
4175     trace_output = stderr;
4176   if (level > 0) {
4177     gedcom_high_level_debug = 1;
4178   }
4179   if (level > 1) {
4180 #if YYDEBUG != 0
4181     gedcom_debug = 1;
4182 #endif
4183   }
4184 }
4185
4186 int gedcom_debug_print(const char* s, ...)
4187 {
4188   int res = 0;
4189   if (gedcom_high_level_debug) {
4190     va_list ap;
4191     va_start(ap, s);
4192     res = vfprintf(trace_output, s, ap);
4193     va_end(ap);
4194     fprintf(trace_output, "\n");
4195   }
4196   return(res);
4197 }
4198
4199 /* Setting the error mechanism */
4200 void gedcom_set_error_handling(Gedcom_err_mech mechanism)
4201 {
4202   error_mechanism = mechanism;
4203 }