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