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