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