c8aaed00805bbf9f994914e8ae417f0da9da2ee3
[gedcom-parse.git] / gedcom / gedcom.y
1 /* Parser for Gedcom.
2    Copyright (C) 2001 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
149 int  count_level    = 0;
150 int  fail           = 0;
151 int  compat_enabled = 1;
152 int  gedcom_high_level_debug = 0; 
153 int  compatibility  = 0; 
154 Gedcom_err_mech error_mechanism = IMMED_FAIL;
155  
156 char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
157 char *line_item_buf_ptr;
158
159 enum _COMPAT {
160   C_FTREE = 0x01
161 };
162
163 /* These are defined at the bottom of the file */ 
164 void push_countarray();
165 void set_parenttag(char* tag);
166 char* get_parenttag(); 
167 void set_parentctxt(Gedcom_ctxt ctxt);
168 Gedcom_ctxt get_parentctxt();
169 void pop_countarray();
170 int  count_tag(int tag);
171 int  check_occurrence(int tag);
172 void set_compatibility(char* program);
173 int  compat_mode(int flags); 
174
175 #define CLEAR_BUFFER(BUF)                                                     \
176      memset(BUF, 0, sizeof(BUF));
177  
178 #define HANDLE_ERROR                                                          \
179      { if (error_mechanism == IMMED_FAIL) {                                   \
180          YYABORT;                                                             \
181        }                                                                      \
182        else if (error_mechanism == DEFER_FAIL) {                              \
183          yyerrok; fail = 1;                                                   \
184        }                                                                      \
185        else if (error_mechanism == IGNORE_ERRORS) {                           \
186          yyerrok;                                                             \
187        }                                                                      \
188      }
189 #define START(PARENTTAG,PARENTCTXT)                                           \
190      { ++count_level;                                                         \
191        set_parenttag(#PARENTTAG);                                             \
192        set_parentctxt(PARENTCTXT);                                            \
193        push_countarray();                                                     \
194      }
195 #define PARENT                                                              \
196      get_parentctxt()
197 #define CHK(TAG)                                                              \
198      { if (!check_occurrence(TAG_##TAG)) {                                    \
199          char* parenttag = get_parenttag();                                   \
200          gedcom_error(_("The tag '%s' is mandatory within '%s', but missing"),\
201                       #TAG, parenttag);                                       \
202          HANDLE_ERROR;                                                        \
203        }                                                                      \
204      }
205 #define POP                                                                   \
206      { pop_countarray();                                                      \
207        --count_level;                                                         \
208      }
209 #define CHECK0 POP; 
210 #define CHECK1(TAG1) { CHK(TAG1); POP; }
211 #define CHECK2(TAG1,TAG2)                                                     \
212      { CHK(TAG1); CHK(TAG2); POP; }
213 #define CHECK3(TAG1,TAG2,TAG3)                                                \
214      { CHK(TAG1); CHK(TAG2); CHK(TAG3); POP; }
215 #define CHECK4(TAG1,TAG2,TAG3,TAG4)                                           \
216      { CHK(TAG1); CHK(TAG2); CHK(TAG3); CHK(TAG4); POP; } 
217 #define OCCUR1(CHILDTAG, MIN) { count_tag(TAG_##CHILDTAG); } 
218 #define OCCUR2(CHILDTAG, MIN, MAX)                                            \
219      { int num = count_tag(TAG_##CHILDTAG);                                   \
220        if (num > MAX) {                                                       \
221          char* parenttag = get_parenttag();                                   \
222          gedcom_error(_("The tag '%s' can maximally occur %d time(s) within '%s'"),                                                                          \
223                       #CHILDTAG, MAX, parenttag);                             \
224          HANDLE_ERROR;                                                        \
225        }                                                                      \
226      }
227 #define INVALID_TAG(CHILDTAG)                                                 \
228      { char* parenttag = get_parenttag();                                     \
229        gedcom_error(_("The tag '%s' is not a valid tag within '%s'"),         \
230                     CHILDTAG, parenttag);                                     \
231        HANDLE_ERROR;                                                          \
232      }
233 #define INVALID_TOP_TAG(CHILDTAG)                                             \
234      { gedcom_error(_("The tag '%s' is not a valid top-level tag"),           \
235                     CHILDTAG); \
236        HANDLE_ERROR; \
237      }
238
239 %}
240
241 %union {
242   int  number;
243   char *string;
244   Gedcom_ctxt ctxt;
245 }
246
247 %token_table
248 %expect 300
249
250 %token <string> BADTOKEN
251 %token <number> OPEN
252 %token <string> CLOSE
253 %token <string> ESCAPE
254 %token <string> DELIM
255 %token <string> ANYCHAR
256 %token <string> POINTER
257 %token <string> USERTAG
258 %token <string> TAG_ABBR
259 %token <string> TAG_ADDR
260 %token <string> TAG_ADR1
261 %token <string> TAG_ADR2
262 %token <string> TAG_ADOP
263 %token <string> TAG_AFN
264 %token <string> TAG_AGE
265 %token <string> TAG_AGNC
266 %token <string> TAG_ALIA
267 %token <string> TAG_ANCE
268 %token <string> TAG_ANCI
269 %token <string> TAG_ANUL
270 %token <string> TAG_ASSO
271 %token <string> TAG_AUTH
272 %token <string> TAG_BAPL
273 %token <string> TAG_BAPM
274 %token <string> TAG_BARM
275 %token <string> TAG_BASM
276 %token <string> TAG_BIRT
277 %token <string> TAG_BLES
278 %token <string> TAG_BLOB
279 %token <string> TAG_BURI
280 %token <string> TAG_CALN
281 %token <string> TAG_CAST
282 %token <string> TAG_CAUS
283 %token <string> TAG_CENS
284 %token <string> TAG_CHAN
285 %token <string> TAG_CHAR
286 %token <string> TAG_CHIL
287 %token <string> TAG_CHR
288 %token <string> TAG_CHRA
289 %token <string> TAG_CITY
290 %token <string> TAG_CONC
291 %token <string> TAG_CONF
292 %token <string> TAG_CONL
293 %token <string> TAG_CONT
294 %token <string> TAG_COPR
295 %token <string> TAG_CORP
296 %token <string> TAG_CREM
297 %token <string> TAG_CTRY
298 %token <string> TAG_DATA
299 %token <string> TAG_DATE
300 %token <string> TAG_DEAT
301 %token <string> TAG_DESC
302 %token <string> TAG_DESI
303 %token <string> TAG_DEST
304 %token <string> TAG_DIV
305 %token <string> TAG_DIVF
306 %token <string> TAG_DSCR
307 %token <string> TAG_EDUC
308 %token <string> TAG_EMIG
309 %token <string> TAG_ENDL
310 %token <string> TAG_ENGA
311 %token <string> TAG_EVEN
312 %token <string> TAG_FAM
313 %token <string> TAG_FAMC
314 %token <string> TAG_FAMF
315 %token <string> TAG_FAMS
316 %token <string> TAG_FCOM
317 %token <string> TAG_FILE
318 %token <string> TAG_FORM
319 %token <string> TAG_GEDC
320 %token <string> TAG_GIVN
321 %token <string> TAG_GRAD
322 %token <string> TAG_HEAD
323 %token <string> TAG_HUSB
324 %token <string> TAG_IDNO
325 %token <string> TAG_IMMI
326 %token <string> TAG_INDI
327 %token <string> TAG_LANG
328 %token <string> TAG_LEGA
329 %token <string> TAG_MARB
330 %token <string> TAG_MARC
331 %token <string> TAG_MARL
332 %token <string> TAG_MARR
333 %token <string> TAG_MARS
334 %token <string> TAG_MEDI
335 %token <string> TAG_NAME
336 %token <string> TAG_NATI
337 %token <string> TAG_NATU
338 %token <string> TAG_NCHI
339 %token <string> TAG_NICK
340 %token <string> TAG_NMR
341 %token <string> TAG_NOTE
342 %token <string> TAG_NPFX
343 %token <string> TAG_NSFX
344 %token <string> TAG_OBJE
345 %token <string> TAG_OCCU
346 %token <string> TAG_ORDI
347 %token <string> TAG_ORDN
348 %token <string> TAG_PAGE
349 %token <string> TAG_PEDI
350 %token <string> TAG_PHON
351 %token <string> TAG_PLAC
352 %token <string> TAG_POST
353 %token <string> TAG_PROB
354 %token <string> TAG_PROP
355 %token <string> TAG_PUBL
356 %token <string> TAG_QUAY
357 %token <string> TAG_REFN
358 %token <string> TAG_RELA
359 %token <string> TAG_RELI
360 %token <string> TAG_REPO
361 %token <string> TAG_RESI
362 %token <string> TAG_RESN
363 %token <string> TAG_RETI
364 %token <string> TAG_RFN
365 %token <string> TAG_RIN
366 %token <string> TAG_ROLE
367 %token <string> TAG_SEX
368 %token <string> TAG_SLGC
369 %token <string> TAG_SLGS
370 %token <string> TAG_SOUR
371 %token <string> TAG_SPFX
372 %token <string> TAG_SSN
373 %token <string> TAG_STAE
374 %token <string> TAG_STAT
375 %token <string> TAG_SUBM
376 %token <string> TAG_SUBN
377 %token <string> TAG_SURN
378 %token <string> TAG_TEMP
379 %token <string> TAG_TEXT
380 %token <string> TAG_TIME
381 %token <string> TAG_TITL
382 %token <string> TAG_TRLR
383 %token <string> TAG_TYPE
384 %token <string> TAG_VERS
385 %token <string> TAG_WIFE
386 %token <string> TAG_WILL
387
388 %type <string> anystdtag
389 %type <string> anytoptag
390 %type <string> line_item
391 %type <string> line_value
392 %type <string> mand_line_item
393 %type <string> mand_pointer
394 %type <string> note_line_item
395 %type <string> anychar
396 %type <string> opt_xref
397 %type <string> opt_value
398 %type <ctxt> head_sect
399
400 %%
401
402 file        : head_sect records trlr_sect
403                { if (fail == 1) YYABORT; }
404             ;
405
406 records     : /* empty */
407             | records record
408             ;
409
410 record      : fam_rec
411             | indiv_rec
412             | multim_rec
413             | note_rec
414             | repos_rec
415             | source_rec
416             | submis_rec
417             | submit_rec
418             | no_std_rec
419             ;
420
421 /*********************************************************************/
422 /**** Header                                                      ****/
423 /*********************************************************************/
424 head_sect    : OPEN DELIM TAG_HEAD
425                { $<ctxt>$ = start_record(REC_HEAD, $1, NULL, $3);
426                  START(HEAD, $<ctxt>$) }
427                head_subs
428                { if (compat_mode(C_FTREE))
429                    CHECK3(SOUR, GEDC, CHAR)
430                  else
431                    CHECK4(SOUR, SUBM, GEDC, CHAR)
432                }
433                CLOSE
434                { end_record(REC_HEAD, $<ctxt>4); }
435              ;
436
437 head_subs    : /* empty */
438              | head_subs head_sub
439              ;
440
441 head_sub     : head_sour_sect  { OCCUR2(SOUR, 1, 1) }
442              | head_dest_sect  { OCCUR2(DEST, 0, 1) }
443              | head_date_sect  { OCCUR2(DATE, 0, 1) }
444              | head_subm_sect  { OCCUR2(SUBM, 1, 1) }
445              | head_subn_sect  { OCCUR2(SUBN, 0, 1) }
446              | head_file_sect  { OCCUR2(FILE, 0, 1) }
447              | head_copr_sect  { OCCUR2(COPR, 0, 1) }
448              | head_gedc_sect  { OCCUR2(GEDC, 1, 1) }
449              | head_char_sect  { OCCUR2(CHAR, 1, 1) }
450              | head_lang_sect  { OCCUR2(LANG, 0, 1) }
451              | head_plac_sect  { OCCUR2(PLAC, 0, 1) }
452              | head_note_sect  { OCCUR2(NOTE, 0, 1) }
453              | no_std_sub
454              ;
455
456 /* HEAD.SOUR */
457 head_sour_sect : OPEN DELIM TAG_SOUR mand_line_item 
458                  { set_compatibility($4);
459                    $<ctxt>$ = start_element(ELT_HEAD_SOUR, PARENT,
460                                             $1, $3, $4, $4);
461                    START(SOUR, $<ctxt>$)
462                  }
463                  head_sour_subs
464                  { CHECK0 }
465                  CLOSE
466                  { end_element(ELT_HEAD_SOUR, PARENT, $<ctxt>5, NULL); }
467                ;
468
469 head_sour_subs : /* empty */
470                | head_sour_subs head_sour_sub
471                ;
472
473 head_sour_sub : head_sour_vers_sect  { OCCUR2(VERS, 0, 1) }
474               | head_sour_name_sect  { OCCUR2(NAME, 0, 1) }
475               | head_sour_corp_sect  { OCCUR2(CORP, 0, 1) } 
476               | head_sour_data_sect  { OCCUR2(DATA, 0, 1) }
477               | no_std_sub
478               ;
479
480 head_sour_vers_sect : OPEN DELIM TAG_VERS mand_line_item
481                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_VERS, PARENT,
482                                                  $1, $3, $4, $4);
483                         START(VERS, $<ctxt>$)
484                       }
485                       no_std_subs
486                       { CHECK0 }
487                       CLOSE
488                       { end_element(ELT_HEAD_SOUR_VERS,
489                                     PARENT, $<ctxt>5, NULL);
490                       }
491                     ;
492 head_sour_name_sect : OPEN DELIM TAG_NAME mand_line_item
493                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_NAME, PARENT,
494                                                  $1, $3, $4, $4);
495                         START(NAME, $<ctxt>$)
496                       }
497                       no_std_subs
498                       { CHECK0 }
499                       CLOSE
500                       { end_element(ELT_HEAD_SOUR_NAME,
501                                     PARENT, $<ctxt>5, NULL);
502                       }
503                     ;
504 head_sour_corp_sect : OPEN DELIM TAG_CORP mand_line_item 
505                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_CORP, PARENT,
506                                                  $1, $3, $4, $4);
507                         START(CORP, $<ctxt>$)
508                       }
509                       head_sour_corp_subs
510                       { CHECK0 }
511                       CLOSE
512                       { end_element(ELT_HEAD_SOUR_CORP,
513                                     PARENT, $<ctxt>5, NULL);
514                       }
515                     ;
516
517 head_sour_corp_subs : /* empty */
518                     | head_sour_corp_subs head_sour_corp_sub
519                     ;
520
521 head_sour_corp_sub : addr_struc_sub  /* 0:1 */
522                    | no_std_sub
523                    ;
524
525 head_sour_data_sect : OPEN DELIM TAG_DATA mand_line_item 
526                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA, PARENT,
527                                                  $1, $3, $4, $4);
528                         START(DATA, $<ctxt>$)
529                       }
530                       head_sour_data_subs
531                       { CHECK0 }
532                       CLOSE
533                       { end_element(ELT_HEAD_SOUR_DATA,
534                                     PARENT, $<ctxt>5, NULL);
535                       }
536                     ;
537
538 head_sour_data_subs : /* empty */
539                     | head_sour_data_subs head_sour_data_sub
540                     ;
541
542 head_sour_data_sub : head_sour_data_date_sect  { OCCUR2(DATE, 0, 1) }
543                    | head_sour_data_copr_sect  { OCCUR2(COPR, 0, 1) }
544                    | no_std_sub
545                    ;
546
547 head_sour_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
548                            { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_DATE,
549                                                       PARENT, $1, $3, $4, $4);
550                              START(DATE, $<ctxt>$)
551                            }
552                            no_std_subs
553                            { CHECK0 }
554                            CLOSE
555                            { end_element(ELT_HEAD_SOUR_DATA_DATE,
556                                          PARENT, $<ctxt>5, NULL);
557                            }
558                          ;
559 head_sour_data_copr_sect : OPEN DELIM TAG_COPR mand_line_item
560                            { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_COPR,
561                                                       PARENT, $1, $3, $4, $4);
562                              START(COPR, $<ctxt>$)
563                            }
564                            no_std_subs
565                            { CHECK0 }
566                            CLOSE
567                            { end_element(ELT_HEAD_SOUR_DATA_COPR,
568                                          PARENT, $<ctxt>5, NULL);
569                            }
570                          ;
571
572 /* HEAD.DEST */
573 head_dest_sect : OPEN DELIM TAG_DEST mand_line_item
574                  { $<ctxt>$ = start_element(ELT_HEAD_DEST,
575                                             PARENT, $1, $3, $4, $4);
576                    START(DEST, $<ctxt>$)
577                  }
578                  no_std_subs
579                  { CHECK0 }
580                  CLOSE
581                  { end_element(ELT_HEAD_DEST,
582                                PARENT, $<ctxt>5, NULL);
583                  }
584                ;
585
586 /* HEAD.DATE */
587 head_date_sect : OPEN DELIM TAG_DATE mand_line_item 
588                  { $<ctxt>$ = start_element(ELT_HEAD_DATE,
589                                             PARENT, $1, $3, $4, $4);
590                    START(DATE, $<ctxt>$)
591                  }
592                  head_date_subs
593                  { CHECK0 }
594                  CLOSE
595                  { end_element(ELT_HEAD_DATE,
596                                PARENT, $<ctxt>5, NULL);
597                  }
598                ;
599
600 head_date_subs : /* empty */
601                | head_date_subs head_date_sub
602                ;
603
604 head_date_sub  : head_date_time_sect  { OCCUR2(TIME, 0, 1) }
605                | no_std_sub
606                ;
607
608 head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
609                       { $<ctxt>$ = start_element(ELT_HEAD_DATE_TIME,
610                                                  PARENT, $1, $3, $4, $4);
611                         START(TIME, $<ctxt>$)
612                       }
613                       no_std_subs
614                       { CHECK0 }
615                       CLOSE
616                       { end_element(ELT_HEAD_DATE_TIME,
617                                     PARENT, $<ctxt>5, NULL);
618                       }
619                     ;
620
621 /* HEAD.SUBM */
622 head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
623                  { $<ctxt>$ = start_element(ELT_HEAD_SUBM,
624                                             PARENT, $1, $3, $4, $4);
625                    START(SUBM, $<ctxt>$)
626                  }
627                  no_std_subs
628                  { CHECK0 }
629                  CLOSE
630                  { end_element(ELT_HEAD_SUBM,
631                                PARENT, $<ctxt>5, NULL);
632                  }
633                ;
634 /* HEAD.SUBN */
635 head_subn_sect : OPEN DELIM TAG_SUBN mand_pointer 
636                  { $<ctxt>$ = start_element(ELT_HEAD_SUBN,
637                                             PARENT, $1, $3, $4, $4);
638                    START(SUBN, $<ctxt>$)
639                  }
640                  no_std_subs
641                  { CHECK0 }
642                  CLOSE
643                  { end_element(ELT_HEAD_SUBN,
644                                PARENT, $<ctxt>5, NULL);
645                  }
646                ;
647 /* HEAD.FILE */
648 head_file_sect : OPEN DELIM TAG_FILE mand_line_item 
649                  { $<ctxt>$ = start_element(ELT_HEAD_FILE,
650                                             PARENT, $1, $3, $4, $4);
651                    START(FILE, $<ctxt>$)
652                  }
653                  no_std_subs
654                  { CHECK0 }
655                  CLOSE
656                  { end_element(ELT_HEAD_FILE, PARENT, $<ctxt>5, NULL);
657                  }
658                ;
659 /* HEAD.COPR */
660 head_copr_sect : OPEN DELIM TAG_COPR mand_line_item 
661                  { $<ctxt>$ = start_element(ELT_HEAD_COPR,
662                                             PARENT, $1, $3, $4, $4);
663                    START(COPR, $<ctxt>$)
664                  }
665                  no_std_subs
666                  { CHECK0 }
667                  CLOSE
668                  { end_element(ELT_HEAD_COPR, PARENT, $<ctxt>5, NULL);
669                  }
670                ;
671 /* HEAD.GEDC */
672 head_gedc_sect : OPEN DELIM TAG_GEDC
673                  { $<ctxt>$ = start_element(ELT_HEAD_GEDC,
674                                             PARENT, $1, $3, NULL, NULL);
675                    START(GEDC, $<ctxt>$)
676                  }
677                  head_gedc_subs
678                  { CHECK2(VERS, FORM) }
679                  CLOSE
680                  { end_element(ELT_HEAD_GEDC, PARENT, $<ctxt>4, NULL);
681                  }
682                ;
683
684 head_gedc_subs : /* empty */
685                | head_gedc_subs head_gedc_sub
686                ;
687
688 head_gedc_sub  : head_gedc_vers_sect  { OCCUR2(VERS, 1, 1) }
689                | head_gedc_form_sect  { OCCUR2(FORM, 1, 1) }
690                | no_std_sub
691                ;
692 head_gedc_vers_sect : OPEN DELIM TAG_VERS mand_line_item  
693                       { $<ctxt>$ = start_element(ELT_HEAD_GEDC_VERS,
694                                                  PARENT, $1, $3, $4, $4);
695                         START(VERS, $<ctxt>$)
696                       }
697                       no_std_subs
698                       { CHECK0 }
699                       CLOSE
700                       { end_element(ELT_HEAD_GEDC_VERS,
701                                     PARENT, $<ctxt>5, NULL);
702                       }
703                     ;
704 head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item   
705                       { $<ctxt>$ = start_element(ELT_HEAD_GEDC_FORM,
706                                                  PARENT, $1, $3, $4, $4);
707                         START(FORM, $<ctxt>$)
708                       }
709                       no_std_subs
710                       { CHECK0 }
711                       CLOSE
712                       { end_element(ELT_HEAD_GEDC_FORM,
713                                     PARENT, $<ctxt>5, NULL);
714                       }
715                     ;
716
717 /* HEAD.CHAR */
718 head_char_sect : OPEN DELIM TAG_CHAR mand_line_item 
719                  { if (open_conv_to_internal($4) == 0) YYERROR;
720                    $<ctxt>$ = start_element(ELT_HEAD_CHAR,
721                                             PARENT, $1, $3, $4, $4);
722                    START(CHAR, $<ctxt>$)
723                  }
724                  head_char_subs
725                  { CHECK0 }
726                  CLOSE
727                  { end_element(ELT_HEAD_CHAR, PARENT, $<ctxt>5, NULL);
728                  }
729                ;
730
731 head_char_subs : /* empty */
732                | head_char_subs head_char_sub
733                ;
734
735 head_char_sub  : head_char_vers_sect  { OCCUR2(VERS, 0, 1) }
736                | no_std_sub
737                ;
738 head_char_vers_sect : OPEN DELIM TAG_VERS mand_line_item   
739                       { $<ctxt>$ = start_element(ELT_HEAD_CHAR_VERS,
740                                                  PARENT, $1, $3, $4, $4);
741                         START(VERS, $<ctxt>$)
742                       }
743                       no_std_subs
744                       { CHECK0 }
745                       CLOSE
746                       { end_element(ELT_HEAD_CHAR_VERS,
747                                     PARENT, $<ctxt>5, NULL);
748                       }
749                     ;
750
751 /* HEAD.LANG */
752 head_lang_sect : OPEN DELIM TAG_LANG mand_line_item   
753                  { $<ctxt>$ = start_element(ELT_HEAD_LANG,
754                                             PARENT, $1, $3, $4, $4);
755                    START(LANG, $<ctxt>$)
756                  }
757                  no_std_subs
758                  { CHECK0 }
759                  CLOSE
760                  { end_element(ELT_HEAD_LANG, PARENT, $<ctxt>5, NULL);
761                  }
762                ;
763 /* HEAD.PLAC */
764 head_plac_sect : OPEN DELIM TAG_PLAC
765                  { $<ctxt>$ = start_element(ELT_HEAD_PLAC,
766                                             PARENT, $1, $3, NULL, NULL);
767                    START(PLAC, $<ctxt>$)
768                  }
769                  head_plac_subs
770                  { CHECK1(FORM) }
771                  CLOSE
772                  { end_element(ELT_HEAD_PLAC, PARENT, $<ctxt>4, NULL);
773                  }
774                ;
775
776 head_plac_subs : /* empty */
777                | head_plac_subs head_plac_sub
778                ;
779
780 head_plac_sub  : head_plac_form_sect  { OCCUR2(FORM, 1, 1) }
781                | no_std_sub
782                ;
783 head_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item   
784                       { $<ctxt>$ = start_element(ELT_HEAD_PLAC_FORM,
785                                                  PARENT, $1, $3, $4, $4);
786                         START(FORM, $<ctxt>$)
787                       }
788                       no_std_subs
789                       { CHECK0 }
790                       CLOSE
791                       { end_element(ELT_HEAD_PLAC_FORM,
792                                     PARENT, $<ctxt>5, NULL);
793                       }
794                     ;
795
796 /* HEAD.NOTE */
797 head_note_sect : OPEN DELIM TAG_NOTE mand_line_item 
798                  { $<ctxt>$ = start_element(ELT_HEAD_NOTE,
799                                             PARENT, $1, $3, $4, $4);
800                    START(NOTE, $<ctxt>$)
801                  }
802                  head_note_subs
803                  { CHECK0 }
804                  CLOSE
805                  { end_element(ELT_HEAD_NOTE, PARENT, $<ctxt>5, NULL);
806                  }
807                ;
808
809 head_note_subs : /* empty */
810                | head_note_subs head_note_sub
811                ;
812
813 head_note_sub  : continuation_sub  /* 0:M */
814                | no_std_sub
815                ;
816
817 /*********************************************************************/
818 /**** Trailer                                                     ****/
819 /*********************************************************************/
820 /* Don't need callbacks here, there is no information... */
821 trlr_sect   : OPEN DELIM TAG_TRLR CLOSE { }
822             ;
823
824 /*********************************************************************/
825 /**** Family record                                               ****/
826 /*********************************************************************/
827 fam_rec      : OPEN DELIM POINTER DELIM TAG_FAM
828                { $<ctxt>$ = start_record(REC_FAM, $1, $3, $5);
829                  START(FAM, $<ctxt>$) }
830                fam_subs
831                { CHECK0 }
832                CLOSE
833                { end_record(REC_FAM, $<ctxt>6); }
834              ;
835
836 fam_subs     : /* empty */
837              | fam_subs fam_sub
838              ;
839
840 fam_sub      : fam_event_struc_sub  /* 0:M */
841              | fam_husb_sect  { OCCUR2(HUSB, 0, 1) }
842              | fam_wife_sect  { OCCUR2(WIFE, 0, 1) }
843              | fam_chil_sect  /* 0:M */
844              | fam_nchi_sect  { OCCUR2(NCHI, 0, 1) }
845              | fam_subm_sect  /* 0:M */
846              | lds_spouse_seal_sub  /* 0:M */
847              | source_cit_sub  /* 0:M */
848              | multim_link_sub  /* 0:M */
849              | note_struc_sub  /* 0:M */
850              | ident_struc_sub  /* 0:1 */
851              | change_date_sub  /* 0:1 */
852              | no_std_sub
853              ;
854
855 /* FAM.HUSB */
856 fam_husb_sect : OPEN DELIM TAG_HUSB mand_pointer    
857                 { $<ctxt>$ = start_element(ELT_FAM_HUSB,
858                                            PARENT, $1, $3, $4, $4);
859                   START(HUSB, $<ctxt>$)
860                 }
861                 no_std_subs
862                 { CHECK0 }
863                 CLOSE
864                 { end_element(ELT_FAM_HUSB, PARENT, $<ctxt>5, NULL);
865                 }
866               ;
867
868 /* FAM.WIFE */
869 fam_wife_sect : OPEN DELIM TAG_WIFE mand_pointer 
870                 { $<ctxt>$ = start_element(ELT_FAM_WIFE,
871                                            PARENT, $1, $3, $4, $4);
872                   START(WIFE, $<ctxt>$)
873                 }
874                 no_std_subs
875                 { CHECK0 }
876                 CLOSE
877                 { end_element(ELT_FAM_WIFE, PARENT, $<ctxt>5, NULL);
878                 }
879               ;
880
881 /* FAM.CHIL */
882 fam_chil_sect : OPEN DELIM TAG_CHIL mand_pointer
883                 { $<ctxt>$ = start_element(ELT_FAM_CHIL,
884                                            PARENT, $1, $3, $4, $4);
885                   START(CHIL, $<ctxt>$) 
886                 } 
887                 no_std_subs 
888                 { CHECK0 } 
889                 CLOSE
890                 { end_element(ELT_FAM_CHIL, PARENT, $<ctxt>5, NULL);
891                 }
892               ;
893
894 /* FAM.NCHI */
895 fam_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item    
896                 { $<ctxt>$ = start_element(ELT_FAM_NCHI,
897                                            PARENT, $1, $3, $4, $4);
898                   START(NCHI, $<ctxt>$)  
899                 }  
900                 no_std_subs  
901                 { CHECK0 }  
902                 CLOSE
903                 { end_element(ELT_FAM_NCHI, PARENT, $<ctxt>5, NULL);
904                 }
905               ;
906
907 /* FAM.SUBM */
908 fam_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
909                 { $<ctxt>$ = start_element(ELT_FAM_SUBM,
910                                            PARENT, $1, $3, $4, $4);
911                   START(SUBM, $<ctxt>$)   
912                 }   
913                 no_std_subs   
914                 { CHECK0 }   
915                 CLOSE
916                 { end_element(ELT_FAM_SUBM, PARENT, $<ctxt>5, NULL);
917                 }
918               ;
919
920 /*********************************************************************/
921 /**** Individual record                                           ****/
922 /*********************************************************************/
923 indiv_rec   : OPEN DELIM POINTER DELIM TAG_INDI
924               { $<ctxt>$ = start_record(REC_INDI, $1, $3, $5);
925                 START(INDI, $<ctxt>$) }
926               indi_subs
927               { CHECK0 }
928               CLOSE
929               { end_record(REC_INDI, $<ctxt>6); }
930             ;
931
932 indi_subs   : /* empty */
933             | indi_subs indi_sub
934             ;
935
936 indi_sub    : indi_resn_sect  { OCCUR2(RESN, 0, 1) }
937             | pers_name_struc_sub  /* 0:M */
938             | indi_sex_sect  { OCCUR2(SEX, 0, 1) }
939             | indiv_even_struc_sub  /* 0:M */
940             | indiv_attr_struc_sub  /* 0:M */
941             | lds_indiv_ord_sub  /* 0:M */
942             | chi_fam_link_sub  /* 0:M */
943             | spou_fam_link_sub  /* 0:M */
944             | indi_subm_sect  /* 0:M */
945             | assoc_struc_sub  /* 0:M */
946             | indi_alia_sect  /* 0:M */
947             | indi_anci_sect  /* 0:M */
948             | indi_desi_sect  /* 0:M */
949             | source_cit_sub  /* 0:M */
950             | multim_link_sub  /* 0:M */
951             | note_struc_sub  /* 0:M */
952             | indi_rfn_sect  { OCCUR2(RFN, 0, 1) }
953             | indi_afn_sect  /* 0:M */
954             | ident_struc_sub  /* 0:1 */
955             | change_date_sub  /* 0:1 */
956             | ftree_addr_sect { if (!compat_mode(C_FTREE))
957                                   INVALID_TAG("ADDR");
958                               }
959             | no_std_sub
960             ;
961
962 /* INDI.RESN */
963 indi_resn_sect : OPEN DELIM TAG_RESN mand_line_item     
964                  { $<ctxt>$ = start_element(ELT_INDI_RESN,
965                                             PARENT, $1, $3, $4, $4);
966                    START(RESN, $<ctxt>$)    
967                  }    
968                  no_std_subs     
969                  { CHECK0 }     
970                  CLOSE     
971                  { end_element(ELT_INDI_RESN, PARENT, $<ctxt>5, NULL);
972                  }
973                ;
974
975 /* INDI.SEX */
976 indi_sex_sect  : OPEN DELIM TAG_SEX mand_line_item     
977                  { $<ctxt>$ = start_element(ELT_INDI_SEX,
978                                             PARENT, $1, $3, $4, $4);
979                    START(SEX, $<ctxt>$)     
980                  }     
981                  no_std_subs     
982                  { CHECK0 }     
983                  CLOSE     
984                  { end_element(ELT_INDI_SEX, PARENT, $<ctxt>5, NULL);
985                  }
986                ;
987
988 /* INDI.SUBM */
989 indi_subm_sect : OPEN DELIM TAG_SUBM mand_pointer 
990                  { $<ctxt>$ = start_element(ELT_INDI_SUBM,
991                                             PARENT, $1, $3, $4, $4);
992                    START(SUBM, $<ctxt>$)      
993                  }      
994                  no_std_subs      
995                  { CHECK0 }      
996                  CLOSE      
997                  { end_element(ELT_INDI_SUBM, PARENT, $<ctxt>5, NULL);
998                  }
999                ;
1000
1001 /* INDI.ALIA */
1002 indi_alia_sect : OPEN DELIM TAG_ALIA mand_pointer
1003                  { $<ctxt>$ = start_element(ELT_INDI_ALIA,
1004                                             PARENT, $1, $3, $4, $4);
1005                    START(ALIA, $<ctxt>$)       
1006                  }       
1007                  no_std_subs       
1008                  { CHECK0 }       
1009                  CLOSE       
1010                  { end_element(ELT_INDI_ALIA, PARENT, $<ctxt>5, NULL);
1011                  }
1012                ;
1013
1014 /* INDI.ANCI */
1015 indi_anci_sect : OPEN DELIM TAG_ANCI mand_pointer
1016                  { $<ctxt>$ = start_element(ELT_INDI_ANCI,
1017                                             PARENT, $1, $3, $4, $4);
1018                    START(ANCI, $<ctxt>$)        
1019                  }        
1020                  no_std_subs        
1021                  { CHECK0 }        
1022                  CLOSE        
1023                  { end_element(ELT_INDI_ANCI, PARENT, $<ctxt>5, NULL);
1024                  }
1025                ;
1026
1027 /* INDI.DESI */
1028 indi_desi_sect : OPEN DELIM TAG_DESI mand_pointer
1029                  { $<ctxt>$ = start_element(ELT_INDI_DESI,
1030                                             PARENT, $1, $3, $4, $4);
1031                    START(DESI, $<ctxt>$)         
1032                  }         
1033                  no_std_subs         
1034                  { CHECK0 }         
1035                  CLOSE         
1036                  { end_element(ELT_INDI_DESI, PARENT, $<ctxt>5, NULL);
1037                  }
1038                ;
1039
1040 /* INDI.RFN */
1041 indi_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item     
1042                  { $<ctxt>$ = start_element(ELT_INDI_RFN,
1043                                             PARENT, $1, $3, $4, $4);
1044                    START(RFN, $<ctxt>$)          
1045                  }          
1046                  no_std_subs          
1047                  { CHECK0 }          
1048                  CLOSE          
1049                  { end_element(ELT_INDI_RFN, PARENT, $<ctxt>5, NULL);
1050                  }
1051                ;
1052
1053 /* INDI.AFN */
1054 indi_afn_sect  : OPEN DELIM TAG_AFN mand_line_item      
1055                  { $<ctxt>$ = start_element(ELT_INDI_AFN,
1056                                             PARENT, $1, $3, $4, $4);
1057                    START(AFN, $<ctxt>$)           
1058                  }           
1059                  no_std_subs           
1060                  { CHECK0 }           
1061                  CLOSE           
1062                  { end_element(ELT_INDI_AFN, PARENT, $<ctxt>5, NULL);
1063                  }
1064                ;
1065
1066 /* INDI.ADDR (Only for 'ftree' compatibility) */
1067 ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
1068                   { START(ADDR, NULL) } no_std_subs { CHECK0 } CLOSE { }
1069
1070 /*********************************************************************/
1071 /**** Multimedia record                                           ****/
1072 /*********************************************************************/
1073 multim_rec  : OPEN DELIM POINTER DELIM TAG_OBJE
1074               { $<ctxt>$ = start_record(REC_OBJE, $1, $3, $5);
1075                 START(OBJE, $<ctxt>$) }
1076               obje_subs
1077               { CHECK2(FORM, BLOB) }
1078               CLOSE
1079               { end_record(REC_OBJE, $<ctxt>6); }
1080             ;
1081
1082 obje_subs   : /* empty */
1083             | obje_subs obje_sub
1084             ;
1085
1086 obje_sub    : obje_form_sect  { OCCUR2(FORM, 1, 1) }
1087             | obje_titl_sect  { OCCUR2(TITL, 0, 1) }
1088             | note_struc_sub  /* 0:M */
1089             | obje_blob_sect  { OCCUR2(BLOB, 1, 1) }
1090             | obje_obje_sect  { OCCUR2(OBJE, 0, 1) }
1091             | ident_struc_sub  /* 0:1 */
1092             | change_date_sub  /* 0:1 */
1093             | no_std_sub
1094             ;
1095
1096 /* OBJE.FORM */
1097 obje_form_sect : OPEN DELIM TAG_FORM mand_line_item       
1098                  { $<ctxt>$ = start_element(ELT_OBJE_FORM,
1099                                             PARENT, $1, $3, $4, $4);
1100                    START(FORM, $<ctxt>$)            
1101                  }            
1102                  no_std_subs            
1103                  { CHECK0 }            
1104                  CLOSE            
1105                  { end_element(ELT_OBJE_FORM, PARENT, $<ctxt>5, NULL);
1106                  }
1107                ;
1108
1109 /* OBJE.TITL */
1110 obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item       
1111                  { $<ctxt>$ = start_element(ELT_OBJE_TITL,
1112                                             PARENT, $1, $3, $4, $4);
1113                    START(TITL, $<ctxt>$)             
1114                  }             
1115                  no_std_subs             
1116                  { CHECK0 }             
1117                  CLOSE             
1118                  { end_element(ELT_OBJE_TITL, PARENT, $<ctxt>5, NULL);
1119                  }
1120                ;
1121
1122 /* OBJE.BLOB */
1123 obje_blob_sect : OPEN DELIM TAG_BLOB
1124                  { $<ctxt>$ = start_element(ELT_OBJE_BLOB,
1125                                             PARENT, $1, $3, NULL, NULL);
1126                    START(BLOB, $<ctxt>$)              
1127                  }
1128                  obje_blob_subs
1129                  { CHECK1(CONT) }
1130                  CLOSE              
1131                  { end_element(ELT_OBJE_BLOB, PARENT, $<ctxt>4, NULL);
1132                  }
1133                ;
1134
1135 obje_blob_subs : /* empty */
1136                | obje_blob_subs obje_blob_sub
1137                ;
1138
1139 obje_blob_sub  : obje_blob_cont_sect  { OCCUR1(CONT, 1) }
1140                | no_std_sub
1141                ;
1142
1143 obje_blob_cont_sect : OPEN DELIM TAG_CONT mand_line_item        
1144                       { $<ctxt>$ = start_element(ELT_OBJE_BLOB_CONT,
1145                                                  PARENT, $1, $3, $4, $4);
1146                         START(CONT, $<ctxt>$)               
1147                       }                
1148                       no_std_subs                
1149                       { CHECK0 }                
1150                       CLOSE                
1151                       { end_element(ELT_OBJE_BLOB_CONT, PARENT,
1152                                     $<ctxt>5, NULL);
1153                       }
1154                     ;
1155
1156 /* OBJE.OBJE */
1157 obje_obje_sect : OPEN DELIM TAG_OBJE mand_pointer 
1158                  { $<ctxt>$ = start_element(ELT_OBJE_OBJE,
1159                                             PARENT, $1, $3, $4, $4);
1160                    START(OBJE, $<ctxt>$)  
1161                  }  
1162                  no_std_subs  
1163                  { CHECK0 }  
1164                  CLOSE  
1165                  { end_element(ELT_OBJE_OBJE, PARENT, $<ctxt>5, NULL);
1166                  }
1167                ;
1168
1169 /*********************************************************************/
1170 /**** Note record                                                 ****/
1171 /*********************************************************************/
1172 note_rec    : OPEN DELIM POINTER DELIM TAG_NOTE note_line_item
1173               { $<ctxt>$ = start_record(REC_NOTE, $1, $3, $5);
1174                 START(NOTE, $<ctxt>$) }
1175               note_subs
1176               { CHECK0 }
1177               CLOSE
1178               { end_record(REC_NOTE, $<ctxt>6); }
1179             ;
1180
1181 note_line_item : /* empty */
1182                    { if (!compat_mode(C_FTREE)) {
1183                        gedcom_error(_("Missing value")); YYERROR;
1184                      }
1185                    }
1186                | DELIM line_item
1187                    { gedcom_debug_print("==Val: %s==", $2);
1188                      $$ = $2; }
1189                ;
1190
1191 note_subs   : /* empty */
1192             | note_subs note_sub
1193             ;
1194
1195 note_sub    : continuation_sub  /* 0:M */
1196             | source_cit_sub  /* 0:M */
1197             | ident_struc_sub  /* 0:1 */
1198             | change_date_sub  /* 0:1 */
1199             | no_std_sub
1200             ;
1201
1202 /*********************************************************************/
1203 /**** Repository record                                           ****/
1204 /*********************************************************************/
1205 repos_rec   : OPEN DELIM POINTER DELIM TAG_REPO
1206               { $<ctxt>$ = start_record(REC_REPO, $1, $3, $5);
1207                 START(REPO, $<ctxt>$) }
1208               repo_subs
1209               { CHECK0 }
1210               CLOSE
1211               { end_record(REC_REPO, $<ctxt>6); }
1212             ;
1213
1214 repo_subs   : /* empty */
1215             | repo_subs repo_sub
1216             ;
1217
1218 repo_sub    : repo_name_sect  { OCCUR2(NAME, 0, 1) }
1219             | addr_struc_sub  /* 0:1 */
1220             | note_struc_sub  /* 0:M */
1221             | ident_struc_sub  /* 0:1 */
1222             | change_date_sub  /* 0:1 */
1223             | no_std_sub
1224             ;
1225
1226 /* REPO.NAME */
1227 repo_name_sect : OPEN DELIM TAG_NAME mand_line_item         
1228                  { $<ctxt>$ = start_element(ELT_REPO_NAME,
1229                                             PARENT, $1, $3, $4, $4);
1230                    START(NAME, $<ctxt>$)          
1231                  }          
1232                  no_std_subs          
1233                  { CHECK0 }          
1234                  CLOSE          
1235                  { end_element(ELT_REPO_NAME, PARENT, $<ctxt>5, NULL);
1236                  }
1237                ;
1238
1239 /*********************************************************************/
1240 /**** Source record                                               ****/
1241 /*********************************************************************/
1242 source_rec  : OPEN DELIM POINTER DELIM TAG_SOUR
1243               { $<ctxt>$ = start_record(REC_SOUR, $1, $3, $5);
1244                 START(SOUR, $<ctxt>$) }
1245               sour_subs
1246               { CHECK0 }
1247               CLOSE
1248               { end_record(REC_SOUR, $<ctxt>6); }
1249             ;
1250
1251 sour_subs   : /* empty */
1252             | sour_subs sour_sub
1253             ;
1254
1255 sour_sub    : sour_data_sect  { OCCUR2(DATA, 0, 1) }
1256             | sour_auth_sect  { OCCUR2(AUTH, 0, 1) }
1257             | sour_titl_sect  { OCCUR2(TITL, 0, 1) }
1258             | sour_abbr_sect  { OCCUR2(ABBR, 0, 1) }
1259             | sour_publ_sect  { OCCUR2(PUBL, 0, 1) }
1260             | sour_text_sect  { OCCUR2(TEXT, 0, 1) }
1261             | source_repos_cit_sub  /* 0:1 */
1262             | multim_link_sub  /* 0:M */
1263             | note_struc_sub  /* 0:M */
1264             | ident_struc_sub  /* 0:1 */
1265             | change_date_sub  /* 0:1 */
1266             | no_std_sub
1267             ;
1268
1269 /* SOUR.DATA */
1270 sour_data_sect : OPEN DELIM TAG_DATA
1271                  { START(DATA, NULL) }
1272                  sour_data_subs
1273                  { CHECK0 }
1274                  CLOSE { }
1275                ;
1276
1277 sour_data_subs : /* empty */
1278                | sour_data_subs sour_data_sub
1279                ;
1280
1281 sour_data_sub  : sour_data_even_sect  /* 0:M */
1282                | sour_data_agnc_sect  { OCCUR2(AGNC, 0, 1) }
1283                | note_struc_sub  /* 0:M */
1284                | no_std_sub
1285                ;
1286
1287 sour_data_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
1288                       { START(EVEN, NULL) }
1289                       sour_data_even_subs
1290                       { CHECK0 }
1291                       CLOSE { }
1292                     ;
1293
1294 sour_data_even_subs : /* empty */
1295                     | sour_data_even_subs sour_data_even_sub
1296                     ;
1297
1298 sour_data_even_sub  : sour_data_even_date_sect { OCCUR2(DATE, 0, 1) }
1299                     | sour_data_even_plac_sect { OCCUR2(PLAC, 0, 1) }
1300                     | no_std_sub
1301                     ;
1302
1303 sour_data_even_date_sect : OPEN DELIM TAG_DATE mand_line_item          
1304                            { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1305                          ;
1306
1307 sour_data_even_plac_sect : OPEN DELIM TAG_PLAC mand_line_item          
1308                            { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1309                          ;
1310
1311 sour_data_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item          
1312                       { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1313                     ;
1314
1315 /* SOUR.AUTH */
1316 sour_auth_sect : OPEN DELIM TAG_AUTH mand_line_item
1317                  { START(AUTH, NULL) }
1318                  sour_auth_subs
1319                  { CHECK0 }
1320                  CLOSE { }
1321                ;
1322
1323 sour_auth_subs : /* empty */
1324                | sour_auth_subs sour_auth_sub
1325                ;
1326
1327 sour_auth_sub  : continuation_sub  /* 0:M */
1328                | no_std_sub
1329                ;
1330
1331 /* SOUR.TITL */
1332 sour_titl_sect : OPEN DELIM TAG_TITL mand_line_item  
1333                  { START(TITL, NULL) }
1334                  sour_titl_subs 
1335                  { CHECK0 }
1336                  CLOSE { }
1337                ;
1338
1339 sour_titl_subs : /* empty */
1340                | sour_titl_subs sour_titl_sub
1341                ;
1342
1343 sour_titl_sub  : continuation_sub  /* 0:M */
1344                | no_std_sub
1345                ;
1346
1347 /* SOUR.ABBR */
1348 sour_abbr_sect : OPEN DELIM TAG_ABBR mand_line_item           
1349                  { START(ABBR, NULL) } no_std_subs { CHECK0 } CLOSE { }
1350                ;
1351
1352 /* SOUR.PUBL */
1353 sour_publ_sect : OPEN DELIM TAG_PUBL mand_line_item  
1354                  { START(PUBL, NULL) }
1355                  sour_publ_subs  
1356                  { CHECK0 }
1357                  CLOSE { }
1358                ;
1359
1360 sour_publ_subs : /* empty */
1361                | sour_publ_subs sour_publ_sub
1362                ;
1363
1364 sour_publ_sub  : continuation_sub  /* 0:M */
1365                | no_std_sub
1366                ;
1367
1368 /* SOUR.TEXT */
1369 sour_text_sect : OPEN DELIM TAG_TEXT mand_line_item   
1370                  { START(TEXT, NULL) }
1371                  sour_text_subs  
1372                  { CHECK0 }
1373                  CLOSE { }
1374                ;
1375
1376 sour_text_subs : /* empty */
1377                | sour_text_subs sour_text_sub
1378                ;
1379
1380 sour_text_sub  : continuation_sub  /* 0:M */
1381                | no_std_sub
1382                ;
1383
1384 /*********************************************************************/
1385 /**** Submission record                                           ****/
1386 /*********************************************************************/
1387 submis_rec  : OPEN DELIM POINTER DELIM TAG_SUBN    
1388               { $<ctxt>$ = start_record(REC_SUBN, $1, $3, $5);
1389                 START(SUBN, $<ctxt>$) }
1390               subn_subs
1391               { CHECK0 }
1392               CLOSE
1393               { end_record(REC_SUBN, $<ctxt>6); }
1394             ;
1395
1396 subn_subs   : /* empty */
1397             | subn_subs subn_sub
1398             ;
1399
1400 subn_sub    : subn_subm_sect  { OCCUR2(SUBM, 0, 1) }
1401             | subn_famf_sect  { OCCUR2(FAMF, 0, 1) }
1402             | subn_temp_sect  { OCCUR2(TEMP, 0, 1) }
1403             | subn_ance_sect  { OCCUR2(ANCE, 0, 1) }
1404             | subn_desc_sect  { OCCUR2(DESC, 0, 1) }
1405             | subn_ordi_sect  { OCCUR2(ORDI, 0, 1) }
1406             | subn_rin_sect  { OCCUR2(RIN, 0, 1) }
1407             | no_std_sub
1408             ;
1409
1410 /* SUBN.SUBM */
1411 subn_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
1412                  { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1413                ;
1414
1415 /* SUBN.FAMF */
1416 subn_famf_sect : OPEN DELIM TAG_FAMF mand_line_item            
1417                  { START(FAMF, NULL) } no_std_subs { CHECK0 } CLOSE { }
1418                ;
1419
1420 /* SUBN.TEMP */
1421 subn_temp_sect : OPEN DELIM TAG_TEMP mand_line_item            
1422                  { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1423                ;
1424
1425 /* SUBN.ANCE */
1426 subn_ance_sect : OPEN DELIM TAG_ANCE mand_line_item            
1427                  { START(ANCE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1428                ;
1429
1430 /* SUBN.DESC */
1431 subn_desc_sect : OPEN DELIM TAG_DESC mand_line_item            
1432                  { START(DESC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1433                ;
1434
1435 /* SUBN.ORDI */
1436 subn_ordi_sect : OPEN DELIM TAG_ORDI mand_line_item            
1437                  { START(ORDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1438                ;
1439
1440 /* SUBN.RIN */
1441 subn_rin_sect  : OPEN DELIM TAG_RIN mand_line_item            
1442                  { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1443                ;
1444
1445 /*********************************************************************/
1446 /**** Submitter record                                            ****/
1447 /*********************************************************************/
1448 submit_rec : OPEN DELIM POINTER DELIM TAG_SUBM    
1449              { $<ctxt>$ = start_record(REC_SUBM, $1, $3, $5);
1450                 START(SUBM, $<ctxt>$) }
1451              subm_subs
1452              { CHECK1(NAME) }
1453              CLOSE
1454              { end_record(REC_SUBM, $<ctxt>6); }
1455            ;
1456
1457 subm_subs  : /* empty */
1458            | subm_subs subm_sub
1459            ;
1460
1461 subm_sub   : subm_name_sect  { OCCUR2(NAME, 0, 1) }
1462            | addr_struc_sub  /* 0:1 */
1463            | multim_link_sub  /* 0:M */
1464            | subm_lang_sect  { OCCUR2(LANG, 0, 3) }
1465            | subm_rfn_sect  { OCCUR2(RFN, 0, 1) }
1466            | subm_rin_sect  { OCCUR2(RIN, 0, 1) }
1467            | change_date_sub  /* 0:1 */
1468            | no_std_sub
1469            ;
1470
1471 /* SUBM.NAME */
1472 subm_name_sect : OPEN DELIM TAG_NAME mand_line_item             
1473                  { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1474                ;
1475
1476 /* SUBM.LANG */
1477 subm_lang_sect : OPEN DELIM TAG_LANG mand_line_item             
1478                  { START(LANG, NULL) } no_std_subs { CHECK0 } CLOSE { }
1479                ;
1480
1481 /* SUBM.RFN */
1482 subm_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item             
1483                  { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1484                ;
1485
1486 /* SUBM.RIN */
1487 subm_rin_sect  : OPEN DELIM TAG_RIN mand_line_item             
1488                  { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1489                ;
1490
1491 /*********************************************************************/
1492 /**** Substructures                                               ****/
1493 /*********************************************************************/
1494
1495 /* ADDRESS STRUCTURE */
1496 addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) }
1497                | phon_sect { OCCUR2(PHON, 0, 3) }
1498                ;
1499
1500 addr_sect   : OPEN DELIM TAG_ADDR mand_line_item 
1501               { START(ADDR, NULL) }
1502               addr_subs
1503               { CHECK0 }
1504               CLOSE { }
1505             ;
1506
1507 addr_subs   : /* empty */
1508             | addr_subs addr_sub
1509             ;
1510
1511 addr_sub    : addr_cont_sect  /* 0:M */
1512             | addr_adr1_sect  { OCCUR2(ADR1, 0, 1) }
1513             | addr_adr2_sect  { OCCUR2(ADR2, 0, 1) }
1514             | addr_city_sect  { OCCUR2(CITY, 0, 1) }
1515             | addr_stae_sect  { OCCUR2(STAE, 0, 1) }
1516             | addr_post_sect  { OCCUR2(POST, 0, 1) }
1517             | addr_ctry_sect  { OCCUR2(CTRY, 0, 1) }
1518             | no_std_sub
1519             ;
1520
1521 addr_cont_sect : OPEN DELIM TAG_CONT mand_line_item              
1522                  { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1523                ;
1524 addr_adr1_sect : OPEN DELIM TAG_ADR1 mand_line_item              
1525                  { START(ADR1, NULL) } no_std_subs { CHECK0 } CLOSE { }
1526                ;
1527 addr_adr2_sect : OPEN DELIM TAG_ADR2 mand_line_item              
1528                  { START(ADR2, NULL) } no_std_subs { CHECK0 } CLOSE { }
1529                ;
1530 addr_city_sect : OPEN DELIM TAG_CITY mand_line_item              
1531                  { START(CITY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1532                ;
1533 addr_stae_sect : OPEN DELIM TAG_STAE mand_line_item              
1534                  { START(STAE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1535                ;
1536 addr_post_sect : OPEN DELIM TAG_POST mand_line_item              
1537                  { START(POST, NULL) } no_std_subs { CHECK0 } CLOSE { }
1538                ;
1539 addr_ctry_sect : OPEN DELIM TAG_CTRY mand_line_item              
1540                  { START(CTRY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1541                ;
1542
1543 phon_sect   : OPEN DELIM TAG_PHON mand_line_item              
1544               { START(PHON, NULL) } no_std_subs { CHECK0 } CLOSE { }
1545             ;
1546
1547 /* ASSOCIATION STRUCTURE */
1548 assoc_struc_sub : asso_sect /* 0:M */
1549                 ;
1550
1551 asso_sect : OPEN DELIM TAG_ASSO mand_pointer
1552             { START(ASSO, NULL) }
1553             asso_subs
1554             { CHECK2(TYPE,RELA) }
1555             CLOSE { }
1556           ;
1557
1558 asso_subs : /* empty */
1559           | asso_type_sect  { OCCUR2(TYPE, 1, 1) }
1560           | asso_rela_sect  { OCCUR2(RELA, 1, 1) }
1561           | note_struc_sub
1562           | source_cit_sub
1563           | no_std_sub
1564           ;
1565
1566 asso_type_sect : OPEN DELIM TAG_TYPE mand_line_item               
1567                  { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1568                ;
1569
1570 asso_rela_sect : OPEN DELIM TAG_RELA mand_line_item               
1571                  { START(RELA, NULL) } no_std_subs { CHECK0 } CLOSE { }
1572                ;
1573
1574 /* CHANGE DATE */
1575 change_date_sub : change_date_chan_sect  { OCCUR2(CHAN, 0, 1) }
1576                 ;
1577
1578 change_date_chan_sect : OPEN DELIM TAG_CHAN
1579                         { START(CHAN, NULL) }
1580                         change_date_chan_subs
1581                         { CHECK1(DATE) }
1582                         CLOSE { }
1583                       ;
1584
1585 change_date_chan_subs : /* empty */
1586                       | change_date_chan_subs change_date_chan_sub
1587                       ;
1588
1589 change_date_chan_sub  : change_date_date_sect  { OCCUR2(DATE, 1, 1) }
1590                       | note_struc_sub
1591                       | no_std_sub
1592                       ;
1593
1594 change_date_date_sect : OPEN DELIM TAG_DATE mand_line_item 
1595                         { START(DATE, NULL) }
1596                         change_date_date_subs
1597                         { CHECK0 }
1598                         CLOSE { }
1599                       ;
1600
1601 change_date_date_subs : /* empty */
1602                       | change_date_date_subs change_date_date_sub
1603                       ;
1604
1605 change_date_date_sub : change_date_date_time_sect  { OCCUR2(TIME, 0, 1) }
1606                      | no_std_sub
1607                      ;
1608
1609 change_date_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
1610                              { START(TIME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1611                            ;
1612
1613 /* CHILD TO FAMILY LINK */
1614 chi_fam_link_sub : famc_sect  /* 0:M */
1615                  ;
1616
1617 famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1618             { START(FAMC, NULL) }
1619             famc_subs
1620             { CHECK0 }
1621             CLOSE { }
1622           ;
1623
1624 famc_subs : /* empty */
1625           | famc_subs famc_sub
1626           ;
1627
1628 famc_sub  : famc_pedi_sect  /* 0:M */
1629           | note_struc_sub
1630           | no_std_sub
1631           ;
1632
1633 famc_pedi_sect : OPEN DELIM TAG_PEDI mand_line_item 
1634                  { START(PEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1635                ;
1636
1637 /* CONTINUATION SUBSECTIONS */
1638 continuation_sub : cont_sect  /* 0:M */
1639                  | conc_sect  /* 0:M */
1640                  ;
1641
1642 cont_sect : OPEN DELIM TAG_CONT mand_line_item 
1643             { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1644           ;
1645
1646 conc_sect : OPEN DELIM TAG_CONC mand_line_item 
1647             { START(CONC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1648           ; 
1649
1650 /* EVENT DETAIL */
1651 event_detail_sub : event_detail_type_sect  { OCCUR2(TYPE, 0, 1) }
1652                  | event_detail_date_sect  { OCCUR2(DATE, 0, 1) }
1653                  | place_struc_sub
1654                  | addr_struc_sub
1655                  | event_detail_age_sect  { OCCUR2(AGE, 0, 1) }
1656                  | event_detail_agnc_sect  { OCCUR2(AGNC, 0, 1) }
1657                  | event_detail_caus_sect  { OCCUR2(CAUS, 0, 1) }
1658                  | source_cit_sub
1659                  | multim_link_sub
1660                  | note_struc_sub
1661                  ;
1662
1663 event_detail_type_sect : OPEN DELIM TAG_TYPE mand_line_item 
1664                          { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1665                        ;
1666 event_detail_date_sect : OPEN DELIM TAG_DATE mand_line_item 
1667                          { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1668                        ;
1669 event_detail_age_sect  : OPEN DELIM TAG_AGE mand_line_item 
1670                          { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1671                        ;
1672 event_detail_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item 
1673                          { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1674                        ;
1675 event_detail_caus_sect : OPEN DELIM TAG_CAUS mand_line_item 
1676                          { START(CAUS, NULL) } no_std_subs { CHECK0 } CLOSE { }
1677                        ;
1678
1679 /* FAMILY EVENT STRUCTURE */
1680 fam_event_struc_sub : fam_event_sect
1681                     | fam_gen_even_sect  /* 0:M */
1682                     ;
1683
1684 fam_event_sect : OPEN DELIM fam_event_tag opt_value fam_event_subs
1685                  { CHECK0 }
1686                  CLOSE { }
1687                ;
1688
1689 fam_event_tag : TAG_ANUL { START(ANUL, NULL) }
1690               | TAG_CENS { START(CENS, NULL) }
1691               | TAG_DIV { START(DIV, NULL) }
1692               | TAG_DIVF { START(DIVF, NULL) }
1693               | TAG_ENGA { START(ENGA, NULL) }
1694               | TAG_MARR { START(MARR, NULL) }
1695               | TAG_MARB { START(MARB, NULL) }
1696               | TAG_MARC { START(MARC, NULL) }
1697               | TAG_MARL { START(MARL, NULL) }
1698               | TAG_MARS { START(MARS, NULL) }
1699               ;
1700
1701 fam_event_subs : /* empty */
1702                | fam_event_subs fam_event_sub
1703                ;
1704
1705 fam_event_sub : event_detail_sub
1706               | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
1707               | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
1708               | no_std_sub
1709               ;
1710
1711 fam_even_husb_sect : OPEN DELIM TAG_HUSB
1712                      { START(HUSB, NULL) }
1713                      fam_even_husb_subs
1714                      { CHECK1(AGE) }
1715                      CLOSE { }
1716                    ;
1717
1718 fam_even_husb_subs : /* empty */
1719                    | fam_even_husb_subs fam_even_husb_sub
1720                    ;
1721
1722 fam_even_husb_sub : fam_even_husb_age_sect  { OCCUR2(AGE, 1, 1) }
1723                   | no_std_sub
1724                   ;
1725
1726 fam_even_husb_age_sect : OPEN DELIM TAG_AGE mand_line_item  
1727                          { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1728                        ;
1729
1730 fam_even_wife_sect : OPEN DELIM TAG_WIFE
1731                      { START(HUSB, NULL) }
1732                      fam_even_husb_subs
1733                      { CHECK1(AGE) }
1734                      CLOSE { }
1735                    ;
1736
1737 fam_gen_even_sect : OPEN DELIM TAG_EVEN
1738                     { START(EVEN, NULL) }
1739                     fam_gen_even_subs
1740                     { CHECK0 }
1741                     CLOSE { }
1742                   ;
1743
1744 fam_gen_even_subs : /* empty */
1745                   | fam_gen_even_subs fam_gen_even_sub
1746                   ;
1747
1748 fam_gen_even_sub : event_detail_sub
1749                  | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
1750                  | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
1751                  | no_std_sub
1752                  ;
1753
1754 /* IDENTIFICATION STRUCTURE */
1755 ident_struc_sub : ident_refn_sect  /* 0:M */
1756                 | ident_rin_sect  { OCCUR2(RIN, 0, 1) }
1757                 ;
1758
1759 ident_refn_sect : OPEN DELIM TAG_REFN mand_line_item 
1760                   { START(REFN, NULL) }
1761                   ident_refn_subs
1762                   { CHECK0 }
1763                   CLOSE { }
1764                 ;
1765
1766 ident_refn_subs : /* empty */
1767                 | ident_refn_subs ident_refn_sub
1768                 ;
1769
1770 ident_refn_sub  : ident_refn_type_sect  { OCCUR2(TYPE, 0, 1) }
1771                 | no_std_sub
1772                 ;
1773
1774 ident_refn_type_sect : OPEN DELIM TAG_TYPE mand_line_item   
1775                        { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1776                      ;
1777
1778 ident_rin_sect  : OPEN DELIM TAG_RIN mand_line_item   
1779                   { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1780                 ;
1781
1782 /* INDIVIDUAL ATTRIBUTE STRUCTURE */
1783 indiv_attr_struc_sub : indiv_cast_sect  /* 0:M */
1784                      | indiv_dscr_sect  /* 0:M */
1785                      | indiv_educ_sect  /* 0:M */
1786                      | indiv_idno_sect  /* 0:M */
1787                      | indiv_nati_sect  /* 0:M */
1788                      | indiv_nchi_sect  /* 0:M */
1789                      | indiv_nmr_sect  /* 0:M */
1790                      | indiv_occu_sect  /* 0:M */
1791                      | indiv_prop_sect  /* 0:M */
1792                      | indiv_reli_sect  /* 0:M */
1793                      | indiv_resi_sect  /* 0:M */
1794                      | indiv_ssn_sect  /* 0:M */
1795                      | indiv_titl_sect  /* 0:M */
1796                      ;
1797
1798 indiv_cast_sect : OPEN DELIM TAG_CAST mand_line_item 
1799                   { START(CAST, NULL) }
1800                   indiv_attr_event_subs
1801                   { CHECK0 }
1802                   CLOSE { }
1803                 ;
1804 indiv_dscr_sect : OPEN DELIM TAG_DSCR mand_line_item 
1805                   { START(DSCR, NULL) }
1806                   indiv_attr_event_subs
1807                   { CHECK0 }
1808                   CLOSE { }
1809                 ;
1810 indiv_educ_sect : OPEN DELIM TAG_EDUC mand_line_item  
1811                   { START(EDUC, NULL) }
1812                   indiv_attr_event_subs 
1813                   { CHECK0 }
1814                   CLOSE { }
1815                 ;
1816 indiv_idno_sect : OPEN DELIM TAG_IDNO mand_line_item 
1817                   { START(IDNO, NULL) }
1818                   indiv_attr_event_subs 
1819                   { CHECK0 }
1820                   CLOSE { }
1821                 ;
1822 indiv_nati_sect : OPEN DELIM TAG_NATI mand_line_item 
1823                   { START(NATI, NULL) }
1824                   indiv_attr_event_subs 
1825                   { CHECK0 }
1826                   CLOSE { }
1827                 ;
1828 indiv_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item 
1829                   { START(NCHI, NULL) }
1830                   indiv_attr_event_subs 
1831                   { CHECK0 }
1832                   CLOSE { }
1833                 ;
1834 indiv_nmr_sect  : OPEN DELIM TAG_NMR mand_line_item 
1835                   { START(NMR, NULL) }
1836                   indiv_attr_event_subs 
1837                   { CHECK0 }
1838                   CLOSE { }
1839                 ;
1840 indiv_occu_sect : OPEN DELIM TAG_OCCU mand_line_item 
1841                   { START(OCCU, NULL) }
1842                   indiv_attr_event_subs 
1843                   { CHECK0 }
1844                   CLOSE { }
1845                 ;
1846 indiv_prop_sect : OPEN DELIM TAG_PROP mand_line_item 
1847                   { START(PROP, NULL) }
1848                   indiv_attr_event_subs 
1849                   { CHECK0 }
1850                   CLOSE { }
1851                 ;
1852 indiv_reli_sect : OPEN DELIM TAG_RELI mand_line_item 
1853                   { START(RELI, NULL) }
1854                   indiv_attr_event_subs 
1855                   { CHECK0 }
1856                   CLOSE { }
1857                 ;
1858 indiv_resi_sect : OPEN DELIM TAG_RESI 
1859                   { START(RESI, NULL) }
1860                   indiv_attr_event_subs 
1861                   { CHECK0 }
1862                   CLOSE { }
1863                 ;
1864 indiv_ssn_sect  : OPEN DELIM TAG_SSN mand_line_item 
1865                   { START(SSN, NULL) }
1866                   indiv_attr_event_subs 
1867                   { CHECK0 }
1868                   CLOSE { }
1869                 ;
1870 indiv_titl_sect : OPEN DELIM TAG_TITL mand_line_item 
1871                   { START(TITL, NULL) }
1872                   indiv_attr_event_subs 
1873                   { CHECK0 }
1874                   CLOSE { }
1875                 ;
1876
1877 indiv_attr_event_subs : /* empty */
1878                       | indiv_attr_event_subs indiv_attr_event_sub
1879                       ;
1880
1881 indiv_attr_event_sub  : event_detail_sub
1882                       | no_std_sub
1883                       ;
1884
1885 /* INDIVIDUAL EVENT STRUCTURE */
1886 indiv_even_struc_sub : indiv_birt_sect
1887                      | indiv_gen_sect
1888                      | indiv_adop_sect  /* 0:M */
1889                      | indiv_even_sect  /* 0:M */
1890                      ;
1891
1892 indiv_birt_sect : OPEN DELIM indiv_birt_tag opt_value indiv_birt_subs
1893                   { CHECK0 }
1894                   CLOSE { }
1895                 ;
1896
1897 indiv_birt_tag  : TAG_BIRT { START(BIRT, NULL) }
1898                 | TAG_CHR { START(CHR, NULL) }
1899                 ;
1900
1901 indiv_birt_subs : /* empty */
1902                 | indiv_birt_subs indiv_birt_sub
1903                 ;
1904
1905 indiv_birt_sub  : event_detail_sub
1906                 | indiv_birt_famc_sect  { OCCUR2(FAMC,0, 1) }
1907                 | no_std_sub
1908                 ;
1909
1910 indiv_birt_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1911                        { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1912                      ;
1913
1914 indiv_gen_sect  : OPEN DELIM indiv_gen_tag opt_value indiv_gen_subs
1915                   { CHECK0 }
1916                   CLOSE { }
1917                 ;
1918
1919 indiv_gen_tag   : TAG_DEAT { START(DEAT, NULL) }
1920                 | TAG_BURI { START(BURI, NULL) }
1921                 | TAG_CREM { START(CREM, NULL) }
1922                 | TAG_BAPM { START(BAPM, NULL) }
1923                 | TAG_BARM { START(BARM, NULL) }
1924                 | TAG_BASM { START(BASM, NULL) }
1925                 | TAG_BLES { START(BLES, NULL) }
1926                 | TAG_CHRA { START(CHRA, NULL) }
1927                 | TAG_CONF { START(CONF, NULL) }
1928                 | TAG_FCOM { START(FCOM, NULL) }
1929                 | TAG_ORDN { START(ORDN, NULL) }
1930                 | TAG_NATU { START(NATU, NULL) }
1931                 | TAG_EMIG { START(EMIG, NULL) }
1932                 | TAG_IMMI { START(IMMI, NULL) }
1933                 | TAG_CENS { START(CENS, NULL) }
1934                 | TAG_PROB { START(PROB, NULL) }
1935                 | TAG_WILL { START(WILL, NULL) }
1936                 | TAG_GRAD { START(GRAD, NULL) }
1937                 | TAG_RETI { START(RETI, NULL) }
1938                 ;
1939
1940 indiv_gen_subs  : /* empty */
1941                 | indiv_gen_subs indiv_gen_sub
1942                 ;
1943
1944 indiv_gen_sub   : event_detail_sub
1945                 | no_std_sub
1946                 ;
1947
1948 indiv_adop_sect : OPEN DELIM TAG_ADOP opt_value 
1949                   { START(ADOP, NULL) }
1950                   indiv_adop_subs
1951                   { CHECK0 }
1952                   CLOSE { }
1953                 ;
1954
1955 indiv_adop_subs : /* empty */
1956                 | indiv_adop_subs indiv_adop_sub
1957                 ;
1958
1959 indiv_adop_sub  : event_detail_sub
1960                 | indiv_adop_famc_sect  { OCCUR2(FAMC,0, 1) }
1961                 | no_std_sub
1962                 ;
1963
1964 indiv_adop_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1965                        { START(FAMC, NULL) }
1966                        indiv_adop_famc_subs
1967                        { CHECK0 }
1968                        CLOSE { }
1969                      ;
1970
1971 indiv_adop_famc_subs : /* empty */
1972                      | indiv_adop_famc_subs indiv_adop_famc_sub
1973                      ;
1974
1975 indiv_adop_famc_sub  : indiv_adop_famc_adop_sect  { OCCUR2(ADOP,0, 1) }
1976                      | no_std_sub
1977                      ;
1978
1979 indiv_adop_famc_adop_sect : OPEN DELIM TAG_ADOP mand_line_item   
1980                             { START(ADOP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1981                           ;
1982
1983 indiv_even_sect : OPEN DELIM TAG_EVEN
1984                   { START(EVEN, NULL) }
1985                   indiv_gen_subs
1986                   { CHECK0 }
1987                   CLOSE { }
1988                 ;
1989
1990 /* LDS INDIVIDUAL ORDINANCE */
1991 lds_indiv_ord_sub : lio_bapl_sect  /* 0:M */
1992                   | lio_slgc_sect  /* 0:M */
1993                   ;
1994
1995 lio_bapl_sect : OPEN DELIM lio_bapl_tag lio_bapl_subs
1996                 { CHECK0 }
1997                 CLOSE { }
1998               ;
1999
2000 lio_bapl_tag  : TAG_BAPL { START(BAPL, NULL) }
2001               | TAG_CONL { START(CONL, NULL) }
2002               | TAG_ENDL { START(ENDL, NULL) }
2003               ;
2004
2005 lio_bapl_subs : /* empty */
2006               | lio_bapl_subs lio_bapl_sub
2007               ;
2008
2009 lio_bapl_sub  : lio_bapl_stat_sect  { OCCUR2(STAT, 0, 1) }
2010               | lio_bapl_date_sect  { OCCUR2(DATE, 0, 1) }
2011               | lio_bapl_temp_sect  { OCCUR2(TEMP, 0, 1) }
2012               | lio_bapl_plac_sect  { OCCUR2(PLAC, 0, 1) }
2013               | source_cit_sub
2014               | note_struc_sub
2015               | no_std_sub
2016               ;
2017
2018 lio_bapl_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
2019                      { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
2020                    ;
2021 lio_bapl_date_sect : OPEN DELIM TAG_DATE mand_line_item   
2022                      { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2023                    ;
2024 lio_bapl_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
2025                      { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
2026                    ;
2027 lio_bapl_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
2028                      { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
2029                    ;
2030
2031 lio_slgc_sect : OPEN DELIM TAG_SLGC
2032                 { START(SLGC, NULL) }
2033                 lio_slgc_subs
2034                 { CHECK1(FAMC) }
2035                 CLOSE { }
2036               ;
2037
2038 lio_slgc_subs : /* empty */
2039               | lio_slgc_subs lio_slgc_sub
2040               ;
2041
2042 lio_slgc_sub  : lio_bapl_sub
2043               | lio_slgc_famc_sect  { OCCUR2(FAMC, 1, 1) }
2044               ;
2045
2046 lio_slgc_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2047                      { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
2048                    ;
2049
2050 /* LDS SPOUSE SEALING */
2051 lds_spouse_seal_sub : lss_slgs_sect
2052                     ;
2053
2054 lss_slgs_sect : OPEN DELIM TAG_SLGS
2055                 { START(SLGS, NULL) }
2056                 lss_slgs_subs
2057                 { CHECK0 }
2058                 CLOSE { }
2059               ;
2060
2061 lss_slgs_subs : /* empty */
2062               | lss_slgs_subs lss_slgs_sub
2063               ;
2064
2065 lss_slgs_sub  : lss_slgs_stat_sect  { OCCUR2(STAT, 0, 1) }
2066               | lss_slgs_date_sect  { OCCUR2(DATE, 0, 1) }
2067               | lss_slgs_temp_sect  { OCCUR2(TEMP, 0, 1) }
2068               | lss_slgs_plac_sect  { OCCUR2(PLAC, 0, 1) }
2069               | source_cit_sub
2070               | note_struc_sub
2071               | no_std_sub
2072               ;
2073
2074 lss_slgs_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
2075                      { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
2076                    ;
2077 lss_slgs_date_sect : OPEN DELIM TAG_DATE mand_line_item   
2078                      { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2079                    ;
2080 lss_slgs_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
2081                      { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
2082                    ;
2083 lss_slgs_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
2084                      { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
2085                    ;
2086
2087 /* MULTIMEDIA LINK */
2088 multim_link_sub : multim_obje_link_sect
2089                 | multim_obje_emb_sect
2090                 ;
2091
2092 multim_obje_link_sect : OPEN DELIM TAG_OBJE DELIM POINTER    
2093                         { START(OBJE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2094                       ;
2095
2096 multim_obje_emb_sect : OPEN DELIM TAG_OBJE
2097                        { START(OBJE, NULL) }
2098                        multim_obje_emb_subs
2099                        { CHECK2(FORM,FILE) }
2100                        CLOSE { }
2101                      ;
2102
2103 multim_obje_emb_subs : /* empty */
2104                      | multim_obje_emb_subs multim_obje_emb_sub
2105                      ;
2106
2107 multim_obje_emb_sub : multim_obje_form_sect  { OCCUR2(FORM, 1, 1) }
2108                     | multim_obje_titl_sect  { OCCUR2(TITL, 0, 1) }
2109                     | multim_obje_file_sect  { OCCUR2(FILE, 1, 1) }
2110                     | note_struc_sub
2111                     | no_std_sub
2112                     ;
2113
2114 multim_obje_form_sect : OPEN DELIM TAG_FORM mand_line_item    
2115                         { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
2116                       ;
2117 multim_obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item    
2118                         { START(TITL, NULL) } no_std_subs { CHECK0 } CLOSE { }
2119                       ;
2120 multim_obje_file_sect : OPEN DELIM TAG_FILE mand_line_item    
2121                         { START(FILE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2122                       ;
2123
2124 /* NOTE STRUCTURE */
2125 note_struc_sub : note_struc_link_sect  /* 0:M */
2126                | note_struc_emb_sect  /* 0:M */
2127                ;
2128
2129 note_struc_link_sect : OPEN DELIM TAG_NOTE DELIM POINTER
2130                        { START(NOTE, NULL) }
2131                        note_struc_link_subs
2132                        { CHECK0 }
2133                        CLOSE { }
2134                      ;
2135
2136 note_struc_link_subs : /* empty */
2137                      | note_struc_link_subs note_struc_link_sub
2138                      ;
2139
2140 note_struc_link_sub : source_cit_sub
2141                     | no_std_sub
2142                     ;
2143
2144 note_struc_emb_sect : OPEN DELIM TAG_NOTE opt_line_item
2145                       { START(NOTE, NULL) }
2146                       note_struc_emb_subs
2147                       { CHECK0 }
2148                       CLOSE { }
2149                     ;
2150
2151 note_struc_emb_subs : /* empty */
2152                     | note_struc_emb_subs note_struc_emb_sub
2153                     ;
2154
2155 note_struc_emb_sub  : continuation_sub
2156                     | source_cit_sub
2157                     | no_std_sub
2158                     ;
2159
2160 /* PERSONAL NAME STRUCTURE */
2161 pers_name_struc_sub : pers_name_sect /* 0:M */
2162                     ;
2163
2164 pers_name_sect : OPEN DELIM TAG_NAME mand_line_item 
2165                  { START(NAME, NULL) }
2166                  pers_name_subs
2167                  { CHECK0 }
2168                  CLOSE { }
2169                ;
2170
2171 pers_name_subs : /* empty */
2172                | pers_name_subs pers_name_sub
2173                ;
2174
2175 pers_name_sub  : pers_name_npfx_sect  { OCCUR2(NPFX, 0, 1) }
2176                | pers_name_givn_sect  { OCCUR2(GIVN, 0, 1) }
2177                | pers_name_nick_sect  { OCCUR2(NICK, 0, 1) }
2178                | pers_name_spfx_sect  { OCCUR2(SPFX, 0, 1) }
2179                | pers_name_surn_sect  { OCCUR2(SURN, 0, 1) }
2180                | pers_name_nsfx_sect  { OCCUR2(NSFX, 0, 1) }
2181                | source_cit_sub
2182                | note_struc_sub
2183                | no_std_sub
2184                ;
2185
2186 pers_name_npfx_sect : OPEN DELIM TAG_NPFX mand_line_item    
2187                       { START(NPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2188                     ;
2189 pers_name_givn_sect : OPEN DELIM TAG_GIVN mand_line_item    
2190                       { START(GIVN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2191                     ;
2192 pers_name_nick_sect : OPEN DELIM TAG_NICK mand_line_item    
2193                       { START(NICK, NULL) } no_std_subs { CHECK0 } CLOSE { }
2194                     ;
2195 pers_name_spfx_sect : OPEN DELIM TAG_SPFX mand_line_item    
2196                       { START(SPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2197                     ;
2198 pers_name_surn_sect : OPEN DELIM TAG_SURN mand_line_item    
2199                       { START(SURN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2200                     ;
2201 pers_name_nsfx_sect : OPEN DELIM TAG_NSFX mand_line_item    
2202                       { START(NSFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2203                     ;
2204
2205 /* PLACE STRUCTURE */
2206 place_struc_sub : place_struc_plac_sect /* 0:M */
2207                 ;
2208
2209 place_struc_plac_sect : OPEN DELIM TAG_PLAC mand_line_item 
2210                         { START(PLAC, NULL) }
2211                         place_struc_plac_subs
2212                         { CHECK0 }
2213                         CLOSE { }
2214                       ;
2215
2216 place_struc_plac_subs : /* empty */
2217                       | place_struc_plac_subs place_struc_plac_sub
2218                       ;
2219
2220 place_struc_plac_sub : place_plac_form_sect  { OCCUR2(FORM, 0, 1) }
2221                      | source_cit_sub
2222                      | note_struc_sub
2223                      | no_std_sub
2224                      ;
2225
2226 place_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item    
2227                        { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
2228                      ;
2229
2230 /* SOURCE_CITATION */
2231 source_cit_sub : source_cit_link_sect /* 0:M */
2232                | source_cit_emb_sect /* 0:M */
2233                ;
2234
2235 source_cit_link_sect : OPEN DELIM TAG_SOUR DELIM POINTER
2236                        { START(SOUR, NULL) }
2237                        source_cit_link_subs
2238                        { CHECK0 }
2239                        CLOSE { }
2240                      ;
2241
2242 source_cit_link_subs : /* empty */
2243                      | source_cit_link_subs source_cit_link_sub
2244                      ;
2245
2246 source_cit_link_sub : source_cit_page_sect  { OCCUR2(PAGE, 0, 1) }
2247                     | source_cit_even_sect  { OCCUR2(EVEN, 0, 1) }
2248                     | source_cit_data_sect  { OCCUR2(DATA, 0, 1) }
2249                     | source_cit_quay_sect  { OCCUR2(QUAY, 0, 1) }
2250                     | multim_link_sub
2251                     | note_struc_sub
2252                     | no_std_sub
2253                     ;
2254
2255 source_cit_page_sect : OPEN DELIM TAG_PAGE mand_line_item    
2256                        { START(PAGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2257                      ;
2258
2259 source_cit_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
2260                        { START(EVEN, NULL) }
2261                        source_cit_even_subs
2262                        { CHECK0 }
2263                        CLOSE { }
2264                      ;
2265
2266 source_cit_even_subs : /* empty */
2267                      | source_cit_even_subs source_cit_even_sub
2268                      ;
2269
2270 source_cit_even_sub  : source_cit_even_role_sect  { OCCUR2(ROLE, 0, 1) }
2271                      | no_std_sub
2272                      ;
2273
2274 source_cit_even_role_sect : OPEN DELIM TAG_ROLE mand_line_item    
2275                           { START(ROLE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2276                           ;
2277
2278 source_cit_data_sect : OPEN DELIM TAG_DATA
2279                        { START(DATA, NULL) }
2280                        source_cit_data_subs
2281                        { CHECK0 }
2282                        CLOSE { }
2283                      ;
2284
2285 source_cit_data_subs : /* empty */
2286                      | source_cit_data_subs source_cit_data_sub
2287                      ;
2288
2289 source_cit_data_sub : source_cit_data_date_sect  { OCCUR2(DATE, 0, 1) }
2290                     | source_cit_text_sect  /* 0:M */
2291                     | no_std_sub
2292                     ;
2293
2294 source_cit_data_date_sect : OPEN DELIM TAG_DATE mand_line_item    
2295                             { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2296                           ;
2297
2298 source_cit_text_sect : OPEN DELIM TAG_TEXT mand_line_item 
2299                        { START(TEXT, NULL) }
2300                        source_cit_text_subs
2301                        { CHECK0 }
2302                        CLOSE { }
2303                      ;
2304
2305 source_cit_text_subs : /* empty */
2306                      | source_cit_text_subs source_cit_text_sub
2307                      ;
2308
2309 source_cit_text_sub : continuation_sub
2310                     | no_std_sub
2311                     ;
2312
2313 source_cit_quay_sect : OPEN DELIM TAG_QUAY mand_line_item    
2314                        { START(QUAY, NULL) } no_std_subs { CHECK0 } CLOSE { }
2315                      ;
2316
2317 source_cit_emb_sect : OPEN DELIM TAG_SOUR mand_line_item
2318                       { START(SOUR, NULL) }
2319                       source_cit_emb_subs
2320                       { CHECK0 }
2321                       CLOSE { }
2322                     ;
2323
2324 source_cit_emb_subs : /* empty */
2325                     | source_cit_emb_subs source_cit_emb_sub
2326                     ;
2327
2328 source_cit_emb_sub : continuation_sub
2329                    | source_cit_text_sect  /* 0:M */
2330                    | note_struc_sub
2331                    | no_std_sub
2332                    ;
2333
2334 /* SOURCE REPOSITORY CITATION */
2335 source_repos_cit_sub : source_repos_repo_sect  { OCCUR2(REPO, 0, 1) }
2336                      ;
2337
2338 source_repos_repo_sect : OPEN DELIM TAG_REPO mand_pointer
2339                          { START(REPO, NULL) }
2340                          source_repos_repo_subs
2341                          { CHECK0 }
2342                          CLOSE { }
2343                        ;
2344
2345 source_repos_repo_subs : /* empty */
2346                        | source_repos_repo_subs source_repos_repo_sub
2347                        ;
2348
2349 source_repos_repo_sub  : note_struc_sub
2350                        | caln_sect  /* 0:M */
2351                        | no_std_sub
2352                        ;
2353
2354 caln_sect : OPEN DELIM TAG_CALN mand_line_item 
2355             { START(CALN, NULL) }
2356             caln_subs
2357             { CHECK0 }
2358             CLOSE { }
2359           ;
2360
2361 caln_subs : /* empty */
2362           | caln_subs caln_sub
2363           ;
2364
2365 caln_sub  : caln_medi_sect  { OCCUR2(MEDI, 0, 1) }
2366           | no_std_sub
2367           ;
2368
2369 caln_medi_sect : OPEN DELIM TAG_MEDI mand_line_item    
2370                  { START(MEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
2371                ;
2372  
2373 /* SPOUSE TO FAMILY LINK */
2374 spou_fam_link_sub : spou_fam_fams_sect  /* 0:M */
2375                   ;
2376
2377 spou_fam_fams_sect : OPEN DELIM TAG_FAMS mand_pointer
2378                      { START(FAMS, NULL) }
2379                      spou_fam_fams_subs
2380                      { CHECK0 }
2381                      CLOSE { }
2382                    ;
2383
2384 spou_fam_fams_subs : /* empty */
2385                    | spou_fam_fams_subs spou_fam_fams_sub
2386                    ;
2387
2388 spou_fam_fams_sub  : note_struc_sub
2389                    | no_std_sub
2390                    ;
2391
2392 /*********************************************************************/
2393 /**** Special values                                              ****/
2394 /*********************************************************************/
2395
2396 /*********************************************************************/
2397 /**** General                                                     ****/
2398 /*********************************************************************/
2399
2400 no_std_subs : /* empty */
2401             | no_std_subs no_std_sub
2402             ;
2403
2404 no_std_sub  : user_sect /* 0:M */
2405             | gen_sect
2406             | error error_subs CLOSE  { HANDLE_ERROR }
2407             ;
2408
2409 no_std_rec  : user_rec /* 0:M */
2410             | gen_rec
2411             | error error_subs CLOSE  { HANDLE_ERROR }
2412             ;
2413
2414 user_rec    : OPEN DELIM opt_xref USERTAG 
2415               { if ($4[0] != '_') {
2416                   gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
2417                                $4);
2418                   YYERROR;
2419                 }
2420               }
2421               opt_value
2422               { $<ctxt>$ = start_record(REC_USER, $1, $3, $4);
2423                 START($4, $<ctxt>$)
2424               }
2425               user_sects
2426               { CHECK0 }
2427               CLOSE
2428               { end_record(REC_USER, $<ctxt>7); }
2429             ;
2430 user_sect   : OPEN DELIM opt_xref USERTAG 
2431               { if ($4[0] != '_') {
2432                   gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
2433                                $4);
2434                   YYERROR;
2435                 }
2436               }
2437               opt_value
2438               { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6, $6);
2439                 START($4, $<ctxt>$);
2440               }
2441               user_sects
2442               { CHECK0 }
2443               CLOSE
2444               { end_element(ELT_USER, PARENT, $<ctxt>7, NULL);
2445               }
2446             ;
2447
2448 user_sects   : /* empty */     { }
2449             | user_sects user_sect { }
2450             ;
2451
2452 opt_xref    : /* empty */        { $$ = NULL; }
2453             | POINTER DELIM        { $$ = $1; }
2454             ;
2455
2456 opt_value   : /* empty */        { $$ = NULL; }
2457             | DELIM line_value        { $$ = $2; }
2458             ;
2459
2460 line_value  : POINTER        { $$ = $1; }
2461             | line_item        { $$ = $1; }
2462             ;
2463
2464 mand_pointer : /* empty */ { gedcom_error(_("Missing pointer")); YYERROR; }
2465              | DELIM POINTER { gedcom_debug_print("==Ptr: %s==", $2);
2466                                $$ = $2; }
2467              ;
2468
2469 mand_line_item : /* empty */ { gedcom_error(_("Missing value")); YYERROR; }
2470                | DELIM line_item { gedcom_debug_print("==Val: %s==", $2);
2471                                    $$ = $2; }
2472                ;
2473
2474 opt_line_item : /* empty */ { }
2475               | DELIM line_item { }
2476               ;
2477
2478 line_item   : anychar  { size_t i;
2479                          CLEAR_BUFFER(line_item_buf);
2480                          line_item_buf_ptr = line_item_buf;
2481                          /* The following also takes care of '@@' */
2482                          if (!strncmp($1, "@@", 3))
2483                            *line_item_buf_ptr++ = '@';
2484                          else
2485                            for (i=0; i < strlen($1); i++)
2486                              *line_item_buf_ptr++ = $1[i];
2487                          $$ = line_item_buf;
2488                        }
2489             | ESCAPE   { CLEAR_BUFFER(line_item_buf);
2490                          line_item_buf_ptr = line_item_buf;
2491                          /* For now, ignore escapes */
2492                          $$ = line_item_buf;
2493                        }
2494             | line_item anychar
2495                   { size_t i;
2496                     /* The following also takes care of '@@' */
2497                     if (!strncmp($2, "@@", 3))
2498                       *line_item_buf_ptr++ = '@';
2499                     else
2500                       for (i=0; i < strlen($2); i++)
2501                         *line_item_buf_ptr++ = $2[i];
2502                     $$ = line_item_buf;
2503                   }
2504             | line_item ESCAPE
2505                   { /* For now, ignore escapes */
2506                     $$ = line_item_buf;
2507                   }
2508             ;
2509
2510 anychar     : ANYCHAR        { }
2511             | DELIM        { }
2512             ;
2513
2514 error_subs  : /* empty */
2515             | error_subs error_sect
2516             ;
2517
2518 error_sect  : OPEN DELIM opt_xref anytag opt_value error_subs CLOSE { }
2519
2520 gen_sect    : OPEN DELIM opt_xref anystdtag
2521               { INVALID_TAG($4); }
2522               opt_value opt_sects CLOSE
2523               { }
2524             ;
2525
2526 gen_rec : gen_rec_top
2527         | gen_rec_norm
2528         ;
2529
2530 gen_rec_norm : OPEN DELIM opt_xref anystdtag
2531                { INVALID_TOP_TAG($4) }
2532                opt_value opt_sects CLOSE
2533                { }
2534              ;
2535
2536 gen_rec_top : OPEN DELIM anytoptag
2537               { gedcom_error(_("Missing cross-reference")); YYERROR; }
2538               opt_value opt_sects CLOSE
2539                 { }
2540             ;
2541
2542 opt_sects   : /* empty */     { }
2543             | opt_sects gen_sect { }
2544             ;
2545
2546 anytag      : USERTAG { }
2547             | anystdtag { }
2548             ;
2549
2550 anytoptag   : TAG_FAM
2551             | TAG_INDI
2552             | TAG_OBJE
2553             | TAG_NOTE
2554             | TAG_REPO
2555             | TAG_SOUR
2556             | TAG_SUBN
2557             | TAG_SUBM
2558             ;
2559
2560 anystdtag   : TAG_ABBR
2561             | TAG_ADDR
2562             | TAG_ADR1
2563             | TAG_ADR2   { }
2564             | TAG_ADOP   { }
2565             | TAG_AFN   { }
2566             | TAG_AGE   { }
2567             | TAG_AGNC   { }
2568             | TAG_ALIA   { }
2569             | TAG_ANCE   { }
2570             | TAG_ANCI   { }
2571             | TAG_ANUL   { }
2572             | TAG_ASSO   { }
2573             | TAG_AUTH   { }
2574             | TAG_BAPL   { }
2575             | TAG_BAPM   { }
2576             | TAG_BARM   { }
2577             | TAG_BASM   { }
2578             | TAG_BIRT   { }
2579             | TAG_BLES   { }
2580             | TAG_BLOB   { }
2581             | TAG_BURI   { }
2582             | TAG_CALN   { }
2583             | TAG_CAST   { }
2584             | TAG_CAUS   { }
2585             | TAG_CENS   { }
2586             | TAG_CHAN   { }
2587             | TAG_CHAR   { }
2588             | TAG_CHIL   { }
2589             | TAG_CHR   { }
2590             | TAG_CHRA   { }
2591             | TAG_CITY   { }
2592             | TAG_CONC   { }
2593             | TAG_CONF   { }
2594             | TAG_CONL   { }
2595             | TAG_CONT   { }
2596             | TAG_COPR   { }
2597             | TAG_CORP   { }
2598             | TAG_CREM   { }
2599             | TAG_CTRY   { }
2600             | TAG_DATA   { }
2601             | TAG_DATE   { }
2602             | TAG_DEAT   { }
2603             | TAG_DESC   { }
2604             | TAG_DESI   { }
2605             | TAG_DEST   { }
2606             | TAG_DIV   { }
2607             | TAG_DIVF   { }
2608             | TAG_DSCR   { }
2609             | TAG_EDUC   { }
2610             | TAG_EMIG   { }
2611             | TAG_ENDL   { }
2612             | TAG_ENGA   { }
2613             | TAG_EVEN   { }
2614             | TAG_FAM    { }
2615             | TAG_FAMC   { }
2616             | TAG_FAMS   { }
2617             | TAG_FCOM   { }
2618             | TAG_FILE   { }
2619             | TAG_FORM   { }
2620             | TAG_GEDC   { }
2621             | TAG_GIVN   { }
2622             | TAG_GRAD   { }
2623             | TAG_HEAD   { }
2624             | TAG_HUSB   { }
2625             | TAG_IDNO   { }
2626             | TAG_IMMI   { }
2627             | TAG_INDI   { }
2628             | TAG_LANG   { }
2629             | TAG_LEGA   { }
2630             | TAG_MARB   { }
2631             | TAG_MARC   { }
2632             | TAG_MARL   { }
2633             | TAG_MARR   { }
2634             | TAG_MARS   { }
2635             | TAG_MEDI   { }
2636             | TAG_NAME   { }
2637             | TAG_NATI   { }
2638             | TAG_NCHI   { }
2639             | TAG_NICK   { }
2640             | TAG_NMR   { }
2641             | TAG_NOTE   { }
2642             | TAG_NPFX   { }
2643             | TAG_NSFX   { }
2644             | TAG_OBJE   { }
2645             | TAG_OCCU   { }
2646             | TAG_ORDI   { }
2647             | TAG_ORDN   { }
2648             | TAG_PAGE   { }
2649             | TAG_PEDI   { }
2650             | TAG_PHON   { }
2651             | TAG_PLAC   { }
2652             | TAG_POST   { }
2653             | TAG_PROB   { }
2654             | TAG_PROP   { }
2655             | TAG_PUBL   { }
2656             | TAG_QUAY   { }
2657             | TAG_REFN   { }
2658             | TAG_RELA   { }
2659             | TAG_RELI   { }
2660             | TAG_REPO   { }
2661             | TAG_RESI   { }
2662             | TAG_RESN   { }
2663             | TAG_RETI   { }
2664             | TAG_RFN   { }
2665             | TAG_RIN   { }
2666             | TAG_ROLE   { }
2667             | TAG_SEX   { }
2668             | TAG_SLGC   { }
2669             | TAG_SLGS   { }
2670             | TAG_SOUR   { }
2671             | TAG_SPFX   { }
2672             | TAG_SSN   { }
2673             | TAG_STAE   { }
2674             | TAG_STAT   { }
2675             | TAG_SUBM   { }
2676             | TAG_SUBN   { }
2677             | TAG_SURN   { }
2678             | TAG_TEMP   { }
2679             | TAG_TEXT   { }
2680             | TAG_TIME   { }
2681             | TAG_TITL   { }
2682             | TAG_TRLR   { }
2683             | TAG_TYPE   { }
2684             | TAG_VERS   { }
2685             | TAG_WIFE   { }
2686             | TAG_WILL   { }
2687
2688 %%
2689
2690 /* Functions that handle the counting of subtags */
2691
2692 int* count_arrays[MAXGEDCLEVEL+1];
2693 char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLEN+1];
2694 Gedcom_ctxt ctxt_stack[MAXGEDCLEVEL+1];
2695
2696 void push_countarray()
2697 {
2698   int *count = NULL;
2699   if (count_level > MAXGEDCLEVEL) {
2700     gedcom_error(_("Internal error: count array overflow"));
2701     exit(1);
2702   }
2703   else {
2704     count = (int *)calloc(YYNTOKENS, sizeof(int));
2705     if (count == NULL) {
2706       gedcom_error(_("Internal error: count array calloc error"));
2707       exit(1);
2708     }
2709     else {
2710       count_arrays[count_level] = count;
2711     }
2712   }
2713 }
2714
2715 void set_parenttag(char* tag)
2716 {
2717   strncpy(tag_stack[count_level], tag, MAXSTDTAGLEN+1);
2718 }
2719
2720 void set_parentctxt(Gedcom_ctxt ctxt)
2721 {
2722   ctxt_stack[count_level] = ctxt;
2723 }
2724
2725 char* get_parenttag()
2726 {
2727   return tag_stack[count_level];
2728 }
2729
2730 Gedcom_ctxt get_parentctxt()
2731 {
2732   return ctxt_stack[count_level];
2733 }
2734
2735 int count_tag(int tag)
2736 {
2737   int *count = count_arrays[count_level];
2738   return ++count[tag - GEDCOMTAGOFFSET];
2739 }
2740
2741 int check_occurrence(int tag)
2742 {
2743   int *count = count_arrays[count_level];
2744   return (count[tag - GEDCOMTAGOFFSET] > 0);
2745 }
2746
2747 void pop_countarray()
2748 {
2749   int *count;
2750   if (count_level < 0) {
2751     gedcom_error(_("Internal error: count array underflow"));
2752     exit(1);
2753   }
2754   else {
2755     count = count_arrays[count_level];
2756     free(count);
2757     count_arrays[count_level] = NULL;
2758   }
2759 }
2760
2761 /* Enabling debug mode */
2762 /* level 0: no debugging */
2763 /* level 1: only internal */
2764 /* level 2: also bison */
2765 FILE* trace_output;
2766
2767 void gedcom_set_debug_level(int level, FILE* f)
2768 {
2769   if (f != NULL)
2770     trace_output = f;
2771   else
2772     trace_output = stderr;
2773   if (level > 0) {
2774     gedcom_high_level_debug = 1;
2775   }
2776   if (level > 1) {
2777 #if YYDEBUG != 0
2778     gedcom_debug = 1;
2779 #endif
2780   }
2781 }
2782
2783 int gedcom_debug_print(char* s, ...)
2784 {
2785   int res = 0;
2786   if (gedcom_high_level_debug) {
2787     va_list ap;
2788     va_start(ap, s);
2789     res = vfprintf(trace_output, s, ap);
2790     va_end(ap);
2791     fprintf(trace_output, "\n");
2792   }
2793   return(res);
2794 }
2795
2796 /* Setting the error mechanism */
2797 void gedcom_set_error_handling(Gedcom_err_mech mechanism)
2798 {
2799   error_mechanism = mechanism;
2800 }
2801
2802 /* Compatibility handling */
2803
2804 void gedcom_set_compat_handling(int enable_compat)
2805 {
2806   compat_enabled = enable_compat;
2807 }
2808
2809 void set_compatibility(char* program)
2810 {
2811   if (compat_enabled) {
2812     if (! strncmp(program, "ftree", 6)) {
2813       gedcom_warning(_("Enabling compatibility with 'ftree'"));
2814       compatibility = C_FTREE;
2815     }
2816     else {
2817       compatibility = 0;
2818     }
2819   }
2820 }
2821
2822 int compat_mode(int compat_flags)
2823 {
2824   return (compat_flags & compatibility);
2825 }
2826