Added gettext calls.
[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                 { START(HUSB, NULL) } no_std_subs { CHECK0 } CLOSE
858                        { }
859               ;
860
861 /* FAM.WIFE */
862 fam_wife_sect : OPEN DELIM TAG_WIFE mand_pointer 
863                 { START(WIFE, NULL) } no_std_subs { CHECK0 } CLOSE
864                        { }
865               ;
866
867 /* FAM.CHIL */
868 fam_chil_sect : OPEN DELIM TAG_CHIL mand_pointer
869                 { START(CHIL, NULL) } no_std_subs { CHECK0 } CLOSE
870                        { }
871               ;
872
873 /* FAM.NCHI */
874 fam_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item    
875                 { START(NCHI, NULL) } no_std_subs { CHECK0 } CLOSE
876                        { }
877               ;
878
879 /* FAM.SUBM */
880 fam_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
881                 { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE
882                        { }
883               ;
884
885 /*********************************************************************/
886 /**** Individual record                                           ****/
887 /*********************************************************************/
888 indiv_rec   : OPEN DELIM POINTER DELIM TAG_INDI
889               { $<ctxt>$ = start_record(REC_INDI, $1, $3, $5);
890                 START(INDI, $<ctxt>$) }
891               indi_subs
892               { CHECK0 }
893               CLOSE
894               { end_record(REC_INDI, $<ctxt>6); }
895             ;
896
897 indi_subs   : /* empty */
898             | indi_subs indi_sub
899             ;
900
901 indi_sub    : indi_resn_sect  { OCCUR2(RESN, 0, 1) }
902             | pers_name_struc_sub  /* 0:M */
903             | indi_sex_sect  { OCCUR2(SEX, 0, 1) }
904             | indiv_even_struc_sub  /* 0:M */
905             | indiv_attr_struc_sub  /* 0:M */
906             | lds_indiv_ord_sub  /* 0:M */
907             | chi_fam_link_sub  /* 0:M */
908             | spou_fam_link_sub  /* 0:M */
909             | indi_subm_sect  /* 0:M */
910             | assoc_struc_sub  /* 0:M */
911             | indi_alia_sect  /* 0:M */
912             | indi_anci_sect  /* 0:M */
913             | indi_desi_sect  /* 0:M */
914             | source_cit_sub  /* 0:M */
915             | multim_link_sub  /* 0:M */
916             | note_struc_sub  /* 0:M */
917             | indi_rfn_sect  { OCCUR2(RFN, 0, 1) }
918             | indi_afn_sect  /* 0:M */
919             | ident_struc_sub  /* 0:1 */
920             | change_date_sub  /* 0:1 */
921             | ftree_addr_sect { if (!compat_mode(C_FTREE))
922                                   INVALID_TAG("ADDR");
923                               }
924             | no_std_sub
925             ;
926
927 /* INDI.RESN */
928 indi_resn_sect : OPEN DELIM TAG_RESN mand_line_item     
929                  { START(RESN, NULL) } no_std_subs { CHECK0 } CLOSE { }
930                ;
931
932 /* INDI.SEX */
933 indi_sex_sect  : OPEN DELIM TAG_SEX mand_line_item     
934                  { START(SEX, NULL) } no_std_subs { CHECK0 } CLOSE { }
935                ;
936
937 /* INDI.SUBM */
938 indi_subm_sect : OPEN DELIM TAG_SUBM mand_pointer 
939                  { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
940                ;
941
942 /* INDI.ALIA */
943 indi_alia_sect : OPEN DELIM TAG_ALIA mand_pointer
944                  { START(ALIA, NULL) } no_std_subs { CHECK0 } CLOSE { }
945                ;
946
947 /* INDI.ANCI */
948 indi_anci_sect : OPEN DELIM TAG_ANCI mand_pointer
949                  { START(ANCI, NULL) } no_std_subs { CHECK0 } CLOSE { }
950                ;
951
952 /* INDI.DESI */
953 indi_desi_sect : OPEN DELIM TAG_DESI mand_pointer
954                  { START(DESI, NULL) } no_std_subs { CHECK0 } CLOSE { }
955                ;
956
957 /* INDI.RFN */
958 indi_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item     
959                  { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
960                ;
961
962 /* INDI.AFN */
963 indi_afn_sect  : OPEN DELIM TAG_AFN mand_line_item      
964                  { START(AFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
965                ;
966
967 /* INDI.ADDR (Only for 'ftree' compatibility) */
968 ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
969                   { START(ADDR, NULL) } no_std_subs { CHECK0 } CLOSE { }
970
971 /*********************************************************************/
972 /**** Multimedia record                                           ****/
973 /*********************************************************************/
974 multim_rec  : OPEN DELIM POINTER DELIM TAG_OBJE
975               { $<ctxt>$ = start_record(REC_OBJE, $1, $3, $5);
976                 START(OBJE, $<ctxt>$) }
977               obje_subs
978               { CHECK2(FORM, BLOB) }
979               CLOSE
980               { end_record(REC_OBJE, $<ctxt>6); }
981             ;
982
983 obje_subs   : /* empty */
984             | obje_subs obje_sub
985             ;
986
987 obje_sub    : obje_form_sect  { OCCUR2(FORM, 1, 1) }
988             | obje_titl_sect  { OCCUR2(TITL, 0, 1) }
989             | note_struc_sub  /* 0:M */
990             | obje_blob_sect  { OCCUR2(BLOB, 1, 1) }
991             | obje_obje_sect  { OCCUR2(OBJE, 0, 1) }
992             | ident_struc_sub  /* 0:1 */
993             | change_date_sub  /* 0:1 */
994             | no_std_sub
995             ;
996
997 /* OBJE.FORM */
998 obje_form_sect : OPEN DELIM TAG_FORM mand_line_item       
999                  { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1000                ;
1001
1002 /* OBJE.TITL */
1003 obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item       
1004                  { START(TITL, NULL) } no_std_subs { CHECK0 } CLOSE { }
1005                ;
1006
1007 /* OBJE.BLOB */
1008 obje_blob_sect : OPEN DELIM TAG_BLOB
1009                  { START(BLOB, NULL) }
1010                  obje_blob_subs
1011                  { CHECK1(CONT) }
1012                  CLOSE { }
1013                ;
1014
1015 obje_blob_subs : /* empty */
1016                | obje_blob_subs obje_blob_sub
1017                ;
1018
1019 obje_blob_sub  : obje_blob_cont_sect  { OCCUR1(CONT, 1) }
1020                | no_std_sub
1021                ;
1022
1023 obje_blob_cont_sect : OPEN DELIM TAG_CONT mand_line_item        
1024                       { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1025                     ;
1026
1027 /* OBJE.OBJE */
1028 obje_obje_sect : OPEN DELIM TAG_OBJE mand_pointer 
1029                  { START(OBJE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1030                ;
1031
1032 /*********************************************************************/
1033 /**** Note record                                                 ****/
1034 /*********************************************************************/
1035 note_rec    : OPEN DELIM POINTER DELIM TAG_NOTE note_line_item
1036               { $<ctxt>$ = start_record(REC_NOTE, $1, $3, $5);
1037                 START(NOTE, $<ctxt>$) }
1038               note_subs
1039               { CHECK0 }
1040               CLOSE
1041               { end_record(REC_NOTE, $<ctxt>6); }
1042             ;
1043
1044 note_line_item : /* empty */
1045                    { if (!compat_mode(C_FTREE)) {
1046                        gedcom_error(_("Missing value")); YYERROR;
1047                      }
1048                    }
1049                | DELIM line_item
1050                    { $$ = $2; }
1051                ;
1052
1053 note_subs   : /* empty */
1054             | note_subs note_sub
1055             ;
1056
1057 note_sub    : continuation_sub  /* 0:M */
1058             | source_cit_sub  /* 0:M */
1059             | ident_struc_sub  /* 0:1 */
1060             | change_date_sub  /* 0:1 */
1061             | no_std_sub
1062             ;
1063
1064 /*********************************************************************/
1065 /**** Repository record                                           ****/
1066 /*********************************************************************/
1067 repos_rec   : OPEN DELIM POINTER DELIM TAG_REPO
1068               { $<ctxt>$ = start_record(REC_REPO, $1, $3, $5);
1069                 START(REPO, $<ctxt>$) }
1070               repo_subs
1071               { CHECK0 }
1072               CLOSE
1073               { end_record(REC_REPO, $<ctxt>6); }
1074             ;
1075
1076 repo_subs   : /* empty */
1077             | repo_subs repo_sub
1078             ;
1079
1080 repo_sub    : repo_name_sect  { OCCUR2(NAME, 0, 1) }
1081             | addr_struc_sub  /* 0:1 */
1082             | note_struc_sub  /* 0:M */
1083             | ident_struc_sub  /* 0:1 */
1084             | change_date_sub  /* 0:1 */
1085             | no_std_sub
1086             ;
1087
1088 /* REPO.NAME */
1089 repo_name_sect : OPEN DELIM TAG_NAME mand_line_item         
1090                  { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE {}
1091                ;
1092
1093 /*********************************************************************/
1094 /**** Source record                                               ****/
1095 /*********************************************************************/
1096 source_rec  : OPEN DELIM POINTER DELIM TAG_SOUR
1097               { $<ctxt>$ = start_record(REC_SOUR, $1, $3, $5);
1098                 START(SOUR, $<ctxt>$) }
1099               sour_subs
1100               { CHECK0 }
1101               CLOSE
1102               { end_record(REC_SOUR, $<ctxt>6); }
1103             ;
1104
1105 sour_subs   : /* empty */
1106             | sour_subs sour_sub
1107             ;
1108
1109 sour_sub    : sour_data_sect  { OCCUR2(DATA, 0, 1) }
1110             | sour_auth_sect  { OCCUR2(AUTH, 0, 1) }
1111             | sour_titl_sect  { OCCUR2(TITL, 0, 1) }
1112             | sour_abbr_sect  { OCCUR2(ABBR, 0, 1) }
1113             | sour_publ_sect  { OCCUR2(PUBL, 0, 1) }
1114             | sour_text_sect  { OCCUR2(TEXT, 0, 1) }
1115             | source_repos_cit_sub  /* 0:1 */
1116             | multim_link_sub  /* 0:M */
1117             | note_struc_sub  /* 0:M */
1118             | ident_struc_sub  /* 0:1 */
1119             | change_date_sub  /* 0:1 */
1120             | no_std_sub
1121             ;
1122
1123 /* SOUR.DATA */
1124 sour_data_sect : OPEN DELIM TAG_DATA
1125                  { START(DATA, NULL) }
1126                  sour_data_subs
1127                  { CHECK0 }
1128                  CLOSE { }
1129                ;
1130
1131 sour_data_subs : /* empty */
1132                | sour_data_subs sour_data_sub
1133                ;
1134
1135 sour_data_sub  : sour_data_even_sect  /* 0:M */
1136                | sour_data_agnc_sect  { OCCUR2(AGNC, 0, 1) }
1137                | note_struc_sub  /* 0:M */
1138                | no_std_sub
1139                ;
1140
1141 sour_data_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
1142                       { START(EVEN, NULL) }
1143                       sour_data_even_subs
1144                       { CHECK0 }
1145                       CLOSE { }
1146                     ;
1147
1148 sour_data_even_subs : /* empty */
1149                     | sour_data_even_subs sour_data_even_sub
1150                     ;
1151
1152 sour_data_even_sub  : sour_data_even_date_sect { OCCUR2(DATE, 0, 1) }
1153                     | sour_data_even_plac_sect { OCCUR2(PLAC, 0, 1) }
1154                     | no_std_sub
1155                     ;
1156
1157 sour_data_even_date_sect : OPEN DELIM TAG_DATE mand_line_item          
1158                            { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1159                          ;
1160
1161 sour_data_even_plac_sect : OPEN DELIM TAG_PLAC mand_line_item          
1162                            { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1163                          ;
1164
1165 sour_data_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item          
1166                       { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1167                     ;
1168
1169 /* SOUR.AUTH */
1170 sour_auth_sect : OPEN DELIM TAG_AUTH mand_line_item
1171                  { START(AUTH, NULL) }
1172                  sour_auth_subs
1173                  { CHECK0 }
1174                  CLOSE { }
1175                ;
1176
1177 sour_auth_subs : /* empty */
1178                | sour_auth_subs sour_auth_sub
1179                ;
1180
1181 sour_auth_sub  : continuation_sub  /* 0:M */
1182                | no_std_sub
1183                ;
1184
1185 /* SOUR.TITL */
1186 sour_titl_sect : OPEN DELIM TAG_TITL mand_line_item  
1187                  { START(TITL, NULL) }
1188                  sour_titl_subs 
1189                  { CHECK0 }
1190                  CLOSE { }
1191                ;
1192
1193 sour_titl_subs : /* empty */
1194                | sour_titl_subs sour_titl_sub
1195                ;
1196
1197 sour_titl_sub  : continuation_sub  /* 0:M */
1198                | no_std_sub
1199                ;
1200
1201 /* SOUR.ABBR */
1202 sour_abbr_sect : OPEN DELIM TAG_ABBR mand_line_item           
1203                  { START(ABBR, NULL) } no_std_subs { CHECK0 } CLOSE { }
1204                ;
1205
1206 /* SOUR.PUBL */
1207 sour_publ_sect : OPEN DELIM TAG_PUBL mand_line_item  
1208                  { START(PUBL, NULL) }
1209                  sour_publ_subs  
1210                  { CHECK0 }
1211                  CLOSE { }
1212                ;
1213
1214 sour_publ_subs : /* empty */
1215                | sour_publ_subs sour_publ_sub
1216                ;
1217
1218 sour_publ_sub  : continuation_sub  /* 0:M */
1219                | no_std_sub
1220                ;
1221
1222 /* SOUR.TEXT */
1223 sour_text_sect : OPEN DELIM TAG_TEXT mand_line_item   
1224                  { START(TEXT, NULL) }
1225                  sour_text_subs  
1226                  { CHECK0 }
1227                  CLOSE { }
1228                ;
1229
1230 sour_text_subs : /* empty */
1231                | sour_text_subs sour_text_sub
1232                ;
1233
1234 sour_text_sub  : continuation_sub  /* 0:M */
1235                | no_std_sub
1236                ;
1237
1238 /*********************************************************************/
1239 /**** Submission record                                           ****/
1240 /*********************************************************************/
1241 submis_rec  : OPEN DELIM POINTER DELIM TAG_SUBN    
1242               { $<ctxt>$ = start_record(REC_SUBN, $1, $3, $5);
1243                 START(SUBN, $<ctxt>$) }
1244               subn_subs
1245               { CHECK0 }
1246               CLOSE
1247               { end_record(REC_SUBN, $<ctxt>6); }
1248             ;
1249
1250 subn_subs   : /* empty */
1251             | subn_subs subn_sub
1252             ;
1253
1254 subn_sub    : subn_subm_sect  { OCCUR2(SUBM, 0, 1) }
1255             | subn_famf_sect  { OCCUR2(FAMF, 0, 1) }
1256             | subn_temp_sect  { OCCUR2(TEMP, 0, 1) }
1257             | subn_ance_sect  { OCCUR2(ANCE, 0, 1) }
1258             | subn_desc_sect  { OCCUR2(DESC, 0, 1) }
1259             | subn_ordi_sect  { OCCUR2(ORDI, 0, 1) }
1260             | subn_rin_sect  { OCCUR2(RIN, 0, 1) }
1261             | no_std_sub
1262             ;
1263
1264 /* SUBN.SUBM */
1265 subn_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
1266                  { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1267                ;
1268
1269 /* SUBN.FAMF */
1270 subn_famf_sect : OPEN DELIM TAG_FAMF mand_line_item            
1271                  { START(FAMF, NULL) } no_std_subs { CHECK0 } CLOSE { }
1272                ;
1273
1274 /* SUBN.TEMP */
1275 subn_temp_sect : OPEN DELIM TAG_TEMP mand_line_item            
1276                  { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1277                ;
1278
1279 /* SUBN.ANCE */
1280 subn_ance_sect : OPEN DELIM TAG_ANCE mand_line_item            
1281                  { START(ANCE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1282                ;
1283
1284 /* SUBN.DESC */
1285 subn_desc_sect : OPEN DELIM TAG_DESC mand_line_item            
1286                  { START(DESC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1287                ;
1288
1289 /* SUBN.ORDI */
1290 subn_ordi_sect : OPEN DELIM TAG_ORDI mand_line_item            
1291                  { START(ORDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1292                ;
1293
1294 /* SUBN.RIN */
1295 subn_rin_sect  : OPEN DELIM TAG_RIN mand_line_item            
1296                  { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1297                ;
1298
1299 /*********************************************************************/
1300 /**** Submitter record                                            ****/
1301 /*********************************************************************/
1302 submit_rec : OPEN DELIM POINTER DELIM TAG_SUBM    
1303              { $<ctxt>$ = start_record(REC_SUBM, $1, $3, $5);
1304                 START(SUBM, $<ctxt>$) }
1305              subm_subs
1306              { CHECK1(NAME) }
1307              CLOSE
1308              { end_record(REC_SUBM, $<ctxt>6); }
1309            ;
1310
1311 subm_subs  : /* empty */
1312            | subm_subs subm_sub
1313            ;
1314
1315 subm_sub   : subm_name_sect  { OCCUR2(NAME, 0, 1) }
1316            | addr_struc_sub  /* 0:1 */
1317            | multim_link_sub  /* 0:M */
1318            | subm_lang_sect  { OCCUR2(LANG, 0, 3) }
1319            | subm_rfn_sect  { OCCUR2(RFN, 0, 1) }
1320            | subm_rin_sect  { OCCUR2(RIN, 0, 1) }
1321            | change_date_sub  /* 0:1 */
1322            | no_std_sub
1323            ;
1324
1325 /* SUBM.NAME */
1326 subm_name_sect : OPEN DELIM TAG_NAME mand_line_item             
1327                  { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1328                ;
1329
1330 /* SUBM.LANG */
1331 subm_lang_sect : OPEN DELIM TAG_LANG mand_line_item             
1332                  { START(LANG, NULL) } no_std_subs { CHECK0 } CLOSE { }
1333                ;
1334
1335 /* SUBM.RFN */
1336 subm_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item             
1337                  { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1338                ;
1339
1340 /* SUBM.RIN */
1341 subm_rin_sect  : OPEN DELIM TAG_RIN mand_line_item             
1342                  { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1343                ;
1344
1345 /*********************************************************************/
1346 /**** Substructures                                               ****/
1347 /*********************************************************************/
1348
1349 /* ADDRESS STRUCTURE */
1350 addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) }
1351                | phon_sect { OCCUR2(PHON, 0, 3) }
1352                ;
1353
1354 addr_sect   : OPEN DELIM TAG_ADDR mand_line_item 
1355               { START(ADDR, NULL) }
1356               addr_subs
1357               { CHECK0 }
1358               CLOSE { }
1359             ;
1360
1361 addr_subs   : /* empty */
1362             | addr_subs addr_sub
1363             ;
1364
1365 addr_sub    : addr_cont_sect  /* 0:M */
1366             | addr_adr1_sect  { OCCUR2(ADR1, 0, 1) }
1367             | addr_adr2_sect  { OCCUR2(ADR2, 0, 1) }
1368             | addr_city_sect  { OCCUR2(CITY, 0, 1) }
1369             | addr_stae_sect  { OCCUR2(STAE, 0, 1) }
1370             | addr_post_sect  { OCCUR2(POST, 0, 1) }
1371             | addr_ctry_sect  { OCCUR2(CTRY, 0, 1) }
1372             | no_std_sub
1373             ;
1374
1375 addr_cont_sect : OPEN DELIM TAG_CONT mand_line_item              
1376                  { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1377                ;
1378 addr_adr1_sect : OPEN DELIM TAG_ADR1 mand_line_item              
1379                  { START(ADR1, NULL) } no_std_subs { CHECK0 } CLOSE { }
1380                ;
1381 addr_adr2_sect : OPEN DELIM TAG_ADR2 mand_line_item              
1382                  { START(ADR2, NULL) } no_std_subs { CHECK0 } CLOSE { }
1383                ;
1384 addr_city_sect : OPEN DELIM TAG_CITY mand_line_item              
1385                  { START(CITY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1386                ;
1387 addr_stae_sect : OPEN DELIM TAG_STAE mand_line_item              
1388                  { START(STAE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1389                ;
1390 addr_post_sect : OPEN DELIM TAG_POST mand_line_item              
1391                  { START(POST, NULL) } no_std_subs { CHECK0 } CLOSE { }
1392                ;
1393 addr_ctry_sect : OPEN DELIM TAG_CTRY mand_line_item              
1394                  { START(CTRY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1395                ;
1396
1397 phon_sect   : OPEN DELIM TAG_PHON mand_line_item              
1398               { START(PHON, NULL) } no_std_subs { CHECK0 } CLOSE { }
1399             ;
1400
1401 /* ASSOCIATION STRUCTURE */
1402 assoc_struc_sub : asso_sect /* 0:M */
1403                 ;
1404
1405 asso_sect : OPEN DELIM TAG_ASSO mand_pointer
1406             { START(ASSO, NULL) }
1407             asso_subs
1408             { CHECK2(TYPE,RELA) }
1409             CLOSE { }
1410           ;
1411
1412 asso_subs : /* empty */
1413           | asso_type_sect  { OCCUR2(TYPE, 1, 1) }
1414           | asso_rela_sect  { OCCUR2(RELA, 1, 1) }
1415           | note_struc_sub
1416           | source_cit_sub
1417           | no_std_sub
1418           ;
1419
1420 asso_type_sect : OPEN DELIM TAG_TYPE mand_line_item               
1421                  { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1422                ;
1423
1424 asso_rela_sect : OPEN DELIM TAG_RELA mand_line_item               
1425                  { START(RELA, NULL) } no_std_subs { CHECK0 } CLOSE { }
1426                ;
1427
1428 /* CHANGE DATE */
1429 change_date_sub : change_date_chan_sect  { OCCUR2(CHAN, 0, 1) }
1430                 ;
1431
1432 change_date_chan_sect : OPEN DELIM TAG_CHAN
1433                         { START(CHAN, NULL) }
1434                         change_date_chan_subs
1435                         { CHECK1(DATE) }
1436                         CLOSE { }
1437                       ;
1438
1439 change_date_chan_subs : /* empty */
1440                       | change_date_chan_subs change_date_chan_sub
1441                       ;
1442
1443 change_date_chan_sub  : change_date_date_sect  { OCCUR2(DATE, 1, 1) }
1444                       | note_struc_sub
1445                       | no_std_sub
1446                       ;
1447
1448 change_date_date_sect : OPEN DELIM TAG_DATE mand_line_item 
1449                         { START(DATE, NULL) }
1450                         change_date_date_subs
1451                         { CHECK0 }
1452                         CLOSE { }
1453                       ;
1454
1455 change_date_date_subs : /* empty */
1456                       | change_date_date_subs change_date_date_sub
1457                       ;
1458
1459 change_date_date_sub : change_date_date_time_sect  { OCCUR2(TIME, 0, 1) }
1460                      | no_std_sub
1461                      ;
1462
1463 change_date_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
1464                              { START(TIME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1465                            ;
1466
1467 /* CHILD TO FAMILY LINK */
1468 chi_fam_link_sub : famc_sect  /* 0:M */
1469                  ;
1470
1471 famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1472             { START(FAMC, NULL) }
1473             famc_subs
1474             { CHECK0 }
1475             CLOSE { }
1476           ;
1477
1478 famc_subs : /* empty */
1479           | famc_subs famc_sub
1480           ;
1481
1482 famc_sub  : famc_pedi_sect  /* 0:M */
1483           | note_struc_sub
1484           | no_std_sub
1485           ;
1486
1487 famc_pedi_sect : OPEN DELIM TAG_PEDI mand_line_item 
1488                  { START(PEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1489                ;
1490
1491 /* CONTINUATION SUBSECTIONS */
1492 continuation_sub : cont_sect  /* 0:M */
1493                  | conc_sect  /* 0:M */
1494                  ;
1495
1496 cont_sect : OPEN DELIM TAG_CONT mand_line_item 
1497             { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1498           ;
1499
1500 conc_sect : OPEN DELIM TAG_CONC mand_line_item 
1501             { START(CONC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1502           ; 
1503
1504 /* EVENT DETAIL */
1505 event_detail_sub : event_detail_type_sect  { OCCUR2(TYPE, 0, 1) }
1506                  | event_detail_date_sect  { OCCUR2(DATE, 0, 1) }
1507                  | place_struc_sub
1508                  | addr_struc_sub
1509                  | event_detail_age_sect  { OCCUR2(AGE, 0, 1) }
1510                  | event_detail_agnc_sect  { OCCUR2(AGNC, 0, 1) }
1511                  | event_detail_caus_sect  { OCCUR2(CAUS, 0, 1) }
1512                  | source_cit_sub
1513                  | multim_link_sub
1514                  | note_struc_sub
1515                  ;
1516
1517 event_detail_type_sect : OPEN DELIM TAG_TYPE mand_line_item 
1518                          { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1519                        ;
1520 event_detail_date_sect : OPEN DELIM TAG_DATE mand_line_item 
1521                          { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1522                        ;
1523 event_detail_age_sect  : OPEN DELIM TAG_AGE mand_line_item 
1524                          { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1525                        ;
1526 event_detail_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item 
1527                          { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1528                        ;
1529 event_detail_caus_sect : OPEN DELIM TAG_CAUS mand_line_item 
1530                          { START(CAUS, NULL) } no_std_subs { CHECK0 } CLOSE { }
1531                        ;
1532
1533 /* FAMILY EVENT STRUCTURE */
1534 fam_event_struc_sub : fam_event_sect
1535                     | fam_gen_even_sect  /* 0:M */
1536                     ;
1537
1538 fam_event_sect : OPEN DELIM fam_event_tag opt_value fam_event_subs
1539                  { CHECK0 }
1540                  CLOSE { }
1541                ;
1542
1543 fam_event_tag : TAG_ANUL { START(ANUL, NULL) }
1544               | TAG_CENS { START(CENS, NULL) }
1545               | TAG_DIV { START(DIV, NULL) }
1546               | TAG_DIVF { START(DIVF, NULL) }
1547               | TAG_ENGA { START(ENGA, NULL) }
1548               | TAG_MARR { START(MARR, NULL) }
1549               | TAG_MARB { START(MARB, NULL) }
1550               | TAG_MARC { START(MARC, NULL) }
1551               | TAG_MARL { START(MARL, NULL) }
1552               | TAG_MARS { START(MARS, NULL) }
1553               ;
1554
1555 fam_event_subs : /* empty */
1556                | fam_event_subs fam_event_sub
1557                ;
1558
1559 fam_event_sub : event_detail_sub
1560               | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
1561               | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
1562               | no_std_sub
1563               ;
1564
1565 fam_even_husb_sect : OPEN DELIM TAG_HUSB
1566                      { START(HUSB, NULL) }
1567                      fam_even_husb_subs
1568                      { CHECK1(AGE) }
1569                      CLOSE { }
1570                    ;
1571
1572 fam_even_husb_subs : /* empty */
1573                    | fam_even_husb_subs fam_even_husb_sub
1574                    ;
1575
1576 fam_even_husb_sub : fam_even_husb_age_sect  { OCCUR2(AGE, 1, 1) }
1577                   | no_std_sub
1578                   ;
1579
1580 fam_even_husb_age_sect : OPEN DELIM TAG_AGE mand_line_item  
1581                          { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1582                        ;
1583
1584 fam_even_wife_sect : OPEN DELIM TAG_WIFE
1585                      { START(HUSB, NULL) }
1586                      fam_even_husb_subs
1587                      { CHECK1(AGE) }
1588                      CLOSE { }
1589                    ;
1590
1591 fam_gen_even_sect : OPEN DELIM TAG_EVEN
1592                     { START(EVEN, NULL) }
1593                     fam_gen_even_subs
1594                     { CHECK0 }
1595                     CLOSE { }
1596                   ;
1597
1598 fam_gen_even_subs : /* empty */
1599                   | fam_gen_even_subs fam_gen_even_sub
1600                   ;
1601
1602 fam_gen_even_sub : event_detail_sub
1603                  | fam_even_husb_sect  { OCCUR2(HUSB, 0, 1) }
1604                  | fam_even_wife_sect  { OCCUR2(WIFE, 0, 1) }
1605                  | no_std_sub
1606                  ;
1607
1608 /* IDENTIFICATION STRUCTURE */
1609 ident_struc_sub : ident_refn_sect  /* 0:M */
1610                 | ident_rin_sect  { OCCUR2(RIN, 0, 1) }
1611                 ;
1612
1613 ident_refn_sect : OPEN DELIM TAG_REFN mand_line_item 
1614                   { START(REFN, NULL) }
1615                   ident_refn_subs
1616                   { CHECK0 }
1617                   CLOSE { }
1618                 ;
1619
1620 ident_refn_subs : /* empty */
1621                 | ident_refn_subs ident_refn_sub
1622                 ;
1623
1624 ident_refn_sub  : ident_refn_type_sect  { OCCUR2(TYPE, 0, 1) }
1625                 | no_std_sub
1626                 ;
1627
1628 ident_refn_type_sect : OPEN DELIM TAG_TYPE mand_line_item   
1629                        { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1630                      ;
1631
1632 ident_rin_sect  : OPEN DELIM TAG_RIN mand_line_item   
1633                   { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1634                 ;
1635
1636 /* INDIVIDUAL ATTRIBUTE STRUCTURE */
1637 indiv_attr_struc_sub : indiv_cast_sect  /* 0:M */
1638                      | indiv_dscr_sect  /* 0:M */
1639                      | indiv_educ_sect  /* 0:M */
1640                      | indiv_idno_sect  /* 0:M */
1641                      | indiv_nati_sect  /* 0:M */
1642                      | indiv_nchi_sect  /* 0:M */
1643                      | indiv_nmr_sect  /* 0:M */
1644                      | indiv_occu_sect  /* 0:M */
1645                      | indiv_prop_sect  /* 0:M */
1646                      | indiv_reli_sect  /* 0:M */
1647                      | indiv_resi_sect  /* 0:M */
1648                      | indiv_ssn_sect  /* 0:M */
1649                      | indiv_titl_sect  /* 0:M */
1650                      ;
1651
1652 indiv_cast_sect : OPEN DELIM TAG_CAST mand_line_item 
1653                   { START(CAST, NULL) }
1654                   indiv_attr_event_subs
1655                   { CHECK0 }
1656                   CLOSE { }
1657                 ;
1658 indiv_dscr_sect : OPEN DELIM TAG_DSCR mand_line_item 
1659                   { START(DSCR, NULL) }
1660                   indiv_attr_event_subs
1661                   { CHECK0 }
1662                   CLOSE { }
1663                 ;
1664 indiv_educ_sect : OPEN DELIM TAG_EDUC mand_line_item  
1665                   { START(EDUC, NULL) }
1666                   indiv_attr_event_subs 
1667                   { CHECK0 }
1668                   CLOSE { }
1669                 ;
1670 indiv_idno_sect : OPEN DELIM TAG_IDNO mand_line_item 
1671                   { START(IDNO, NULL) }
1672                   indiv_attr_event_subs 
1673                   { CHECK0 }
1674                   CLOSE { }
1675                 ;
1676 indiv_nati_sect : OPEN DELIM TAG_NATI mand_line_item 
1677                   { START(NATI, NULL) }
1678                   indiv_attr_event_subs 
1679                   { CHECK0 }
1680                   CLOSE { }
1681                 ;
1682 indiv_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item 
1683                   { START(NCHI, NULL) }
1684                   indiv_attr_event_subs 
1685                   { CHECK0 }
1686                   CLOSE { }
1687                 ;
1688 indiv_nmr_sect  : OPEN DELIM TAG_NMR mand_line_item 
1689                   { START(NMR, NULL) }
1690                   indiv_attr_event_subs 
1691                   { CHECK0 }
1692                   CLOSE { }
1693                 ;
1694 indiv_occu_sect : OPEN DELIM TAG_OCCU mand_line_item 
1695                   { START(OCCU, NULL) }
1696                   indiv_attr_event_subs 
1697                   { CHECK0 }
1698                   CLOSE { }
1699                 ;
1700 indiv_prop_sect : OPEN DELIM TAG_PROP mand_line_item 
1701                   { START(PROP, NULL) }
1702                   indiv_attr_event_subs 
1703                   { CHECK0 }
1704                   CLOSE { }
1705                 ;
1706 indiv_reli_sect : OPEN DELIM TAG_RELI mand_line_item 
1707                   { START(RELI, NULL) }
1708                   indiv_attr_event_subs 
1709                   { CHECK0 }
1710                   CLOSE { }
1711                 ;
1712 indiv_resi_sect : OPEN DELIM TAG_RESI 
1713                   { START(RESI, NULL) }
1714                   indiv_attr_event_subs 
1715                   { CHECK0 }
1716                   CLOSE { }
1717                 ;
1718 indiv_ssn_sect  : OPEN DELIM TAG_SSN mand_line_item 
1719                   { START(SSN, NULL) }
1720                   indiv_attr_event_subs 
1721                   { CHECK0 }
1722                   CLOSE { }
1723                 ;
1724 indiv_titl_sect : OPEN DELIM TAG_TITL mand_line_item 
1725                   { START(TITL, NULL) }
1726                   indiv_attr_event_subs 
1727                   { CHECK0 }
1728                   CLOSE { }
1729                 ;
1730
1731 indiv_attr_event_subs : /* empty */
1732                       | indiv_attr_event_subs indiv_attr_event_sub
1733                       ;
1734
1735 indiv_attr_event_sub  : event_detail_sub
1736                       | no_std_sub
1737                       ;
1738
1739 /* INDIVIDUAL EVENT STRUCTURE */
1740 indiv_even_struc_sub : indiv_birt_sect
1741                      | indiv_gen_sect
1742                      | indiv_adop_sect  /* 0:M */
1743                      | indiv_even_sect  /* 0:M */
1744                      ;
1745
1746 indiv_birt_sect : OPEN DELIM indiv_birt_tag opt_value indiv_birt_subs
1747                   { CHECK0 }
1748                   CLOSE { }
1749                 ;
1750
1751 indiv_birt_tag  : TAG_BIRT { START(BIRT, NULL) }
1752                 | TAG_CHR { START(CHR, NULL) }
1753                 ;
1754
1755 indiv_birt_subs : /* empty */
1756                 | indiv_birt_subs indiv_birt_sub
1757                 ;
1758
1759 indiv_birt_sub  : event_detail_sub
1760                 | indiv_birt_famc_sect  { OCCUR2(FAMC,0, 1) }
1761                 | no_std_sub
1762                 ;
1763
1764 indiv_birt_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1765                        { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1766                      ;
1767
1768 indiv_gen_sect  : OPEN DELIM indiv_gen_tag opt_value indiv_gen_subs
1769                   { CHECK0 }
1770                   CLOSE { }
1771                 ;
1772
1773 indiv_gen_tag   : TAG_DEAT { START(DEAT, NULL) }
1774                 | TAG_BURI { START(BURI, NULL) }
1775                 | TAG_CREM { START(CREM, NULL) }
1776                 | TAG_BAPM { START(BAPM, NULL) }
1777                 | TAG_BARM { START(BARM, NULL) }
1778                 | TAG_BASM { START(BASM, NULL) }
1779                 | TAG_BLES { START(BLES, NULL) }
1780                 | TAG_CHRA { START(CHRA, NULL) }
1781                 | TAG_CONF { START(CONF, NULL) }
1782                 | TAG_FCOM { START(FCOM, NULL) }
1783                 | TAG_ORDN { START(ORDN, NULL) }
1784                 | TAG_NATU { START(NATU, NULL) }
1785                 | TAG_EMIG { START(EMIG, NULL) }
1786                 | TAG_IMMI { START(IMMI, NULL) }
1787                 | TAG_CENS { START(CENS, NULL) }
1788                 | TAG_PROB { START(PROB, NULL) }
1789                 | TAG_WILL { START(WILL, NULL) }
1790                 | TAG_GRAD { START(GRAD, NULL) }
1791                 | TAG_RETI { START(RETI, NULL) }
1792                 ;
1793
1794 indiv_gen_subs  : /* empty */
1795                 | indiv_gen_subs indiv_gen_sub
1796                 ;
1797
1798 indiv_gen_sub   : event_detail_sub
1799                 | no_std_sub
1800                 ;
1801
1802 indiv_adop_sect : OPEN DELIM TAG_ADOP opt_value 
1803                   { START(ADOP, NULL) }
1804                   indiv_adop_subs
1805                   { CHECK0 }
1806                   CLOSE { }
1807                 ;
1808
1809 indiv_adop_subs : /* empty */
1810                 | indiv_adop_subs indiv_adop_sub
1811                 ;
1812
1813 indiv_adop_sub  : event_detail_sub
1814                 | indiv_adop_famc_sect  { OCCUR2(FAMC,0, 1) }
1815                 | no_std_sub
1816                 ;
1817
1818 indiv_adop_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1819                        { START(FAMC, NULL) }
1820                        indiv_adop_famc_subs
1821                        { CHECK0 }
1822                        CLOSE { }
1823                      ;
1824
1825 indiv_adop_famc_subs : /* empty */
1826                      | indiv_adop_famc_subs indiv_adop_famc_sub
1827                      ;
1828
1829 indiv_adop_famc_sub  : indiv_adop_famc_adop_sect  { OCCUR2(ADOP,0, 1) }
1830                      | no_std_sub
1831                      ;
1832
1833 indiv_adop_famc_adop_sect : OPEN DELIM TAG_ADOP mand_line_item   
1834                             { START(ADOP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1835                           ;
1836
1837 indiv_even_sect : OPEN DELIM TAG_EVEN
1838                   { START(EVEN, NULL) }
1839                   indiv_gen_subs
1840                   { CHECK0 }
1841                   CLOSE { }
1842                 ;
1843
1844 /* LDS INDIVIDUAL ORDINANCE */
1845 lds_indiv_ord_sub : lio_bapl_sect  /* 0:M */
1846                   | lio_slgc_sect  /* 0:M */
1847                   ;
1848
1849 lio_bapl_sect : OPEN DELIM lio_bapl_tag lio_bapl_subs
1850                 { CHECK0 }
1851                 CLOSE { }
1852               ;
1853
1854 lio_bapl_tag  : TAG_BAPL { START(BAPL, NULL) }
1855               | TAG_CONL { START(CONL, NULL) }
1856               | TAG_ENDL { START(ENDL, NULL) }
1857               ;
1858
1859 lio_bapl_subs : /* empty */
1860               | lio_bapl_subs lio_bapl_sub
1861               ;
1862
1863 lio_bapl_sub  : lio_bapl_stat_sect  { OCCUR2(STAT, 0, 1) }
1864               | lio_bapl_date_sect  { OCCUR2(DATE, 0, 1) }
1865               | lio_bapl_temp_sect  { OCCUR2(TEMP, 0, 1) }
1866               | lio_bapl_plac_sect  { OCCUR2(PLAC, 0, 1) }
1867               | source_cit_sub
1868               | note_struc_sub
1869               | no_std_sub
1870               ;
1871
1872 lio_bapl_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
1873                      { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1874                    ;
1875 lio_bapl_date_sect : OPEN DELIM TAG_DATE mand_line_item   
1876                      { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1877                    ;
1878 lio_bapl_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
1879                      { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1880                    ;
1881 lio_bapl_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
1882                      { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1883                    ;
1884
1885 lio_slgc_sect : OPEN DELIM TAG_SLGC
1886                 { START(SLGC, NULL) }
1887                 lio_slgc_subs
1888                 { CHECK1(FAMC) }
1889                 CLOSE { }
1890               ;
1891
1892 lio_slgc_subs : /* empty */
1893               | lio_slgc_subs lio_slgc_sub
1894               ;
1895
1896 lio_slgc_sub  : lio_bapl_sub
1897               | lio_slgc_famc_sect  { OCCUR2(FAMC, 1, 1) }
1898               ;
1899
1900 lio_slgc_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1901                      { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1902                    ;
1903
1904 /* LDS SPOUSE SEALING */
1905 lds_spouse_seal_sub : lss_slgs_sect
1906                     ;
1907
1908 lss_slgs_sect : OPEN DELIM TAG_SLGS
1909                 { START(SLGS, NULL) }
1910                 lss_slgs_subs
1911                 { CHECK0 }
1912                 CLOSE { }
1913               ;
1914
1915 lss_slgs_subs : /* empty */
1916               | lss_slgs_subs lss_slgs_sub
1917               ;
1918
1919 lss_slgs_sub  : lss_slgs_stat_sect  { OCCUR2(STAT, 0, 1) }
1920               | lss_slgs_date_sect  { OCCUR2(DATE, 0, 1) }
1921               | lss_slgs_temp_sect  { OCCUR2(TEMP, 0, 1) }
1922               | lss_slgs_plac_sect  { OCCUR2(PLAC, 0, 1) }
1923               | source_cit_sub
1924               | note_struc_sub
1925               | no_std_sub
1926               ;
1927
1928 lss_slgs_stat_sect : OPEN DELIM TAG_STAT mand_line_item   
1929                      { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1930                    ;
1931 lss_slgs_date_sect : OPEN DELIM TAG_DATE mand_line_item   
1932                      { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1933                    ;
1934 lss_slgs_temp_sect : OPEN DELIM TAG_TEMP mand_line_item   
1935                      { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1936                    ;
1937 lss_slgs_plac_sect : OPEN DELIM TAG_PLAC mand_line_item   
1938                      { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1939                    ;
1940
1941 /* MULTIMEDIA LINK */
1942 multim_link_sub : multim_obje_link_sect
1943                 | multim_obje_emb_sect
1944                 ;
1945
1946 multim_obje_link_sect : OPEN DELIM TAG_OBJE DELIM POINTER    
1947                         { START(OBJE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1948                       ;
1949
1950 multim_obje_emb_sect : OPEN DELIM TAG_OBJE
1951                        { START(OBJE, NULL) }
1952                        multim_obje_emb_subs
1953                        { CHECK2(FORM,FILE) }
1954                        CLOSE { }
1955                      ;
1956
1957 multim_obje_emb_subs : /* empty */
1958                      | multim_obje_emb_subs multim_obje_emb_sub
1959                      ;
1960
1961 multim_obje_emb_sub : multim_obje_form_sect  { OCCUR2(FORM, 1, 1) }
1962                     | multim_obje_titl_sect  { OCCUR2(TITL, 0, 1) }
1963                     | multim_obje_file_sect  { OCCUR2(FILE, 1, 1) }
1964                     | note_struc_sub
1965                     | no_std_sub
1966                     ;
1967
1968 multim_obje_form_sect : OPEN DELIM TAG_FORM mand_line_item    
1969                         { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1970                       ;
1971 multim_obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item    
1972                         { START(TITL, NULL) } no_std_subs { CHECK0 } CLOSE { }
1973                       ;
1974 multim_obje_file_sect : OPEN DELIM TAG_FILE mand_line_item    
1975                         { START(FILE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1976                       ;
1977
1978 /* NOTE STRUCTURE */
1979 note_struc_sub : note_struc_link_sect  /* 0:M */
1980                | note_struc_emb_sect  /* 0:M */
1981                ;
1982
1983 note_struc_link_sect : OPEN DELIM TAG_NOTE DELIM POINTER
1984                        { START(NOTE, NULL) }
1985                        note_struc_link_subs
1986                        { CHECK0 }
1987                        CLOSE { }
1988                      ;
1989
1990 note_struc_link_subs : /* empty */
1991                      | note_struc_link_subs note_struc_link_sub
1992                      ;
1993
1994 note_struc_link_sub : source_cit_sub
1995                     | no_std_sub
1996                     ;
1997
1998 note_struc_emb_sect : OPEN DELIM TAG_NOTE opt_line_item
1999                       { START(NOTE, NULL) }
2000                       note_struc_emb_subs
2001                       { CHECK0 }
2002                       CLOSE { }
2003                     ;
2004
2005 note_struc_emb_subs : /* empty */
2006                     | note_struc_emb_subs note_struc_emb_sub
2007                     ;
2008
2009 note_struc_emb_sub  : continuation_sub
2010                     | source_cit_sub
2011                     | no_std_sub
2012                     ;
2013
2014 /* PERSONAL NAME STRUCTURE */
2015 pers_name_struc_sub : pers_name_sect /* 0:M */
2016                     ;
2017
2018 pers_name_sect : OPEN DELIM TAG_NAME mand_line_item 
2019                  { START(NAME, NULL) }
2020                  pers_name_subs
2021                  { CHECK0 }
2022                  CLOSE { }
2023                ;
2024
2025 pers_name_subs : /* empty */
2026                | pers_name_subs pers_name_sub
2027                ;
2028
2029 pers_name_sub  : pers_name_npfx_sect  { OCCUR2(NPFX, 0, 1) }
2030                | pers_name_givn_sect  { OCCUR2(GIVN, 0, 1) }
2031                | pers_name_nick_sect  { OCCUR2(NICK, 0, 1) }
2032                | pers_name_spfx_sect  { OCCUR2(SPFX, 0, 1) }
2033                | pers_name_surn_sect  { OCCUR2(SURN, 0, 1) }
2034                | pers_name_nsfx_sect  { OCCUR2(NSFX, 0, 1) }
2035                | source_cit_sub
2036                | note_struc_sub
2037                | no_std_sub
2038                ;
2039
2040 pers_name_npfx_sect : OPEN DELIM TAG_NPFX mand_line_item    
2041                       { START(NPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2042                     ;
2043 pers_name_givn_sect : OPEN DELIM TAG_GIVN mand_line_item    
2044                       { START(GIVN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2045                     ;
2046 pers_name_nick_sect : OPEN DELIM TAG_NICK mand_line_item    
2047                       { START(NICK, NULL) } no_std_subs { CHECK0 } CLOSE { }
2048                     ;
2049 pers_name_spfx_sect : OPEN DELIM TAG_SPFX mand_line_item    
2050                       { START(SPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2051                     ;
2052 pers_name_surn_sect : OPEN DELIM TAG_SURN mand_line_item    
2053                       { START(SURN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2054                     ;
2055 pers_name_nsfx_sect : OPEN DELIM TAG_NSFX mand_line_item    
2056                       { START(NSFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2057                     ;
2058
2059 /* PLACE STRUCTURE */
2060 place_struc_sub : place_struc_plac_sect /* 0:M */
2061                 ;
2062
2063 place_struc_plac_sect : OPEN DELIM TAG_PLAC mand_line_item 
2064                         { START(PLAC, NULL) }
2065                         place_struc_plac_subs
2066                         { CHECK0 }
2067                         CLOSE { }
2068                       ;
2069
2070 place_struc_plac_subs : /* empty */
2071                       | place_struc_plac_subs place_struc_plac_sub
2072                       ;
2073
2074 place_struc_plac_sub : place_plac_form_sect  { OCCUR2(FORM, 0, 1) }
2075                      | source_cit_sub
2076                      | note_struc_sub
2077                      | no_std_sub
2078                      ;
2079
2080 place_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item    
2081                        { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
2082                      ;
2083
2084 /* SOURCE_CITATION */
2085 source_cit_sub : source_cit_link_sect /* 0:M */
2086                | source_cit_emb_sect /* 0:M */
2087                ;
2088
2089 source_cit_link_sect : OPEN DELIM TAG_SOUR DELIM POINTER
2090                        { START(SOUR, NULL) }
2091                        source_cit_link_subs
2092                        { CHECK0 }
2093                        CLOSE { }
2094                      ;
2095
2096 source_cit_link_subs : /* empty */
2097                      | source_cit_link_subs source_cit_link_sub
2098                      ;
2099
2100 source_cit_link_sub : source_cit_page_sect  { OCCUR2(PAGE, 0, 1) }
2101                     | source_cit_even_sect  { OCCUR2(EVEN, 0, 1) }
2102                     | source_cit_data_sect  { OCCUR2(DATA, 0, 1) }
2103                     | source_cit_quay_sect  { OCCUR2(QUAY, 0, 1) }
2104                     | multim_link_sub
2105                     | note_struc_sub
2106                     | no_std_sub
2107                     ;
2108
2109 source_cit_page_sect : OPEN DELIM TAG_PAGE mand_line_item    
2110                        { START(PAGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2111                      ;
2112
2113 source_cit_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
2114                        { START(EVEN, NULL) }
2115                        source_cit_even_subs
2116                        { CHECK0 }
2117                        CLOSE { }
2118                      ;
2119
2120 source_cit_even_subs : /* empty */
2121                      | source_cit_even_subs source_cit_even_sub
2122                      ;
2123
2124 source_cit_even_sub  : source_cit_even_role_sect  { OCCUR2(ROLE, 0, 1) }
2125                      | no_std_sub
2126                      ;
2127
2128 source_cit_even_role_sect : OPEN DELIM TAG_ROLE mand_line_item    
2129                           { START(ROLE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2130                           ;
2131
2132 source_cit_data_sect : OPEN DELIM TAG_DATA
2133                        { START(DATA, NULL) }
2134                        source_cit_data_subs
2135                        { CHECK0 }
2136                        CLOSE { }
2137                      ;
2138
2139 source_cit_data_subs : /* empty */
2140                      | source_cit_data_subs source_cit_data_sub
2141                      ;
2142
2143 source_cit_data_sub : source_cit_data_date_sect  { OCCUR2(DATE, 0, 1) }
2144                     | source_cit_text_sect  /* 0:M */
2145                     | no_std_sub
2146                     ;
2147
2148 source_cit_data_date_sect : OPEN DELIM TAG_DATE mand_line_item    
2149                             { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2150                           ;
2151
2152 source_cit_text_sect : OPEN DELIM TAG_TEXT mand_line_item 
2153                        { START(TEXT, NULL) }
2154                        source_cit_text_subs
2155                        { CHECK0 }
2156                        CLOSE { }
2157                      ;
2158
2159 source_cit_text_subs : /* empty */
2160                      | source_cit_text_subs source_cit_text_sub
2161                      ;
2162
2163 source_cit_text_sub : continuation_sub
2164                     | no_std_sub
2165                     ;
2166
2167 source_cit_quay_sect : OPEN DELIM TAG_QUAY mand_line_item    
2168                        { START(QUAY, NULL) } no_std_subs { CHECK0 } CLOSE { }
2169                      ;
2170
2171 source_cit_emb_sect : OPEN DELIM TAG_SOUR mand_line_item
2172                       { START(SOUR, NULL) }
2173                       source_cit_emb_subs
2174                       { CHECK0 }
2175                       CLOSE { }
2176                     ;
2177
2178 source_cit_emb_subs : /* empty */
2179                     | source_cit_emb_subs source_cit_emb_sub
2180                     ;
2181
2182 source_cit_emb_sub : continuation_sub
2183                    | source_cit_text_sect  /* 0:M */
2184                    | note_struc_sub
2185                    | no_std_sub
2186                    ;
2187
2188 /* SOURCE REPOSITORY CITATION */
2189 source_repos_cit_sub : source_repos_repo_sect  { OCCUR2(REPO, 0, 1) }
2190                      ;
2191
2192 source_repos_repo_sect : OPEN DELIM TAG_REPO mand_pointer
2193                          { START(REPO, NULL) }
2194                          source_repos_repo_subs
2195                          { CHECK0 }
2196                          CLOSE { }
2197                        ;
2198
2199 source_repos_repo_subs : /* empty */
2200                        | source_repos_repo_subs source_repos_repo_sub
2201                        ;
2202
2203 source_repos_repo_sub  : note_struc_sub
2204                        | caln_sect  /* 0:M */
2205                        | no_std_sub
2206                        ;
2207
2208 caln_sect : OPEN DELIM TAG_CALN mand_line_item 
2209             { START(CALN, NULL) }
2210             caln_subs
2211             { CHECK0 }
2212             CLOSE { }
2213           ;
2214
2215 caln_subs : /* empty */
2216           | caln_subs caln_sub
2217           ;
2218
2219 caln_sub  : caln_medi_sect  { OCCUR2(MEDI, 0, 1) }
2220           | no_std_sub
2221           ;
2222
2223 caln_medi_sect : OPEN DELIM TAG_MEDI mand_line_item    
2224                  { START(MEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
2225                ;
2226  
2227 /* SPOUSE TO FAMILY LINK */
2228 spou_fam_link_sub : spou_fam_fams_sect  /* 0:M */
2229                   ;
2230
2231 spou_fam_fams_sect : OPEN DELIM TAG_FAMS mand_pointer
2232                      { START(FAMS, NULL) }
2233                      spou_fam_fams_subs
2234                      { CHECK0 }
2235                      CLOSE { }
2236                    ;
2237
2238 spou_fam_fams_subs : /* empty */
2239                    | spou_fam_fams_subs spou_fam_fams_sub
2240                    ;
2241
2242 spou_fam_fams_sub  : note_struc_sub
2243                    | no_std_sub
2244                    ;
2245
2246 /*********************************************************************/
2247 /**** General                                                     ****/
2248 /*********************************************************************/
2249
2250 no_std_subs : /* empty */
2251             | no_std_subs no_std_sub
2252             ;
2253
2254 no_std_sub  : user_sect /* 0:M */
2255             | gen_sect
2256             | error error_subs CLOSE  { HANDLE_ERROR }
2257             ;
2258
2259 no_std_rec  : user_rec /* 0:M */
2260             | gen_rec
2261             | error error_subs CLOSE  { HANDLE_ERROR }
2262             ;
2263
2264 user_rec    : OPEN DELIM opt_xref USERTAG 
2265               { if ($4[0] != '_') {
2266                   gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
2267                                $4);
2268                   YYERROR;
2269                 }
2270               }
2271               opt_value
2272               { $<ctxt>$ = start_record(REC_USER, $1, $3, $4);
2273                 START($4, $<ctxt>$)
2274               }
2275               user_sects
2276               { CHECK0 }
2277               CLOSE
2278               { end_record(REC_USER, $<ctxt>7); }
2279             ;
2280 user_sect   : OPEN DELIM opt_xref USERTAG 
2281               { if ($4[0] != '_') {
2282                   gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
2283                                $4);
2284                   YYERROR;
2285                 }
2286               }
2287               opt_value
2288               { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6, $6);
2289                 START($4, $<ctxt>$);
2290               }
2291               user_sects
2292               { CHECK0 }
2293               CLOSE
2294               { end_element(ELT_USER, PARENT, $<ctxt>7, NULL);
2295               }
2296             ;
2297
2298 user_sects   : /* empty */     { }
2299             | user_sects user_sect { }
2300             ;
2301
2302 opt_xref    : /* empty */        { $$ = NULL; }
2303             | POINTER DELIM        { $$ = $1; }
2304             ;
2305
2306 opt_value   : /* empty */        { $$ = NULL; }
2307             | DELIM line_value        { $$ = $2; }
2308             ;
2309
2310 line_value  : POINTER        { $$ = $1; }
2311             | line_item        { $$ = $1; }
2312             ;
2313
2314 mand_pointer : /* empty */ { gedcom_error(_("Missing pointer")); YYERROR; }
2315              | DELIM POINTER { $$ = $2; }
2316              ;
2317
2318 mand_line_item : /* empty */ { gedcom_error(_("Missing value")); YYERROR; }
2319                | DELIM line_item { $$ = $2; }
2320                ;
2321
2322 opt_line_item : /* empty */ { }
2323               | DELIM line_item { }
2324               ;
2325
2326 line_item   : anychar  { size_t i;
2327                          CLEAR_BUFFER(line_item_buf);
2328                          line_item_buf_ptr = line_item_buf;
2329                          /* The following also takes care of '@@' */
2330                          if (!strncmp($1, "@@", 3))
2331                            *line_item_buf_ptr++ = '@';
2332                          else
2333                            for (i=0; i < strlen($1); i++)
2334                              *line_item_buf_ptr++ = $1[i];
2335                          $$ = line_item_buf;
2336                        }
2337             | ESCAPE   { CLEAR_BUFFER(line_item_buf);
2338                          line_item_buf_ptr = line_item_buf;
2339                          /* For now, ignore escapes */
2340                          $$ = line_item_buf;
2341                        }
2342             | line_item anychar
2343                   { size_t i;
2344                     /* The following also takes care of '@@' */
2345                     if (!strncmp($2, "@@", 3))
2346                       *line_item_buf_ptr++ = '@';
2347                     else
2348                       for (i=0; i < strlen($2); i++)
2349                         *line_item_buf_ptr++ = $2[i];
2350                     $$ = line_item_buf;
2351                   }
2352             | line_item ESCAPE
2353                   { /* For now, ignore escapes */
2354                     $$ = line_item_buf;
2355                   }
2356             ;
2357
2358 anychar     : ANYCHAR        { }
2359             | DELIM        { }
2360             ;
2361
2362 error_subs  : /* empty */
2363             | error_subs error_sect
2364             ;
2365
2366 error_sect  : OPEN DELIM opt_xref anytag opt_value error_subs CLOSE { }
2367
2368 gen_sect    : OPEN DELIM opt_xref anystdtag
2369               { INVALID_TAG($4); }
2370               opt_value opt_sects CLOSE
2371               { }
2372             ;
2373
2374 gen_rec : gen_rec_top
2375         | gen_rec_norm
2376         ;
2377
2378 gen_rec_norm : OPEN DELIM opt_xref anystdtag
2379                { INVALID_TOP_TAG($4) }
2380                opt_value opt_sects CLOSE
2381                { }
2382              ;
2383
2384 gen_rec_top : OPEN DELIM anytoptag
2385               { gedcom_error(_("Missing cross-reference")); YYERROR; }
2386               opt_value opt_sects CLOSE
2387                 { }
2388             ;
2389
2390 opt_sects   : /* empty */     { }
2391             | opt_sects gen_sect { }
2392             ;
2393
2394 anytag      : USERTAG { }
2395             | anystdtag { }
2396             ;
2397
2398 anytoptag   : TAG_FAM
2399             | TAG_INDI
2400             | TAG_OBJE
2401             | TAG_NOTE
2402             | TAG_REPO
2403             | TAG_SOUR
2404             | TAG_SUBN
2405             | TAG_SUBM
2406             ;
2407
2408 anystdtag   : TAG_ABBR
2409             | TAG_ADDR
2410             | TAG_ADR1
2411             | TAG_ADR2   { }
2412             | TAG_ADOP   { }
2413             | TAG_AFN   { }
2414             | TAG_AGE   { }
2415             | TAG_AGNC   { }
2416             | TAG_ALIA   { }
2417             | TAG_ANCE   { }
2418             | TAG_ANCI   { }
2419             | TAG_ANUL   { }
2420             | TAG_ASSO   { }
2421             | TAG_AUTH   { }
2422             | TAG_BAPL   { }
2423             | TAG_BAPM   { }
2424             | TAG_BARM   { }
2425             | TAG_BASM   { }
2426             | TAG_BIRT   { }
2427             | TAG_BLES   { }
2428             | TAG_BLOB   { }
2429             | TAG_BURI   { }
2430             | TAG_CALN   { }
2431             | TAG_CAST   { }
2432             | TAG_CAUS   { }
2433             | TAG_CENS   { }
2434             | TAG_CHAN   { }
2435             | TAG_CHAR   { }
2436             | TAG_CHIL   { }
2437             | TAG_CHR   { }
2438             | TAG_CHRA   { }
2439             | TAG_CITY   { }
2440             | TAG_CONC   { }
2441             | TAG_CONF   { }
2442             | TAG_CONL   { }
2443             | TAG_CONT   { }
2444             | TAG_COPR   { }
2445             | TAG_CORP   { }
2446             | TAG_CREM   { }
2447             | TAG_CTRY   { }
2448             | TAG_DATA   { }
2449             | TAG_DATE   { }
2450             | TAG_DEAT   { }
2451             | TAG_DESC   { }
2452             | TAG_DESI   { }
2453             | TAG_DEST   { }
2454             | TAG_DIV   { }
2455             | TAG_DIVF   { }
2456             | TAG_DSCR   { }
2457             | TAG_EDUC   { }
2458             | TAG_EMIG   { }
2459             | TAG_ENDL   { }
2460             | TAG_ENGA   { }
2461             | TAG_EVEN   { }
2462             | TAG_FAM    { }
2463             | TAG_FAMC   { }
2464             | TAG_FAMS   { }
2465             | TAG_FCOM   { }
2466             | TAG_FILE   { }
2467             | TAG_FORM   { }
2468             | TAG_GEDC   { }
2469             | TAG_GIVN   { }
2470             | TAG_GRAD   { }
2471             | TAG_HEAD   { }
2472             | TAG_HUSB   { }
2473             | TAG_IDNO   { }
2474             | TAG_IMMI   { }
2475             | TAG_INDI   { }
2476             | TAG_LANG   { }
2477             | TAG_LEGA   { }
2478             | TAG_MARB   { }
2479             | TAG_MARC   { }
2480             | TAG_MARL   { }
2481             | TAG_MARR   { }
2482             | TAG_MARS   { }
2483             | TAG_MEDI   { }
2484             | TAG_NAME   { }
2485             | TAG_NATI   { }
2486             | TAG_NCHI   { }
2487             | TAG_NICK   { }
2488             | TAG_NMR   { }
2489             | TAG_NOTE   { }
2490             | TAG_NPFX   { }
2491             | TAG_NSFX   { }
2492             | TAG_OBJE   { }
2493             | TAG_OCCU   { }
2494             | TAG_ORDI   { }
2495             | TAG_ORDN   { }
2496             | TAG_PAGE   { }
2497             | TAG_PEDI   { }
2498             | TAG_PHON   { }
2499             | TAG_PLAC   { }
2500             | TAG_POST   { }
2501             | TAG_PROB   { }
2502             | TAG_PROP   { }
2503             | TAG_PUBL   { }
2504             | TAG_QUAY   { }
2505             | TAG_REFN   { }
2506             | TAG_RELA   { }
2507             | TAG_RELI   { }
2508             | TAG_REPO   { }
2509             | TAG_RESI   { }
2510             | TAG_RESN   { }
2511             | TAG_RETI   { }
2512             | TAG_RFN   { }
2513             | TAG_RIN   { }
2514             | TAG_ROLE   { }
2515             | TAG_SEX   { }
2516             | TAG_SLGC   { }
2517             | TAG_SLGS   { }
2518             | TAG_SOUR   { }
2519             | TAG_SPFX   { }
2520             | TAG_SSN   { }
2521             | TAG_STAE   { }
2522             | TAG_STAT   { }
2523             | TAG_SUBM   { }
2524             | TAG_SUBN   { }
2525             | TAG_SURN   { }
2526             | TAG_TEMP   { }
2527             | TAG_TEXT   { }
2528             | TAG_TIME   { }
2529             | TAG_TITL   { }
2530             | TAG_TRLR   { }
2531             | TAG_TYPE   { }
2532             | TAG_VERS   { }
2533             | TAG_WIFE   { }
2534             | TAG_WILL   { }
2535
2536 %%
2537
2538 /* Functions that handle the counting of subtags */
2539
2540 int* count_arrays[MAXGEDCLEVEL+1];
2541 char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLEN+1];
2542 Gedcom_ctxt ctxt_stack[MAXGEDCLEVEL+1];
2543
2544 void push_countarray()
2545 {
2546   int *count = NULL;
2547   if (count_level > MAXGEDCLEVEL) {
2548     gedcom_error(_("Internal error: count array overflow"));
2549     exit(1);
2550   }
2551   else {
2552     count = (int *)calloc(YYNTOKENS, sizeof(int));
2553     if (count == NULL) {
2554       gedcom_error(_("Internal error: count array calloc error"));
2555       exit(1);
2556     }
2557     else {
2558       count_arrays[count_level] = count;
2559     }
2560   }
2561 }
2562
2563 void set_parenttag(char* tag)
2564 {
2565   strncpy(tag_stack[count_level], tag, MAXSTDTAGLEN+1);
2566 }
2567
2568 void set_parentctxt(Gedcom_ctxt ctxt)
2569 {
2570   ctxt_stack[count_level] = ctxt;
2571 }
2572
2573 char* get_parenttag()
2574 {
2575   return tag_stack[count_level];
2576 }
2577
2578 Gedcom_ctxt get_parentctxt()
2579 {
2580   return ctxt_stack[count_level];
2581 }
2582
2583 int count_tag(int tag)
2584 {
2585   int *count = count_arrays[count_level];
2586   return ++count[tag - GEDCOMTAGOFFSET];
2587 }
2588
2589 int check_occurrence(int tag)
2590 {
2591   int *count = count_arrays[count_level];
2592   return (count[tag - GEDCOMTAGOFFSET] > 0);
2593 }
2594
2595 void pop_countarray()
2596 {
2597   int *count;
2598   if (count_level < 0) {
2599     gedcom_error(_("Internal error: count array underflow"));
2600     exit(1);
2601   }
2602   else {
2603     count = count_arrays[count_level];
2604     free(count);
2605     count_arrays[count_level] = NULL;
2606   }
2607 }
2608
2609 /* Enabling debug mode */
2610 /* level 0: no debugging */
2611 /* level 1: only internal */
2612 /* level 2: also bison */
2613 FILE* trace_output;
2614
2615 void gedcom_set_debug_level(int level, FILE* f)
2616 {
2617   if (f != NULL)
2618     trace_output = f;
2619   else
2620     trace_output = stderr;
2621   if (level > 0) {
2622     gedcom_high_level_debug = 1;
2623   }
2624   if (level > 1) {
2625 #if YYDEBUG != 0
2626     gedcom_debug = 1;
2627 #endif
2628   }
2629 }
2630
2631 int gedcom_debug_print(char* s, ...)
2632 {
2633   int res = 0;
2634   if (gedcom_high_level_debug) {
2635     va_list ap;
2636     va_start(ap, s);
2637     res = vfprintf(trace_output, s, ap);
2638     va_end(ap);
2639   }
2640   return(res);
2641 }
2642
2643 /* Setting the error mechanism */
2644 void gedcom_set_error_handling(Gedcom_err_mech mechanism)
2645 {
2646   error_mechanism = mechanism;
2647 }
2648
2649 /* Compatibility handling */
2650
2651 void gedcom_set_compat_handling(int enable_compat)
2652 {
2653   compat_enabled = enable_compat;
2654 }
2655
2656 void set_compatibility(char* program)
2657 {
2658   if (compat_enabled) {
2659     if (! strncmp(program, "ftree", 6)) {
2660       gedcom_warning(_("Enabling compatibility with 'ftree'"));
2661       compatibility = C_FTREE;
2662     }
2663     else {
2664       compatibility = 0;
2665     }
2666   }
2667 }
2668
2669 int compat_mode(int compat_flags)
2670 {
2671   return (compat_flags & compatibility);
2672 }
2673