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.
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.
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.
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
24 /* WARNING: THIS PARSER RELIES HEAVILY ON SOME FEATURES OF BISON.
25 DON'T TRY TO USE IT WITH YACC, IT WON'T WORK...
28 /* Design of the parser:
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).
34 This means that in general we have:
36 A 'record' is a 'section' (sect) containing 'subsections' (subs)
37 Each 'subsection' (sub) is again a specific 'section' (sect)
39 In parser notation, this means:
43 sect : <some prefix> subs <some suffix>
45 subs : <empty> | subs sub
47 sub : sect_a | sect_b | ...
49 This pattern is repeated throughout the parser for the different types of
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.
60 Suppose there is a section A that can contain 0 or 1 B section and
63 This can be expressed in parser notation as follows:
65 A : CC | BCC | CBC | CCB
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.
71 Much simpler is to say:
74 subs : <empty> | subs sub
77 and then check the cardinality in the semantic actions, which is the
78 solution chosen in the parser below, using the following macros:
81 Make a new context for the <parent> tag to count child tags in
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
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.
92 - OCCUR1(<child>, <min>)
93 Express that the <child> tag should occur at least <min> times within
94 its parent (no upper limit)
96 Actually, this only increments the counter for the tag, but it looks
97 very like the previous macro.
99 If the minimum is 0, it is not necessary to express this constraint.
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).
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.
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).
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):
120 head_sect : OPEN DELIM TAG_HEAD
124 CLOSE { <semantic actions> }
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) }
138 - The syntax analysis doesn't handle the contents of the line values;
139 this is done in the semantic analysis.
144 #include "gedcom_internal.h"
145 #include "multilex.h"
146 #include "encoding.h"
147 #include "interface.h"
151 int compat_enabled = 1;
152 int gedcom_high_level_debug = 0;
153 int compatibility = 0;
154 Gedcom_err_mech error_mechanism = IMMED_FAIL;
156 char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
157 char *line_item_buf_ptr;
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);
175 #define CLEAR_BUFFER(BUF) \
176 memset(BUF, 0, sizeof(BUF));
178 #define HANDLE_ERROR \
179 { if (error_mechanism == IMMED_FAIL) { \
182 else if (error_mechanism == DEFER_FAIL) { \
185 else if (error_mechanism == IGNORE_ERRORS) { \
189 #define START(PARENTTAG,PARENTCTXT) \
191 set_parenttag(#PARENTTAG); \
192 set_parentctxt(PARENTCTXT); \
198 { if (!check_occurrence(TAG_##TAG)) { \
199 char* parenttag = get_parenttag(); \
200 gedcom_error(_("The tag '%s' is mandatory within '%s', but missing"),\
206 { pop_countarray(); \
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); \
221 char* parenttag = get_parenttag(); \
222 gedcom_error(_("The tag '%s' can maximally occur %d time(s) within '%s'"), \
223 #CHILDTAG, MAX, parenttag); \
227 #define INVALID_TAG(CHILDTAG) \
228 { char* parenttag = get_parenttag(); \
229 gedcom_error(_("The tag '%s' is not a valid tag within '%s'"), \
230 CHILDTAG, parenttag); \
233 #define INVALID_TOP_TAG(CHILDTAG) \
234 { gedcom_error(_("The tag '%s' is not a valid top-level tag"), \
250 %token <string> BADTOKEN
252 %token <string> CLOSE
253 %token <string> ESCAPE
254 %token <string> DELIM
255 %token <string> ANYCHAR
256 %token <string> POINTER
257 %token <string> USERTAG
258 %token <string> TAG_ABBR
259 %token <string> TAG_ADDR
260 %token <string> TAG_ADR1
261 %token <string> TAG_ADR2
262 %token <string> TAG_ADOP
263 %token <string> TAG_AFN
264 %token <string> TAG_AGE
265 %token <string> TAG_AGNC
266 %token <string> TAG_ALIA
267 %token <string> TAG_ANCE
268 %token <string> TAG_ANCI
269 %token <string> TAG_ANUL
270 %token <string> TAG_ASSO
271 %token <string> TAG_AUTH
272 %token <string> TAG_BAPL
273 %token <string> TAG_BAPM
274 %token <string> TAG_BARM
275 %token <string> TAG_BASM
276 %token <string> TAG_BIRT
277 %token <string> TAG_BLES
278 %token <string> TAG_BLOB
279 %token <string> TAG_BURI
280 %token <string> TAG_CALN
281 %token <string> TAG_CAST
282 %token <string> TAG_CAUS
283 %token <string> TAG_CENS
284 %token <string> TAG_CHAN
285 %token <string> TAG_CHAR
286 %token <string> TAG_CHIL
287 %token <string> TAG_CHR
288 %token <string> TAG_CHRA
289 %token <string> TAG_CITY
290 %token <string> TAG_CONC
291 %token <string> TAG_CONF
292 %token <string> TAG_CONL
293 %token <string> TAG_CONT
294 %token <string> TAG_COPR
295 %token <string> TAG_CORP
296 %token <string> TAG_CREM
297 %token <string> TAG_CTRY
298 %token <string> TAG_DATA
299 %token <string> TAG_DATE
300 %token <string> TAG_DEAT
301 %token <string> TAG_DESC
302 %token <string> TAG_DESI
303 %token <string> TAG_DEST
304 %token <string> TAG_DIV
305 %token <string> TAG_DIVF
306 %token <string> TAG_DSCR
307 %token <string> TAG_EDUC
308 %token <string> TAG_EMIG
309 %token <string> TAG_ENDL
310 %token <string> TAG_ENGA
311 %token <string> TAG_EVEN
312 %token <string> TAG_FAM
313 %token <string> TAG_FAMC
314 %token <string> TAG_FAMF
315 %token <string> TAG_FAMS
316 %token <string> TAG_FCOM
317 %token <string> TAG_FILE
318 %token <string> TAG_FORM
319 %token <string> TAG_GEDC
320 %token <string> TAG_GIVN
321 %token <string> TAG_GRAD
322 %token <string> TAG_HEAD
323 %token <string> TAG_HUSB
324 %token <string> TAG_IDNO
325 %token <string> TAG_IMMI
326 %token <string> TAG_INDI
327 %token <string> TAG_LANG
328 %token <string> TAG_LEGA
329 %token <string> TAG_MARB
330 %token <string> TAG_MARC
331 %token <string> TAG_MARL
332 %token <string> TAG_MARR
333 %token <string> TAG_MARS
334 %token <string> TAG_MEDI
335 %token <string> TAG_NAME
336 %token <string> TAG_NATI
337 %token <string> TAG_NATU
338 %token <string> TAG_NCHI
339 %token <string> TAG_NICK
340 %token <string> TAG_NMR
341 %token <string> TAG_NOTE
342 %token <string> TAG_NPFX
343 %token <string> TAG_NSFX
344 %token <string> TAG_OBJE
345 %token <string> TAG_OCCU
346 %token <string> TAG_ORDI
347 %token <string> TAG_ORDN
348 %token <string> TAG_PAGE
349 %token <string> TAG_PEDI
350 %token <string> TAG_PHON
351 %token <string> TAG_PLAC
352 %token <string> TAG_POST
353 %token <string> TAG_PROB
354 %token <string> TAG_PROP
355 %token <string> TAG_PUBL
356 %token <string> TAG_QUAY
357 %token <string> TAG_REFN
358 %token <string> TAG_RELA
359 %token <string> TAG_RELI
360 %token <string> TAG_REPO
361 %token <string> TAG_RESI
362 %token <string> TAG_RESN
363 %token <string> TAG_RETI
364 %token <string> TAG_RFN
365 %token <string> TAG_RIN
366 %token <string> TAG_ROLE
367 %token <string> TAG_SEX
368 %token <string> TAG_SLGC
369 %token <string> TAG_SLGS
370 %token <string> TAG_SOUR
371 %token <string> TAG_SPFX
372 %token <string> TAG_SSN
373 %token <string> TAG_STAE
374 %token <string> TAG_STAT
375 %token <string> TAG_SUBM
376 %token <string> TAG_SUBN
377 %token <string> TAG_SURN
378 %token <string> TAG_TEMP
379 %token <string> TAG_TEXT
380 %token <string> TAG_TIME
381 %token <string> TAG_TITL
382 %token <string> TAG_TRLR
383 %token <string> TAG_TYPE
384 %token <string> TAG_VERS
385 %token <string> TAG_WIFE
386 %token <string> TAG_WILL
388 %type <string> anystdtag
389 %type <string> anytoptag
390 %type <string> line_item
391 %type <string> line_value
392 %type <string> mand_line_item
393 %type <string> mand_pointer
394 %type <string> note_line_item
395 %type <string> anychar
396 %type <string> opt_xref
397 %type <string> opt_value
398 %type <ctxt> head_sect
402 file : head_sect records trlr_sect
403 { if (fail == 1) YYABORT; }
406 records : /* empty */
421 /*********************************************************************/
423 /*********************************************************************/
424 head_sect : OPEN DELIM TAG_HEAD
425 { $<ctxt>$ = start_record(REC_HEAD, $1, NULL, $3);
426 START(HEAD, $<ctxt>$) }
428 { if (compat_mode(C_FTREE))
429 CHECK3(SOUR, GEDC, CHAR)
431 CHECK4(SOUR, SUBM, GEDC, CHAR)
434 { end_record(REC_HEAD, $<ctxt>4); }
437 head_subs : /* empty */
441 head_sub : head_sour_sect { OCCUR2(SOUR, 1, 1) }
442 | head_dest_sect { OCCUR2(DEST, 0, 1) }
443 | head_date_sect { OCCUR2(DATE, 0, 1) }
444 | head_subm_sect { OCCUR2(SUBM, 1, 1) }
445 | head_subn_sect { OCCUR2(SUBN, 0, 1) }
446 | head_file_sect { OCCUR2(FILE, 0, 1) }
447 | head_copr_sect { OCCUR2(COPR, 0, 1) }
448 | head_gedc_sect { OCCUR2(GEDC, 1, 1) }
449 | head_char_sect { OCCUR2(CHAR, 1, 1) }
450 | head_lang_sect { OCCUR2(LANG, 0, 1) }
451 | head_plac_sect { OCCUR2(PLAC, 0, 1) }
452 | head_note_sect { OCCUR2(NOTE, 0, 1) }
457 head_sour_sect : OPEN DELIM TAG_SOUR mand_line_item
458 { set_compatibility($4);
459 $<ctxt>$ = start_element(ELT_HEAD_SOUR, PARENT,
461 START(SOUR, $<ctxt>$)
466 { end_element(ELT_HEAD_SOUR, PARENT, $<ctxt>5, NULL); }
469 head_sour_subs : /* empty */
470 | head_sour_subs head_sour_sub
473 head_sour_sub : head_sour_vers_sect { OCCUR2(VERS, 0, 1) }
474 | head_sour_name_sect { OCCUR2(NAME, 0, 1) }
475 | head_sour_corp_sect { OCCUR2(CORP, 0, 1) }
476 | head_sour_data_sect { OCCUR2(DATA, 0, 1) }
480 head_sour_vers_sect : OPEN DELIM TAG_VERS mand_line_item
481 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_VERS, PARENT,
483 START(VERS, $<ctxt>$)
488 { end_element(ELT_HEAD_SOUR_VERS,
489 PARENT, $<ctxt>5, NULL);
492 head_sour_name_sect : OPEN DELIM TAG_NAME mand_line_item
493 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_NAME, PARENT,
495 START(NAME, $<ctxt>$)
500 { end_element(ELT_HEAD_SOUR_NAME,
501 PARENT, $<ctxt>5, NULL);
504 head_sour_corp_sect : OPEN DELIM TAG_CORP mand_line_item
505 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_CORP, PARENT,
507 START(CORP, $<ctxt>$)
512 { end_element(ELT_HEAD_SOUR_CORP,
513 PARENT, $<ctxt>5, NULL);
517 head_sour_corp_subs : /* empty */
518 | head_sour_corp_subs head_sour_corp_sub
521 head_sour_corp_sub : addr_struc_sub /* 0:1 */
525 head_sour_data_sect : OPEN DELIM TAG_DATA mand_line_item
526 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA, PARENT,
528 START(DATA, $<ctxt>$)
533 { end_element(ELT_HEAD_SOUR_DATA,
534 PARENT, $<ctxt>5, NULL);
538 head_sour_data_subs : /* empty */
539 | head_sour_data_subs head_sour_data_sub
542 head_sour_data_sub : head_sour_data_date_sect { OCCUR2(DATE, 0, 1) }
543 | head_sour_data_copr_sect { OCCUR2(COPR, 0, 1) }
547 head_sour_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
548 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_DATE,
549 PARENT, $1, $3, $4, $4);
550 START(DATE, $<ctxt>$)
555 { end_element(ELT_HEAD_SOUR_DATA_DATE,
556 PARENT, $<ctxt>5, NULL);
559 head_sour_data_copr_sect : OPEN DELIM TAG_COPR mand_line_item
560 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_COPR,
561 PARENT, $1, $3, $4, $4);
562 START(COPR, $<ctxt>$)
567 { end_element(ELT_HEAD_SOUR_DATA_COPR,
568 PARENT, $<ctxt>5, NULL);
573 head_dest_sect : OPEN DELIM TAG_DEST mand_line_item
574 { $<ctxt>$ = start_element(ELT_HEAD_DEST,
575 PARENT, $1, $3, $4, $4);
576 START(DEST, $<ctxt>$)
581 { end_element(ELT_HEAD_DEST,
582 PARENT, $<ctxt>5, NULL);
587 head_date_sect : OPEN DELIM TAG_DATE mand_line_item
588 { $<ctxt>$ = start_element(ELT_HEAD_DATE,
589 PARENT, $1, $3, $4, $4);
590 START(DATE, $<ctxt>$)
595 { end_element(ELT_HEAD_DATE,
596 PARENT, $<ctxt>5, NULL);
600 head_date_subs : /* empty */
601 | head_date_subs head_date_sub
604 head_date_sub : head_date_time_sect { OCCUR2(TIME, 0, 1) }
608 head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
609 { $<ctxt>$ = start_element(ELT_HEAD_DATE_TIME,
610 PARENT, $1, $3, $4, $4);
611 START(TIME, $<ctxt>$)
616 { end_element(ELT_HEAD_DATE_TIME,
617 PARENT, $<ctxt>5, NULL);
622 head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
623 { $<ctxt>$ = start_element(ELT_HEAD_SUBM,
624 PARENT, $1, $3, $4, $4);
625 START(SUBM, $<ctxt>$)
630 { end_element(ELT_HEAD_SUBM,
631 PARENT, $<ctxt>5, NULL);
635 head_subn_sect : OPEN DELIM TAG_SUBN mand_pointer
636 { $<ctxt>$ = start_element(ELT_HEAD_SUBN,
637 PARENT, $1, $3, $4, $4);
638 START(SUBN, $<ctxt>$)
643 { end_element(ELT_HEAD_SUBN,
644 PARENT, $<ctxt>5, NULL);
648 head_file_sect : OPEN DELIM TAG_FILE mand_line_item
649 { $<ctxt>$ = start_element(ELT_HEAD_FILE,
650 PARENT, $1, $3, $4, $4);
651 START(FILE, $<ctxt>$)
656 { end_element(ELT_HEAD_FILE, PARENT, $<ctxt>5, NULL);
660 head_copr_sect : OPEN DELIM TAG_COPR mand_line_item
661 { $<ctxt>$ = start_element(ELT_HEAD_COPR,
662 PARENT, $1, $3, $4, $4);
663 START(COPR, $<ctxt>$)
668 { end_element(ELT_HEAD_COPR, PARENT, $<ctxt>5, NULL);
672 head_gedc_sect : OPEN DELIM TAG_GEDC
673 { $<ctxt>$ = start_element(ELT_HEAD_GEDC,
674 PARENT, $1, $3, NULL, NULL);
675 START(GEDC, $<ctxt>$)
678 { CHECK2(VERS, FORM) }
680 { end_element(ELT_HEAD_GEDC, PARENT, $<ctxt>4, NULL);
684 head_gedc_subs : /* empty */
685 | head_gedc_subs head_gedc_sub
688 head_gedc_sub : head_gedc_vers_sect { OCCUR2(VERS, 1, 1) }
689 | head_gedc_form_sect { OCCUR2(FORM, 1, 1) }
692 head_gedc_vers_sect : OPEN DELIM TAG_VERS mand_line_item
693 { $<ctxt>$ = start_element(ELT_HEAD_GEDC_VERS,
694 PARENT, $1, $3, $4, $4);
695 START(VERS, $<ctxt>$)
700 { end_element(ELT_HEAD_GEDC_VERS,
701 PARENT, $<ctxt>5, NULL);
704 head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item
705 { $<ctxt>$ = start_element(ELT_HEAD_GEDC_FORM,
706 PARENT, $1, $3, $4, $4);
707 START(FORM, $<ctxt>$)
712 { end_element(ELT_HEAD_GEDC_FORM,
713 PARENT, $<ctxt>5, NULL);
718 head_char_sect : OPEN DELIM TAG_CHAR mand_line_item
719 { if (open_conv_to_internal($4) == 0) YYERROR;
720 $<ctxt>$ = start_element(ELT_HEAD_CHAR,
721 PARENT, $1, $3, $4, $4);
722 START(CHAR, $<ctxt>$)
727 { end_element(ELT_HEAD_CHAR, PARENT, $<ctxt>5, NULL);
731 head_char_subs : /* empty */
732 | head_char_subs head_char_sub
735 head_char_sub : head_char_vers_sect { OCCUR2(VERS, 0, 1) }
738 head_char_vers_sect : OPEN DELIM TAG_VERS mand_line_item
739 { $<ctxt>$ = start_element(ELT_HEAD_CHAR_VERS,
740 PARENT, $1, $3, $4, $4);
741 START(VERS, $<ctxt>$)
746 { end_element(ELT_HEAD_CHAR_VERS,
747 PARENT, $<ctxt>5, NULL);
752 head_lang_sect : OPEN DELIM TAG_LANG mand_line_item
753 { $<ctxt>$ = start_element(ELT_HEAD_LANG,
754 PARENT, $1, $3, $4, $4);
755 START(LANG, $<ctxt>$)
760 { end_element(ELT_HEAD_LANG, PARENT, $<ctxt>5, NULL);
764 head_plac_sect : OPEN DELIM TAG_PLAC
765 { $<ctxt>$ = start_element(ELT_HEAD_PLAC,
766 PARENT, $1, $3, NULL, NULL);
767 START(PLAC, $<ctxt>$)
772 { end_element(ELT_HEAD_PLAC, PARENT, $<ctxt>4, NULL);
776 head_plac_subs : /* empty */
777 | head_plac_subs head_plac_sub
780 head_plac_sub : head_plac_form_sect { OCCUR2(FORM, 1, 1) }
783 head_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item
784 { $<ctxt>$ = start_element(ELT_HEAD_PLAC_FORM,
785 PARENT, $1, $3, $4, $4);
786 START(FORM, $<ctxt>$)
791 { end_element(ELT_HEAD_PLAC_FORM,
792 PARENT, $<ctxt>5, NULL);
797 head_note_sect : OPEN DELIM TAG_NOTE mand_line_item
798 { $<ctxt>$ = start_element(ELT_HEAD_NOTE,
799 PARENT, $1, $3, $4, $4);
800 START(NOTE, $<ctxt>$)
805 { end_element(ELT_HEAD_NOTE, PARENT, $<ctxt>5, NULL);
809 head_note_subs : /* empty */
810 | head_note_subs head_note_sub
813 head_note_sub : continuation_sub /* 0:M */
817 /*********************************************************************/
819 /*********************************************************************/
820 /* Don't need callbacks here, there is no information... */
821 trlr_sect : OPEN DELIM TAG_TRLR CLOSE { }
824 /*********************************************************************/
825 /**** Family record ****/
826 /*********************************************************************/
827 fam_rec : OPEN DELIM POINTER DELIM TAG_FAM
828 { $<ctxt>$ = start_record(REC_FAM, $1, $3, $5);
829 START(FAM, $<ctxt>$) }
833 { end_record(REC_FAM, $<ctxt>6); }
836 fam_subs : /* empty */
840 fam_sub : fam_event_struc_sub /* 0:M */
841 | fam_husb_sect { OCCUR2(HUSB, 0, 1) }
842 | fam_wife_sect { OCCUR2(WIFE, 0, 1) }
843 | fam_chil_sect /* 0:M */
844 | fam_nchi_sect { OCCUR2(NCHI, 0, 1) }
845 | fam_subm_sect /* 0:M */
846 | lds_spouse_seal_sub /* 0:M */
847 | source_cit_sub /* 0:M */
848 | multim_link_sub /* 0:M */
849 | note_struc_sub /* 0:M */
850 | ident_struc_sub /* 0:1 */
851 | change_date_sub /* 0:1 */
856 fam_husb_sect : OPEN DELIM TAG_HUSB mand_pointer
857 { $<ctxt>$ = start_element(ELT_FAM_HUSB,
858 PARENT, $1, $3, $4, $4);
859 START(HUSB, $<ctxt>$)
864 { end_element(ELT_FAM_HUSB, PARENT, $<ctxt>5, NULL);
869 fam_wife_sect : OPEN DELIM TAG_WIFE mand_pointer
870 { $<ctxt>$ = start_element(ELT_FAM_WIFE,
871 PARENT, $1, $3, $4, $4);
872 START(WIFE, $<ctxt>$)
877 { end_element(ELT_FAM_WIFE, PARENT, $<ctxt>5, NULL);
882 fam_chil_sect : OPEN DELIM TAG_CHIL mand_pointer
883 { $<ctxt>$ = start_element(ELT_FAM_CHIL,
884 PARENT, $1, $3, $4, $4);
885 START(CHIL, $<ctxt>$)
890 { end_element(ELT_FAM_CHIL, PARENT, $<ctxt>5, NULL);
895 fam_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item
896 { $<ctxt>$ = start_element(ELT_FAM_NCHI,
897 PARENT, $1, $3, $4, $4);
898 START(NCHI, $<ctxt>$)
903 { end_element(ELT_FAM_NCHI, PARENT, $<ctxt>5, NULL);
908 fam_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
909 { $<ctxt>$ = start_element(ELT_FAM_SUBM,
910 PARENT, $1, $3, $4, $4);
911 START(SUBM, $<ctxt>$)
916 { end_element(ELT_FAM_SUBM, PARENT, $<ctxt>5, NULL);
920 /*********************************************************************/
921 /**** Individual record ****/
922 /*********************************************************************/
923 indiv_rec : OPEN DELIM POINTER DELIM TAG_INDI
924 { $<ctxt>$ = start_record(REC_INDI, $1, $3, $5);
925 START(INDI, $<ctxt>$) }
929 { end_record(REC_INDI, $<ctxt>6); }
932 indi_subs : /* empty */
936 indi_sub : indi_resn_sect { OCCUR2(RESN, 0, 1) }
937 | pers_name_struc_sub /* 0:M */
938 | indi_sex_sect { OCCUR2(SEX, 0, 1) }
939 | indiv_even_struc_sub /* 0:M */
940 | indiv_attr_struc_sub /* 0:M */
941 | lds_indiv_ord_sub /* 0:M */
942 | chi_fam_link_sub /* 0:M */
943 | spou_fam_link_sub /* 0:M */
944 | indi_subm_sect /* 0:M */
945 | assoc_struc_sub /* 0:M */
946 | indi_alia_sect /* 0:M */
947 | indi_anci_sect /* 0:M */
948 | indi_desi_sect /* 0:M */
949 | source_cit_sub /* 0:M */
950 | multim_link_sub /* 0:M */
951 | note_struc_sub /* 0:M */
952 | indi_rfn_sect { OCCUR2(RFN, 0, 1) }
953 | indi_afn_sect /* 0:M */
954 | ident_struc_sub /* 0:1 */
955 | change_date_sub /* 0:1 */
956 | ftree_addr_sect { if (!compat_mode(C_FTREE))
963 indi_resn_sect : OPEN DELIM TAG_RESN mand_line_item
964 { $<ctxt>$ = start_element(ELT_INDI_RESN,
965 PARENT, $1, $3, $4, $4);
966 START(RESN, $<ctxt>$)
971 { end_element(ELT_INDI_RESN, PARENT, $<ctxt>5, NULL);
976 indi_sex_sect : OPEN DELIM TAG_SEX mand_line_item
977 { $<ctxt>$ = start_element(ELT_INDI_SEX,
978 PARENT, $1, $3, $4, $4);
984 { end_element(ELT_INDI_SEX, PARENT, $<ctxt>5, NULL);
989 indi_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
990 { $<ctxt>$ = start_element(ELT_INDI_SUBM,
991 PARENT, $1, $3, $4, $4);
992 START(SUBM, $<ctxt>$)
997 { end_element(ELT_INDI_SUBM, PARENT, $<ctxt>5, NULL);
1002 indi_alia_sect : OPEN DELIM TAG_ALIA mand_pointer
1003 { $<ctxt>$ = start_element(ELT_INDI_ALIA,
1004 PARENT, $1, $3, $4, $4);
1005 START(ALIA, $<ctxt>$)
1010 { end_element(ELT_INDI_ALIA, PARENT, $<ctxt>5, NULL);
1015 indi_anci_sect : OPEN DELIM TAG_ANCI mand_pointer
1016 { $<ctxt>$ = start_element(ELT_INDI_ANCI,
1017 PARENT, $1, $3, $4, $4);
1018 START(ANCI, $<ctxt>$)
1023 { end_element(ELT_INDI_ANCI, PARENT, $<ctxt>5, NULL);
1028 indi_desi_sect : OPEN DELIM TAG_DESI mand_pointer
1029 { $<ctxt>$ = start_element(ELT_INDI_DESI,
1030 PARENT, $1, $3, $4, $4);
1031 START(DESI, $<ctxt>$)
1036 { end_element(ELT_INDI_DESI, PARENT, $<ctxt>5, NULL);
1041 indi_rfn_sect : OPEN DELIM TAG_RFN mand_line_item
1042 { $<ctxt>$ = start_element(ELT_INDI_RFN,
1043 PARENT, $1, $3, $4, $4);
1044 START(RFN, $<ctxt>$)
1049 { end_element(ELT_INDI_RFN, PARENT, $<ctxt>5, NULL);
1054 indi_afn_sect : OPEN DELIM TAG_AFN mand_line_item
1055 { $<ctxt>$ = start_element(ELT_INDI_AFN,
1056 PARENT, $1, $3, $4, $4);
1057 START(AFN, $<ctxt>$)
1062 { end_element(ELT_INDI_AFN, PARENT, $<ctxt>5, NULL);
1066 /* INDI.ADDR (Only for 'ftree' compatibility) */
1067 ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
1068 { START(ADDR, NULL) } no_std_subs { CHECK0 } CLOSE { }
1070 /*********************************************************************/
1071 /**** Multimedia record ****/
1072 /*********************************************************************/
1073 multim_rec : OPEN DELIM POINTER DELIM TAG_OBJE
1074 { $<ctxt>$ = start_record(REC_OBJE, $1, $3, $5);
1075 START(OBJE, $<ctxt>$) }
1077 { CHECK2(FORM, BLOB) }
1079 { end_record(REC_OBJE, $<ctxt>6); }
1082 obje_subs : /* empty */
1083 | obje_subs obje_sub
1086 obje_sub : obje_form_sect { OCCUR2(FORM, 1, 1) }
1087 | obje_titl_sect { OCCUR2(TITL, 0, 1) }
1088 | note_struc_sub /* 0:M */
1089 | obje_blob_sect { OCCUR2(BLOB, 1, 1) }
1090 | obje_obje_sect { OCCUR2(OBJE, 0, 1) }
1091 | ident_struc_sub /* 0:1 */
1092 | change_date_sub /* 0:1 */
1097 obje_form_sect : OPEN DELIM TAG_FORM mand_line_item
1098 { $<ctxt>$ = start_element(ELT_OBJE_FORM,
1099 PARENT, $1, $3, $4, $4);
1100 START(FORM, $<ctxt>$)
1105 { end_element(ELT_OBJE_FORM, PARENT, $<ctxt>5, NULL);
1110 obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item
1111 { $<ctxt>$ = start_element(ELT_OBJE_TITL,
1112 PARENT, $1, $3, $4, $4);
1113 START(TITL, $<ctxt>$)
1118 { end_element(ELT_OBJE_TITL, PARENT, $<ctxt>5, NULL);
1123 obje_blob_sect : OPEN DELIM TAG_BLOB
1124 { $<ctxt>$ = start_element(ELT_OBJE_BLOB,
1125 PARENT, $1, $3, NULL, NULL);
1126 START(BLOB, $<ctxt>$)
1131 { end_element(ELT_OBJE_BLOB, PARENT, $<ctxt>4, NULL);
1135 obje_blob_subs : /* empty */
1136 | obje_blob_subs obje_blob_sub
1139 obje_blob_sub : obje_blob_cont_sect { OCCUR1(CONT, 1) }
1143 obje_blob_cont_sect : OPEN DELIM TAG_CONT mand_line_item
1144 { $<ctxt>$ = start_element(ELT_OBJE_BLOB_CONT,
1145 PARENT, $1, $3, $4, $4);
1146 START(CONT, $<ctxt>$)
1151 { end_element(ELT_OBJE_BLOB_CONT, PARENT,
1157 obje_obje_sect : OPEN DELIM TAG_OBJE mand_pointer
1158 { $<ctxt>$ = start_element(ELT_OBJE_OBJE,
1159 PARENT, $1, $3, $4, $4);
1160 START(OBJE, $<ctxt>$)
1165 { end_element(ELT_OBJE_OBJE, PARENT, $<ctxt>5, NULL);
1169 /*********************************************************************/
1170 /**** Note record ****/
1171 /*********************************************************************/
1172 note_rec : OPEN DELIM POINTER DELIM TAG_NOTE note_line_item
1173 { $<ctxt>$ = start_record(REC_NOTE, $1, $3, $5);
1174 START(NOTE, $<ctxt>$) }
1178 { end_record(REC_NOTE, $<ctxt>6); }
1181 note_line_item : /* empty */
1182 { if (!compat_mode(C_FTREE)) {
1183 gedcom_error(_("Missing value")); YYERROR;
1187 { gedcom_debug_print("==Val: %s==", $2);
1191 note_subs : /* empty */
1192 | note_subs note_sub
1195 note_sub : continuation_sub /* 0:M */
1196 | source_cit_sub /* 0:M */
1197 | ident_struc_sub /* 0:1 */
1198 | change_date_sub /* 0:1 */
1202 /*********************************************************************/
1203 /**** Repository record ****/
1204 /*********************************************************************/
1205 repos_rec : OPEN DELIM POINTER DELIM TAG_REPO
1206 { $<ctxt>$ = start_record(REC_REPO, $1, $3, $5);
1207 START(REPO, $<ctxt>$) }
1211 { end_record(REC_REPO, $<ctxt>6); }
1214 repo_subs : /* empty */
1215 | repo_subs repo_sub
1218 repo_sub : repo_name_sect { OCCUR2(NAME, 0, 1) }
1219 | addr_struc_sub /* 0:1 */
1220 | note_struc_sub /* 0:M */
1221 | ident_struc_sub /* 0:1 */
1222 | change_date_sub /* 0:1 */
1227 repo_name_sect : OPEN DELIM TAG_NAME mand_line_item
1228 { $<ctxt>$ = start_element(ELT_REPO_NAME,
1229 PARENT, $1, $3, $4, $4);
1230 START(NAME, $<ctxt>$)
1235 { end_element(ELT_REPO_NAME, PARENT, $<ctxt>5, NULL);
1239 /*********************************************************************/
1240 /**** Source record ****/
1241 /*********************************************************************/
1242 source_rec : OPEN DELIM POINTER DELIM TAG_SOUR
1243 { $<ctxt>$ = start_record(REC_SOUR, $1, $3, $5);
1244 START(SOUR, $<ctxt>$) }
1248 { end_record(REC_SOUR, $<ctxt>6); }
1251 sour_subs : /* empty */
1252 | sour_subs sour_sub
1255 sour_sub : sour_data_sect { OCCUR2(DATA, 0, 1) }
1256 | sour_auth_sect { OCCUR2(AUTH, 0, 1) }
1257 | sour_titl_sect { OCCUR2(TITL, 0, 1) }
1258 | sour_abbr_sect { OCCUR2(ABBR, 0, 1) }
1259 | sour_publ_sect { OCCUR2(PUBL, 0, 1) }
1260 | sour_text_sect { OCCUR2(TEXT, 0, 1) }
1261 | source_repos_cit_sub /* 0:1 */
1262 | multim_link_sub /* 0:M */
1263 | note_struc_sub /* 0:M */
1264 | ident_struc_sub /* 0:1 */
1265 | change_date_sub /* 0:1 */
1270 sour_data_sect : OPEN DELIM TAG_DATA
1271 { START(DATA, NULL) }
1277 sour_data_subs : /* empty */
1278 | sour_data_subs sour_data_sub
1281 sour_data_sub : sour_data_even_sect /* 0:M */
1282 | sour_data_agnc_sect { OCCUR2(AGNC, 0, 1) }
1283 | note_struc_sub /* 0:M */
1287 sour_data_even_sect : OPEN DELIM TAG_EVEN mand_line_item
1288 { START(EVEN, NULL) }
1294 sour_data_even_subs : /* empty */
1295 | sour_data_even_subs sour_data_even_sub
1298 sour_data_even_sub : sour_data_even_date_sect { OCCUR2(DATE, 0, 1) }
1299 | sour_data_even_plac_sect { OCCUR2(PLAC, 0, 1) }
1303 sour_data_even_date_sect : OPEN DELIM TAG_DATE mand_line_item
1304 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1307 sour_data_even_plac_sect : OPEN DELIM TAG_PLAC mand_line_item
1308 { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1311 sour_data_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item
1312 { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1316 sour_auth_sect : OPEN DELIM TAG_AUTH mand_line_item
1317 { START(AUTH, NULL) }
1323 sour_auth_subs : /* empty */
1324 | sour_auth_subs sour_auth_sub
1327 sour_auth_sub : continuation_sub /* 0:M */
1332 sour_titl_sect : OPEN DELIM TAG_TITL mand_line_item
1333 { START(TITL, NULL) }
1339 sour_titl_subs : /* empty */
1340 | sour_titl_subs sour_titl_sub
1343 sour_titl_sub : continuation_sub /* 0:M */
1348 sour_abbr_sect : OPEN DELIM TAG_ABBR mand_line_item
1349 { START(ABBR, NULL) } no_std_subs { CHECK0 } CLOSE { }
1353 sour_publ_sect : OPEN DELIM TAG_PUBL mand_line_item
1354 { START(PUBL, NULL) }
1360 sour_publ_subs : /* empty */
1361 | sour_publ_subs sour_publ_sub
1364 sour_publ_sub : continuation_sub /* 0:M */
1369 sour_text_sect : OPEN DELIM TAG_TEXT mand_line_item
1370 { START(TEXT, NULL) }
1376 sour_text_subs : /* empty */
1377 | sour_text_subs sour_text_sub
1380 sour_text_sub : continuation_sub /* 0:M */
1384 /*********************************************************************/
1385 /**** Submission record ****/
1386 /*********************************************************************/
1387 submis_rec : OPEN DELIM POINTER DELIM TAG_SUBN
1388 { $<ctxt>$ = start_record(REC_SUBN, $1, $3, $5);
1389 START(SUBN, $<ctxt>$) }
1393 { end_record(REC_SUBN, $<ctxt>6); }
1396 subn_subs : /* empty */
1397 | subn_subs subn_sub
1400 subn_sub : subn_subm_sect { OCCUR2(SUBM, 0, 1) }
1401 | subn_famf_sect { OCCUR2(FAMF, 0, 1) }
1402 | subn_temp_sect { OCCUR2(TEMP, 0, 1) }
1403 | subn_ance_sect { OCCUR2(ANCE, 0, 1) }
1404 | subn_desc_sect { OCCUR2(DESC, 0, 1) }
1405 | subn_ordi_sect { OCCUR2(ORDI, 0, 1) }
1406 | subn_rin_sect { OCCUR2(RIN, 0, 1) }
1411 subn_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
1412 { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1416 subn_famf_sect : OPEN DELIM TAG_FAMF mand_line_item
1417 { START(FAMF, NULL) } no_std_subs { CHECK0 } CLOSE { }
1421 subn_temp_sect : OPEN DELIM TAG_TEMP mand_line_item
1422 { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1426 subn_ance_sect : OPEN DELIM TAG_ANCE mand_line_item
1427 { START(ANCE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1431 subn_desc_sect : OPEN DELIM TAG_DESC mand_line_item
1432 { START(DESC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1436 subn_ordi_sect : OPEN DELIM TAG_ORDI mand_line_item
1437 { START(ORDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1441 subn_rin_sect : OPEN DELIM TAG_RIN mand_line_item
1442 { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1445 /*********************************************************************/
1446 /**** Submitter record ****/
1447 /*********************************************************************/
1448 submit_rec : OPEN DELIM POINTER DELIM TAG_SUBM
1449 { $<ctxt>$ = start_record(REC_SUBM, $1, $3, $5);
1450 START(SUBM, $<ctxt>$) }
1454 { end_record(REC_SUBM, $<ctxt>6); }
1457 subm_subs : /* empty */
1458 | subm_subs subm_sub
1461 subm_sub : subm_name_sect { OCCUR2(NAME, 0, 1) }
1462 | addr_struc_sub /* 0:1 */
1463 | multim_link_sub /* 0:M */
1464 | subm_lang_sect { OCCUR2(LANG, 0, 3) }
1465 | subm_rfn_sect { OCCUR2(RFN, 0, 1) }
1466 | subm_rin_sect { OCCUR2(RIN, 0, 1) }
1467 | change_date_sub /* 0:1 */
1472 subm_name_sect : OPEN DELIM TAG_NAME mand_line_item
1473 { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1477 subm_lang_sect : OPEN DELIM TAG_LANG mand_line_item
1478 { START(LANG, NULL) } no_std_subs { CHECK0 } CLOSE { }
1482 subm_rfn_sect : OPEN DELIM TAG_RFN mand_line_item
1483 { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1487 subm_rin_sect : OPEN DELIM TAG_RIN mand_line_item
1488 { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1491 /*********************************************************************/
1492 /**** Substructures ****/
1493 /*********************************************************************/
1495 /* ADDRESS STRUCTURE */
1496 addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) }
1497 | phon_sect { OCCUR2(PHON, 0, 3) }
1500 addr_sect : OPEN DELIM TAG_ADDR mand_line_item
1501 { START(ADDR, NULL) }
1507 addr_subs : /* empty */
1508 | addr_subs addr_sub
1511 addr_sub : addr_cont_sect /* 0:M */
1512 | addr_adr1_sect { OCCUR2(ADR1, 0, 1) }
1513 | addr_adr2_sect { OCCUR2(ADR2, 0, 1) }
1514 | addr_city_sect { OCCUR2(CITY, 0, 1) }
1515 | addr_stae_sect { OCCUR2(STAE, 0, 1) }
1516 | addr_post_sect { OCCUR2(POST, 0, 1) }
1517 | addr_ctry_sect { OCCUR2(CTRY, 0, 1) }
1521 addr_cont_sect : OPEN DELIM TAG_CONT mand_line_item
1522 { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1524 addr_adr1_sect : OPEN DELIM TAG_ADR1 mand_line_item
1525 { START(ADR1, NULL) } no_std_subs { CHECK0 } CLOSE { }
1527 addr_adr2_sect : OPEN DELIM TAG_ADR2 mand_line_item
1528 { START(ADR2, NULL) } no_std_subs { CHECK0 } CLOSE { }
1530 addr_city_sect : OPEN DELIM TAG_CITY mand_line_item
1531 { START(CITY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1533 addr_stae_sect : OPEN DELIM TAG_STAE mand_line_item
1534 { START(STAE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1536 addr_post_sect : OPEN DELIM TAG_POST mand_line_item
1537 { START(POST, NULL) } no_std_subs { CHECK0 } CLOSE { }
1539 addr_ctry_sect : OPEN DELIM TAG_CTRY mand_line_item
1540 { START(CTRY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1543 phon_sect : OPEN DELIM TAG_PHON mand_line_item
1544 { START(PHON, NULL) } no_std_subs { CHECK0 } CLOSE { }
1547 /* ASSOCIATION STRUCTURE */
1548 assoc_struc_sub : asso_sect /* 0:M */
1551 asso_sect : OPEN DELIM TAG_ASSO mand_pointer
1552 { START(ASSO, NULL) }
1554 { CHECK2(TYPE,RELA) }
1558 asso_subs : /* empty */
1559 | asso_type_sect { OCCUR2(TYPE, 1, 1) }
1560 | asso_rela_sect { OCCUR2(RELA, 1, 1) }
1566 asso_type_sect : OPEN DELIM TAG_TYPE mand_line_item
1567 { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1570 asso_rela_sect : OPEN DELIM TAG_RELA mand_line_item
1571 { START(RELA, NULL) } no_std_subs { CHECK0 } CLOSE { }
1575 change_date_sub : change_date_chan_sect { OCCUR2(CHAN, 0, 1) }
1578 change_date_chan_sect : OPEN DELIM TAG_CHAN
1579 { START(CHAN, NULL) }
1580 change_date_chan_subs
1585 change_date_chan_subs : /* empty */
1586 | change_date_chan_subs change_date_chan_sub
1589 change_date_chan_sub : change_date_date_sect { OCCUR2(DATE, 1, 1) }
1594 change_date_date_sect : OPEN DELIM TAG_DATE mand_line_item
1595 { START(DATE, NULL) }
1596 change_date_date_subs
1601 change_date_date_subs : /* empty */
1602 | change_date_date_subs change_date_date_sub
1605 change_date_date_sub : change_date_date_time_sect { OCCUR2(TIME, 0, 1) }
1609 change_date_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
1610 { START(TIME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1613 /* CHILD TO FAMILY LINK */
1614 chi_fam_link_sub : famc_sect /* 0:M */
1617 famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1618 { START(FAMC, NULL) }
1624 famc_subs : /* empty */
1625 | famc_subs famc_sub
1628 famc_sub : famc_pedi_sect /* 0:M */
1633 famc_pedi_sect : OPEN DELIM TAG_PEDI mand_line_item
1634 { START(PEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1637 /* CONTINUATION SUBSECTIONS */
1638 continuation_sub : cont_sect /* 0:M */
1639 | conc_sect /* 0:M */
1642 cont_sect : OPEN DELIM TAG_CONT mand_line_item
1643 { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1646 conc_sect : OPEN DELIM TAG_CONC mand_line_item
1647 { START(CONC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1651 event_detail_sub : event_detail_type_sect { OCCUR2(TYPE, 0, 1) }
1652 | event_detail_date_sect { OCCUR2(DATE, 0, 1) }
1655 | event_detail_age_sect { OCCUR2(AGE, 0, 1) }
1656 | event_detail_agnc_sect { OCCUR2(AGNC, 0, 1) }
1657 | event_detail_caus_sect { OCCUR2(CAUS, 0, 1) }
1663 event_detail_type_sect : OPEN DELIM TAG_TYPE mand_line_item
1664 { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1666 event_detail_date_sect : OPEN DELIM TAG_DATE mand_line_item
1667 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1669 event_detail_age_sect : OPEN DELIM TAG_AGE mand_line_item
1670 { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1672 event_detail_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item
1673 { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1675 event_detail_caus_sect : OPEN DELIM TAG_CAUS mand_line_item
1676 { START(CAUS, NULL) } no_std_subs { CHECK0 } CLOSE { }
1679 /* FAMILY EVENT STRUCTURE */
1680 fam_event_struc_sub : fam_event_sect
1681 | fam_gen_even_sect /* 0:M */
1684 fam_event_sect : OPEN DELIM fam_event_tag opt_value fam_event_subs
1689 fam_event_tag : TAG_ANUL { START(ANUL, NULL) }
1690 | TAG_CENS { START(CENS, NULL) }
1691 | TAG_DIV { START(DIV, NULL) }
1692 | TAG_DIVF { START(DIVF, NULL) }
1693 | TAG_ENGA { START(ENGA, NULL) }
1694 | TAG_MARR { START(MARR, NULL) }
1695 | TAG_MARB { START(MARB, NULL) }
1696 | TAG_MARC { START(MARC, NULL) }
1697 | TAG_MARL { START(MARL, NULL) }
1698 | TAG_MARS { START(MARS, NULL) }
1701 fam_event_subs : /* empty */
1702 | fam_event_subs fam_event_sub
1705 fam_event_sub : event_detail_sub
1706 | fam_even_husb_sect { OCCUR2(HUSB, 0, 1) }
1707 | fam_even_wife_sect { OCCUR2(WIFE, 0, 1) }
1711 fam_even_husb_sect : OPEN DELIM TAG_HUSB
1712 { START(HUSB, NULL) }
1718 fam_even_husb_subs : /* empty */
1719 | fam_even_husb_subs fam_even_husb_sub
1722 fam_even_husb_sub : fam_even_husb_age_sect { OCCUR2(AGE, 1, 1) }
1726 fam_even_husb_age_sect : OPEN DELIM TAG_AGE mand_line_item
1727 { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1730 fam_even_wife_sect : OPEN DELIM TAG_WIFE
1731 { START(HUSB, NULL) }
1737 fam_gen_even_sect : OPEN DELIM TAG_EVEN
1738 { START(EVEN, NULL) }
1744 fam_gen_even_subs : /* empty */
1745 | fam_gen_even_subs fam_gen_even_sub
1748 fam_gen_even_sub : event_detail_sub
1749 | fam_even_husb_sect { OCCUR2(HUSB, 0, 1) }
1750 | fam_even_wife_sect { OCCUR2(WIFE, 0, 1) }
1754 /* IDENTIFICATION STRUCTURE */
1755 ident_struc_sub : ident_refn_sect /* 0:M */
1756 | ident_rin_sect { OCCUR2(RIN, 0, 1) }
1759 ident_refn_sect : OPEN DELIM TAG_REFN mand_line_item
1760 { START(REFN, NULL) }
1766 ident_refn_subs : /* empty */
1767 | ident_refn_subs ident_refn_sub
1770 ident_refn_sub : ident_refn_type_sect { OCCUR2(TYPE, 0, 1) }
1774 ident_refn_type_sect : OPEN DELIM TAG_TYPE mand_line_item
1775 { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1778 ident_rin_sect : OPEN DELIM TAG_RIN mand_line_item
1779 { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1782 /* INDIVIDUAL ATTRIBUTE STRUCTURE */
1783 indiv_attr_struc_sub : indiv_cast_sect /* 0:M */
1784 | indiv_dscr_sect /* 0:M */
1785 | indiv_educ_sect /* 0:M */
1786 | indiv_idno_sect /* 0:M */
1787 | indiv_nati_sect /* 0:M */
1788 | indiv_nchi_sect /* 0:M */
1789 | indiv_nmr_sect /* 0:M */
1790 | indiv_occu_sect /* 0:M */
1791 | indiv_prop_sect /* 0:M */
1792 | indiv_reli_sect /* 0:M */
1793 | indiv_resi_sect /* 0:M */
1794 | indiv_ssn_sect /* 0:M */
1795 | indiv_titl_sect /* 0:M */
1798 indiv_cast_sect : OPEN DELIM TAG_CAST mand_line_item
1799 { START(CAST, NULL) }
1800 indiv_attr_event_subs
1804 indiv_dscr_sect : OPEN DELIM TAG_DSCR mand_line_item
1805 { START(DSCR, NULL) }
1806 indiv_attr_event_subs
1810 indiv_educ_sect : OPEN DELIM TAG_EDUC mand_line_item
1811 { START(EDUC, NULL) }
1812 indiv_attr_event_subs
1816 indiv_idno_sect : OPEN DELIM TAG_IDNO mand_line_item
1817 { START(IDNO, NULL) }
1818 indiv_attr_event_subs
1822 indiv_nati_sect : OPEN DELIM TAG_NATI mand_line_item
1823 { START(NATI, NULL) }
1824 indiv_attr_event_subs
1828 indiv_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item
1829 { START(NCHI, NULL) }
1830 indiv_attr_event_subs
1834 indiv_nmr_sect : OPEN DELIM TAG_NMR mand_line_item
1835 { START(NMR, NULL) }
1836 indiv_attr_event_subs
1840 indiv_occu_sect : OPEN DELIM TAG_OCCU mand_line_item
1841 { START(OCCU, NULL) }
1842 indiv_attr_event_subs
1846 indiv_prop_sect : OPEN DELIM TAG_PROP mand_line_item
1847 { START(PROP, NULL) }
1848 indiv_attr_event_subs
1852 indiv_reli_sect : OPEN DELIM TAG_RELI mand_line_item
1853 { START(RELI, NULL) }
1854 indiv_attr_event_subs
1858 indiv_resi_sect : OPEN DELIM TAG_RESI
1859 { START(RESI, NULL) }
1860 indiv_attr_event_subs
1864 indiv_ssn_sect : OPEN DELIM TAG_SSN mand_line_item
1865 { START(SSN, NULL) }
1866 indiv_attr_event_subs
1870 indiv_titl_sect : OPEN DELIM TAG_TITL mand_line_item
1871 { START(TITL, NULL) }
1872 indiv_attr_event_subs
1877 indiv_attr_event_subs : /* empty */
1878 | indiv_attr_event_subs indiv_attr_event_sub
1881 indiv_attr_event_sub : event_detail_sub
1885 /* INDIVIDUAL EVENT STRUCTURE */
1886 indiv_even_struc_sub : indiv_birt_sect
1888 | indiv_adop_sect /* 0:M */
1889 | indiv_even_sect /* 0:M */
1892 indiv_birt_sect : OPEN DELIM indiv_birt_tag opt_value indiv_birt_subs
1897 indiv_birt_tag : TAG_BIRT { START(BIRT, NULL) }
1898 | TAG_CHR { START(CHR, NULL) }
1901 indiv_birt_subs : /* empty */
1902 | indiv_birt_subs indiv_birt_sub
1905 indiv_birt_sub : event_detail_sub
1906 | indiv_birt_famc_sect { OCCUR2(FAMC,0, 1) }
1910 indiv_birt_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1911 { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1914 indiv_gen_sect : OPEN DELIM indiv_gen_tag opt_value indiv_gen_subs
1919 indiv_gen_tag : TAG_DEAT { START(DEAT, NULL) }
1920 | TAG_BURI { START(BURI, NULL) }
1921 | TAG_CREM { START(CREM, NULL) }
1922 | TAG_BAPM { START(BAPM, NULL) }
1923 | TAG_BARM { START(BARM, NULL) }
1924 | TAG_BASM { START(BASM, NULL) }
1925 | TAG_BLES { START(BLES, NULL) }
1926 | TAG_CHRA { START(CHRA, NULL) }
1927 | TAG_CONF { START(CONF, NULL) }
1928 | TAG_FCOM { START(FCOM, NULL) }
1929 | TAG_ORDN { START(ORDN, NULL) }
1930 | TAG_NATU { START(NATU, NULL) }
1931 | TAG_EMIG { START(EMIG, NULL) }
1932 | TAG_IMMI { START(IMMI, NULL) }
1933 | TAG_CENS { START(CENS, NULL) }
1934 | TAG_PROB { START(PROB, NULL) }
1935 | TAG_WILL { START(WILL, NULL) }
1936 | TAG_GRAD { START(GRAD, NULL) }
1937 | TAG_RETI { START(RETI, NULL) }
1940 indiv_gen_subs : /* empty */
1941 | indiv_gen_subs indiv_gen_sub
1944 indiv_gen_sub : event_detail_sub
1948 indiv_adop_sect : OPEN DELIM TAG_ADOP opt_value
1949 { START(ADOP, NULL) }
1955 indiv_adop_subs : /* empty */
1956 | indiv_adop_subs indiv_adop_sub
1959 indiv_adop_sub : event_detail_sub
1960 | indiv_adop_famc_sect { OCCUR2(FAMC,0, 1) }
1964 indiv_adop_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1965 { START(FAMC, NULL) }
1966 indiv_adop_famc_subs
1971 indiv_adop_famc_subs : /* empty */
1972 | indiv_adop_famc_subs indiv_adop_famc_sub
1975 indiv_adop_famc_sub : indiv_adop_famc_adop_sect { OCCUR2(ADOP,0, 1) }
1979 indiv_adop_famc_adop_sect : OPEN DELIM TAG_ADOP mand_line_item
1980 { START(ADOP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1983 indiv_even_sect : OPEN DELIM TAG_EVEN
1984 { START(EVEN, NULL) }
1990 /* LDS INDIVIDUAL ORDINANCE */
1991 lds_indiv_ord_sub : lio_bapl_sect /* 0:M */
1992 | lio_slgc_sect /* 0:M */
1995 lio_bapl_sect : OPEN DELIM lio_bapl_tag lio_bapl_subs
2000 lio_bapl_tag : TAG_BAPL { START(BAPL, NULL) }
2001 | TAG_CONL { START(CONL, NULL) }
2002 | TAG_ENDL { START(ENDL, NULL) }
2005 lio_bapl_subs : /* empty */
2006 | lio_bapl_subs lio_bapl_sub
2009 lio_bapl_sub : lio_bapl_stat_sect { OCCUR2(STAT, 0, 1) }
2010 | lio_bapl_date_sect { OCCUR2(DATE, 0, 1) }
2011 | lio_bapl_temp_sect { OCCUR2(TEMP, 0, 1) }
2012 | lio_bapl_plac_sect { OCCUR2(PLAC, 0, 1) }
2018 lio_bapl_stat_sect : OPEN DELIM TAG_STAT mand_line_item
2019 { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
2021 lio_bapl_date_sect : OPEN DELIM TAG_DATE mand_line_item
2022 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2024 lio_bapl_temp_sect : OPEN DELIM TAG_TEMP mand_line_item
2025 { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
2027 lio_bapl_plac_sect : OPEN DELIM TAG_PLAC mand_line_item
2028 { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
2031 lio_slgc_sect : OPEN DELIM TAG_SLGC
2032 { START(SLGC, NULL) }
2038 lio_slgc_subs : /* empty */
2039 | lio_slgc_subs lio_slgc_sub
2042 lio_slgc_sub : lio_bapl_sub
2043 | lio_slgc_famc_sect { OCCUR2(FAMC, 1, 1) }
2046 lio_slgc_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
2047 { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
2050 /* LDS SPOUSE SEALING */
2051 lds_spouse_seal_sub : lss_slgs_sect
2054 lss_slgs_sect : OPEN DELIM TAG_SLGS
2055 { START(SLGS, NULL) }
2061 lss_slgs_subs : /* empty */
2062 | lss_slgs_subs lss_slgs_sub
2065 lss_slgs_sub : lss_slgs_stat_sect { OCCUR2(STAT, 0, 1) }
2066 | lss_slgs_date_sect { OCCUR2(DATE, 0, 1) }
2067 | lss_slgs_temp_sect { OCCUR2(TEMP, 0, 1) }
2068 | lss_slgs_plac_sect { OCCUR2(PLAC, 0, 1) }
2074 lss_slgs_stat_sect : OPEN DELIM TAG_STAT mand_line_item
2075 { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
2077 lss_slgs_date_sect : OPEN DELIM TAG_DATE mand_line_item
2078 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2080 lss_slgs_temp_sect : OPEN DELIM TAG_TEMP mand_line_item
2081 { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
2083 lss_slgs_plac_sect : OPEN DELIM TAG_PLAC mand_line_item
2084 { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
2087 /* MULTIMEDIA LINK */
2088 multim_link_sub : multim_obje_link_sect
2089 | multim_obje_emb_sect
2092 multim_obje_link_sect : OPEN DELIM TAG_OBJE DELIM POINTER
2093 { START(OBJE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2096 multim_obje_emb_sect : OPEN DELIM TAG_OBJE
2097 { START(OBJE, NULL) }
2098 multim_obje_emb_subs
2099 { CHECK2(FORM,FILE) }
2103 multim_obje_emb_subs : /* empty */
2104 | multim_obje_emb_subs multim_obje_emb_sub
2107 multim_obje_emb_sub : multim_obje_form_sect { OCCUR2(FORM, 1, 1) }
2108 | multim_obje_titl_sect { OCCUR2(TITL, 0, 1) }
2109 | multim_obje_file_sect { OCCUR2(FILE, 1, 1) }
2114 multim_obje_form_sect : OPEN DELIM TAG_FORM mand_line_item
2115 { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
2117 multim_obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item
2118 { START(TITL, NULL) } no_std_subs { CHECK0 } CLOSE { }
2120 multim_obje_file_sect : OPEN DELIM TAG_FILE mand_line_item
2121 { START(FILE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2124 /* NOTE STRUCTURE */
2125 note_struc_sub : note_struc_link_sect /* 0:M */
2126 | note_struc_emb_sect /* 0:M */
2129 note_struc_link_sect : OPEN DELIM TAG_NOTE DELIM POINTER
2130 { START(NOTE, NULL) }
2131 note_struc_link_subs
2136 note_struc_link_subs : /* empty */
2137 | note_struc_link_subs note_struc_link_sub
2140 note_struc_link_sub : source_cit_sub
2144 note_struc_emb_sect : OPEN DELIM TAG_NOTE opt_line_item
2145 { START(NOTE, NULL) }
2151 note_struc_emb_subs : /* empty */
2152 | note_struc_emb_subs note_struc_emb_sub
2155 note_struc_emb_sub : continuation_sub
2160 /* PERSONAL NAME STRUCTURE */
2161 pers_name_struc_sub : pers_name_sect /* 0:M */
2164 pers_name_sect : OPEN DELIM TAG_NAME mand_line_item
2165 { START(NAME, NULL) }
2171 pers_name_subs : /* empty */
2172 | pers_name_subs pers_name_sub
2175 pers_name_sub : pers_name_npfx_sect { OCCUR2(NPFX, 0, 1) }
2176 | pers_name_givn_sect { OCCUR2(GIVN, 0, 1) }
2177 | pers_name_nick_sect { OCCUR2(NICK, 0, 1) }
2178 | pers_name_spfx_sect { OCCUR2(SPFX, 0, 1) }
2179 | pers_name_surn_sect { OCCUR2(SURN, 0, 1) }
2180 | pers_name_nsfx_sect { OCCUR2(NSFX, 0, 1) }
2186 pers_name_npfx_sect : OPEN DELIM TAG_NPFX mand_line_item
2187 { START(NPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2189 pers_name_givn_sect : OPEN DELIM TAG_GIVN mand_line_item
2190 { START(GIVN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2192 pers_name_nick_sect : OPEN DELIM TAG_NICK mand_line_item
2193 { START(NICK, NULL) } no_std_subs { CHECK0 } CLOSE { }
2195 pers_name_spfx_sect : OPEN DELIM TAG_SPFX mand_line_item
2196 { START(SPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2198 pers_name_surn_sect : OPEN DELIM TAG_SURN mand_line_item
2199 { START(SURN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2201 pers_name_nsfx_sect : OPEN DELIM TAG_NSFX mand_line_item
2202 { START(NSFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2205 /* PLACE STRUCTURE */
2206 place_struc_sub : place_struc_plac_sect /* 0:M */
2209 place_struc_plac_sect : OPEN DELIM TAG_PLAC mand_line_item
2210 { START(PLAC, NULL) }
2211 place_struc_plac_subs
2216 place_struc_plac_subs : /* empty */
2217 | place_struc_plac_subs place_struc_plac_sub
2220 place_struc_plac_sub : place_plac_form_sect { OCCUR2(FORM, 0, 1) }
2226 place_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item
2227 { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
2230 /* SOURCE_CITATION */
2231 source_cit_sub : source_cit_link_sect /* 0:M */
2232 | source_cit_emb_sect /* 0:M */
2235 source_cit_link_sect : OPEN DELIM TAG_SOUR DELIM POINTER
2236 { START(SOUR, NULL) }
2237 source_cit_link_subs
2242 source_cit_link_subs : /* empty */
2243 | source_cit_link_subs source_cit_link_sub
2246 source_cit_link_sub : source_cit_page_sect { OCCUR2(PAGE, 0, 1) }
2247 | source_cit_even_sect { OCCUR2(EVEN, 0, 1) }
2248 | source_cit_data_sect { OCCUR2(DATA, 0, 1) }
2249 | source_cit_quay_sect { OCCUR2(QUAY, 0, 1) }
2255 source_cit_page_sect : OPEN DELIM TAG_PAGE mand_line_item
2256 { START(PAGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2259 source_cit_even_sect : OPEN DELIM TAG_EVEN mand_line_item
2260 { START(EVEN, NULL) }
2261 source_cit_even_subs
2266 source_cit_even_subs : /* empty */
2267 | source_cit_even_subs source_cit_even_sub
2270 source_cit_even_sub : source_cit_even_role_sect { OCCUR2(ROLE, 0, 1) }
2274 source_cit_even_role_sect : OPEN DELIM TAG_ROLE mand_line_item
2275 { START(ROLE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2278 source_cit_data_sect : OPEN DELIM TAG_DATA
2279 { START(DATA, NULL) }
2280 source_cit_data_subs
2285 source_cit_data_subs : /* empty */
2286 | source_cit_data_subs source_cit_data_sub
2289 source_cit_data_sub : source_cit_data_date_sect { OCCUR2(DATE, 0, 1) }
2290 | source_cit_text_sect /* 0:M */
2294 source_cit_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
2295 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2298 source_cit_text_sect : OPEN DELIM TAG_TEXT mand_line_item
2299 { START(TEXT, NULL) }
2300 source_cit_text_subs
2305 source_cit_text_subs : /* empty */
2306 | source_cit_text_subs source_cit_text_sub
2309 source_cit_text_sub : continuation_sub
2313 source_cit_quay_sect : OPEN DELIM TAG_QUAY mand_line_item
2314 { START(QUAY, NULL) } no_std_subs { CHECK0 } CLOSE { }
2317 source_cit_emb_sect : OPEN DELIM TAG_SOUR mand_line_item
2318 { START(SOUR, NULL) }
2324 source_cit_emb_subs : /* empty */
2325 | source_cit_emb_subs source_cit_emb_sub
2328 source_cit_emb_sub : continuation_sub
2329 | source_cit_text_sect /* 0:M */
2334 /* SOURCE REPOSITORY CITATION */
2335 source_repos_cit_sub : source_repos_repo_sect { OCCUR2(REPO, 0, 1) }
2338 source_repos_repo_sect : OPEN DELIM TAG_REPO mand_pointer
2339 { START(REPO, NULL) }
2340 source_repos_repo_subs
2345 source_repos_repo_subs : /* empty */
2346 | source_repos_repo_subs source_repos_repo_sub
2349 source_repos_repo_sub : note_struc_sub
2350 | caln_sect /* 0:M */
2354 caln_sect : OPEN DELIM TAG_CALN mand_line_item
2355 { START(CALN, NULL) }
2361 caln_subs : /* empty */
2362 | caln_subs caln_sub
2365 caln_sub : caln_medi_sect { OCCUR2(MEDI, 0, 1) }
2369 caln_medi_sect : OPEN DELIM TAG_MEDI mand_line_item
2370 { START(MEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
2373 /* SPOUSE TO FAMILY LINK */
2374 spou_fam_link_sub : spou_fam_fams_sect /* 0:M */
2377 spou_fam_fams_sect : OPEN DELIM TAG_FAMS mand_pointer
2378 { START(FAMS, NULL) }
2384 spou_fam_fams_subs : /* empty */
2385 | spou_fam_fams_subs spou_fam_fams_sub
2388 spou_fam_fams_sub : note_struc_sub
2392 /*********************************************************************/
2393 /**** Special values ****/
2394 /*********************************************************************/
2396 /*********************************************************************/
2398 /*********************************************************************/
2400 no_std_subs : /* empty */
2401 | no_std_subs no_std_sub
2404 no_std_sub : user_sect /* 0:M */
2406 | error error_subs CLOSE { HANDLE_ERROR }
2409 no_std_rec : user_rec /* 0:M */
2411 | error error_subs CLOSE { HANDLE_ERROR }
2414 user_rec : OPEN DELIM opt_xref USERTAG
2415 { if ($4[0] != '_') {
2416 gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
2422 { $<ctxt>$ = start_record(REC_USER, $1, $3, $4);
2428 { end_record(REC_USER, $<ctxt>7); }
2430 user_sect : OPEN DELIM opt_xref USERTAG
2431 { if ($4[0] != '_') {
2432 gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
2438 { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6, $6);
2439 START($4, $<ctxt>$);
2444 { end_element(ELT_USER, PARENT, $<ctxt>7, NULL);
2448 user_sects : /* empty */ { }
2449 | user_sects user_sect { }
2452 opt_xref : /* empty */ { $$ = NULL; }
2453 | POINTER DELIM { $$ = $1; }
2456 opt_value : /* empty */ { $$ = NULL; }
2457 | DELIM line_value { $$ = $2; }
2460 line_value : POINTER { $$ = $1; }
2461 | line_item { $$ = $1; }
2464 mand_pointer : /* empty */ { gedcom_error(_("Missing pointer")); YYERROR; }
2465 | DELIM POINTER { gedcom_debug_print("==Ptr: %s==", $2);
2469 mand_line_item : /* empty */ { gedcom_error(_("Missing value")); YYERROR; }
2470 | DELIM line_item { gedcom_debug_print("==Val: %s==", $2);
2474 opt_line_item : /* empty */ { }
2475 | DELIM line_item { }
2478 line_item : anychar { size_t i;
2479 CLEAR_BUFFER(line_item_buf);
2480 line_item_buf_ptr = line_item_buf;
2481 /* The following also takes care of '@@' */
2482 if (!strncmp($1, "@@", 3))
2483 *line_item_buf_ptr++ = '@';
2485 for (i=0; i < strlen($1); i++)
2486 *line_item_buf_ptr++ = $1[i];
2489 | ESCAPE { CLEAR_BUFFER(line_item_buf);
2490 line_item_buf_ptr = line_item_buf;
2491 /* For now, ignore escapes */
2496 /* The following also takes care of '@@' */
2497 if (!strncmp($2, "@@", 3))
2498 *line_item_buf_ptr++ = '@';
2500 for (i=0; i < strlen($2); i++)
2501 *line_item_buf_ptr++ = $2[i];
2505 { /* For now, ignore escapes */
2510 anychar : ANYCHAR { }
2514 error_subs : /* empty */
2515 | error_subs error_sect
2518 error_sect : OPEN DELIM opt_xref anytag opt_value error_subs CLOSE { }
2520 gen_sect : OPEN DELIM opt_xref anystdtag
2521 { INVALID_TAG($4); }
2522 opt_value opt_sects CLOSE
2526 gen_rec : gen_rec_top
2530 gen_rec_norm : OPEN DELIM opt_xref anystdtag
2531 { INVALID_TOP_TAG($4) }
2532 opt_value opt_sects CLOSE
2536 gen_rec_top : OPEN DELIM anytoptag
2537 { gedcom_error(_("Missing cross-reference")); YYERROR; }
2538 opt_value opt_sects CLOSE
2542 opt_sects : /* empty */ { }
2543 | opt_sects gen_sect { }
2546 anytag : USERTAG { }
2560 anystdtag : TAG_ABBR
2690 /* Functions that handle the counting of subtags */
2692 int* count_arrays[MAXGEDCLEVEL+1];
2693 char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLEN+1];
2694 Gedcom_ctxt ctxt_stack[MAXGEDCLEVEL+1];
2696 void push_countarray()
2699 if (count_level > MAXGEDCLEVEL) {
2700 gedcom_error(_("Internal error: count array overflow"));
2704 count = (int *)calloc(YYNTOKENS, sizeof(int));
2705 if (count == NULL) {
2706 gedcom_error(_("Internal error: count array calloc error"));
2710 count_arrays[count_level] = count;
2715 void set_parenttag(char* tag)
2717 strncpy(tag_stack[count_level], tag, MAXSTDTAGLEN+1);
2720 void set_parentctxt(Gedcom_ctxt ctxt)
2722 ctxt_stack[count_level] = ctxt;
2725 char* get_parenttag()
2727 return tag_stack[count_level];
2730 Gedcom_ctxt get_parentctxt()
2732 return ctxt_stack[count_level];
2735 int count_tag(int tag)
2737 int *count = count_arrays[count_level];
2738 return ++count[tag - GEDCOMTAGOFFSET];
2741 int check_occurrence(int tag)
2743 int *count = count_arrays[count_level];
2744 return (count[tag - GEDCOMTAGOFFSET] > 0);
2747 void pop_countarray()
2750 if (count_level < 0) {
2751 gedcom_error(_("Internal error: count array underflow"));
2755 count = count_arrays[count_level];
2757 count_arrays[count_level] = NULL;
2761 /* Enabling debug mode */
2762 /* level 0: no debugging */
2763 /* level 1: only internal */
2764 /* level 2: also bison */
2767 void gedcom_set_debug_level(int level, FILE* f)
2772 trace_output = stderr;
2774 gedcom_high_level_debug = 1;
2783 int gedcom_debug_print(char* s, ...)
2786 if (gedcom_high_level_debug) {
2789 res = vfprintf(trace_output, s, ap);
2791 fprintf(trace_output, "\n");
2796 /* Setting the error mechanism */
2797 void gedcom_set_error_handling(Gedcom_err_mech mechanism)
2799 error_mechanism = mechanism;
2802 /* Compatibility handling */
2804 void gedcom_set_compat_handling(int enable_compat)
2806 compat_enabled = enable_compat;
2809 void set_compatibility(char* program)
2811 if (compat_enabled) {
2812 if (! strncmp(program, "ftree", 6)) {
2813 gedcom_warning(_("Enabling compatibility with 'ftree'"));
2814 compatibility = C_FTREE;
2822 int compat_mode(int compat_flags)
2824 return (compat_flags & compatibility);