From: Peter Verthez Date: Thu, 1 Nov 2001 10:25:07 +0000 (+0000) Subject: Initial revision X-Git-Url: https://git.dlugolecki.net.pl/?a=commitdiff_plain;h=be41e74e82065afc92849a2ce5a1c51f69ded908;p=gedcom-parse.git Initial revision --- be41e74e82065afc92849a2ce5a1c51f69ded908 diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..b7476dc --- /dev/null +++ b/ChangeLog @@ -0,0 +1,6 @@ +2001-11-01 Peter Verthez + + * release 0.1 + + * Now covering the entire GEDCOM spec, without error handling. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..737ba42 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +# $Id$ +# $Name$ + +gedcom_parse: standalone.o lex.gedcom_.o gedcom.tab.o + cc standalone.o lex.gedcom_.o gedcom.tab.o -o gedcom_parse + +lex.gedcom_.c: gedcom.lex gedcom.tab.h gedcom.h + flex -8 -Pgedcom_ gedcom.lex + +gedcom.tab.c gedcom.tab.h: gedcom.y gedcom.h + bison --debug --defines --name-prefix=gedcom_ gedcom.y + +clean: + rm -f core gedcom_parse *.o lex.gedcom_.c gedcom.tab.* gedcom.output diff --git a/gedcom.h b/gedcom.h new file mode 100644 index 0000000..621155b --- /dev/null +++ b/gedcom.h @@ -0,0 +1,22 @@ +/* $Id$ */ +/* $Name$ */ +#include +#include +#include + +#define MAXGEDCOMLEVEL 99 +#define MAXSTDTAGLENGTH 4 +#define GEDCOMTAGOFFSET 257 + +/* Error handling mechanisms */ +typedef enum _MECH { + FAIL_PARSE, + IGNORE_RECORD, + IGNORE_LINE +} MECHANISM; + +int gedcom_error(char* s, ...); +void gedcom_enable_debug(); +void gedcom_set_error_handling(MECHANISM mechanism); +int gedcom_parse(); +extern int line_no; diff --git a/gedcom.lex b/gedcom.lex new file mode 100644 index 0000000..76bce78 --- /dev/null +++ b/gedcom.lex @@ -0,0 +1,304 @@ +/* $Id$ */ +/* $Name$ */ + +%{ +#include "gedcom.tab.h" +#include "gedcom.h" +%} + +%s NORMAL +%s EXPECT_TAG + +alpha [A-Za-z_] +digit [0-9] +delim " " +tab [\t] +hash # +literal_at @@ +otherchar [\x21-\x22\x24-\x2F\x3A-\x3F\x5B-\x5E\x60\x7B-\x7E\x80-\xFE] +terminator \x0D|\x0A|\x0D\x0A|\x0A\x0D + +any_char {alpha}|{digit}|{otherchar}|{delim}|{hash}|{literal_at} +any_but_delim {alpha}|{digit}|{otherchar}|{hash}|{literal_at} +non_at {alpha}|{digit}|{otherchar}|{delim}|{hash} +alphanum {alpha}|{digit} +gen_delim {delim}|{tab} + +escape @#{any_char}+@ +pointer @{alphanum}{non_at}+@ + +%{ +int current_level=-1; +int level_diff=MAXGEDCOMLEVEL; +int line_no=1; +%} + +%% + + /* The GEDCOM level number is converted into a sequence of opening + and closing brackets. Simply put, the following GEDCOM fragment: + + 0 HEAD + 1 SOUR genes + 2 VERS 1.6 + 2 NAME Genes + 1 DATE 07 OCT 2001 + ... + 0 TRLR + + is converted into: + + { HEAD (initial) + { SOUR genes (1 higher: no closing brackets) + { VERS 1.6 (1 higher: no closing brackets) + } { NAME Genes (same level: 1 closing bracket) + } } { DATE 07 OCT 2001 (1 lower: 2 closing brackets) + ... + } { TRLR } + + or more clearly: + + { HEAD + { SOUR genes + { VERS 1.6 } + { NAME Genes } } + { DATE 07 OCT 2001 + ... } + { TRLR } + + But because this means that one token is converted into a series + of tokens, there is some initial code following immediately here + that returns "pending" tokens. */ + +%{ +if (level_diff < 1) { + level_diff++; + return CLOSE; +} +else if (level_diff == 1) { + level_diff++; + return OPEN; +} +else { + /* out of brackets... */ +} + +#define MKTAGACTION(tag) { gedcom_lval.string = gedcom_text; \ + BEGIN(NORMAL); \ + return TAG_##tag; } +%} + +{gen_delim}* /* ignore leading whitespace (also tabs) */ + +0{digit}+ { gedcom_error ("Level number with leading zero"); + return BADTOKEN; + } + +{digit}+ { int level = atoi(gedcom_text); + if ((level < 0) || (level > MAXGEDCOMLEVEL)) { + gedcom_error ("Level number out of range [0..%d]", + MAXGEDCOMLEVEL); + return BADTOKEN; + } + level_diff = level - current_level; + BEGIN(EXPECT_TAG); + current_level = level; + if (level_diff < 1) { + level_diff++; + return CLOSE; + } + else if (level_diff == 1) { + level_diff++; + return OPEN; + } + else { + /* should never happen (error to GEDCOM spec) */ + gedcom_error ("GEDCOM level number is %d higher than " + "previous", + level_diff); + return BADTOKEN; + } + } + +ABBR MKTAGACTION(ABBR) +ADDR MKTAGACTION(ADDR) +ADR1 MKTAGACTION(ADR1) +ADR2 MKTAGACTION(ADR2) +ADOP MKTAGACTION(ADOP) +AFN MKTAGACTION(AFN) +AGE MKTAGACTION(AGE) +AGNC MKTAGACTION(AGNC) +ALIA MKTAGACTION(ALIA) +ANCE MKTAGACTION(ANCE) +ANCI MKTAGACTION(ANCI) +ANUL MKTAGACTION(ANUL) +ASSO MKTAGACTION(ASSO) +AUTH MKTAGACTION(AUTH) +BAPL MKTAGACTION(BAPL) +BAPM MKTAGACTION(BAPM) +BARM MKTAGACTION(BARM) +BASM MKTAGACTION(BASM) +BIRT MKTAGACTION(BIRT) +BLES MKTAGACTION(BLES) +BLOB MKTAGACTION(BLOB) +BURI MKTAGACTION(BURI) +CALN MKTAGACTION(CALN) +CAST MKTAGACTION(CAST) +CAUS MKTAGACTION(CAUS) +CENS MKTAGACTION(CENS) +CHAN MKTAGACTION(CHAN) +CHAR MKTAGACTION(CHAR) +CHIL MKTAGACTION(CHIL) +CHR MKTAGACTION(CHR) +CHRA MKTAGACTION(CHRA) +CITY MKTAGACTION(CITY) +CONC MKTAGACTION(CONC) +CONF MKTAGACTION(CONF) +CONL MKTAGACTION(CONL) +CONT MKTAGACTION(CONT) +COPR MKTAGACTION(COPR) +CORP MKTAGACTION(CORP) +CREM MKTAGACTION(CREM) +CTRY MKTAGACTION(CTRY) +DATA MKTAGACTION(DATA) +DATE MKTAGACTION(DATE) +DEAT MKTAGACTION(DEAT) +DESC MKTAGACTION(DESC) +DESI MKTAGACTION(DESI) +DEST MKTAGACTION(DEST) +DIV MKTAGACTION(DIV) +DIVF MKTAGACTION(DIVF) +DSCR MKTAGACTION(DSCR) +EDUC MKTAGACTION(EDUC) +EMIG MKTAGACTION(EMIG) +ENDL MKTAGACTION(ENDL) +ENGA MKTAGACTION(ENGA) +EVEN MKTAGACTION(EVEN) +FAM MKTAGACTION(FAM) +FAMC MKTAGACTION(FAMC) +FAMF MKTAGACTION(FAMF) +FAMS MKTAGACTION(FAMS) +FCOM MKTAGACTION(FCOM) +FILE MKTAGACTION(FILE) +FORM MKTAGACTION(FORM) +GEDC MKTAGACTION(GEDC) +GIVN MKTAGACTION(GIVN) +GRAD MKTAGACTION(GRAD) +HEAD MKTAGACTION(HEAD) +HUSB MKTAGACTION(HUSB) +IDNO MKTAGACTION(IDNO) +IMMI MKTAGACTION(IMMI) +INDI MKTAGACTION(INDI) +LANG MKTAGACTION(LANG) +LEGA MKTAGACTION(LEGA) +MARB MKTAGACTION(MARB) +MARC MKTAGACTION(MARC) +MARL MKTAGACTION(MARL) +MARR MKTAGACTION(MARR) +MARS MKTAGACTION(MARS) +MEDI MKTAGACTION(MEDI) +NAME MKTAGACTION(NAME) +NATI MKTAGACTION(NATI) +NATU MKTAGACTION(NATU) +NCHI MKTAGACTION(NCHI) +NICK MKTAGACTION(NICK) +NMR MKTAGACTION(NMR) +NOTE MKTAGACTION(NOTE) +NPFX MKTAGACTION(NPFX) +NSFX MKTAGACTION(NSFX) +OBJE MKTAGACTION(OBJE) +OCCU MKTAGACTION(OCCU) +ORDI MKTAGACTION(ORDI) +ORDN MKTAGACTION(ORDN) +PAGE MKTAGACTION(PAGE) +PEDI MKTAGACTION(PEDI) +PHON MKTAGACTION(PHON) +PLAC MKTAGACTION(PLAC) +POST MKTAGACTION(POST) +PROB MKTAGACTION(PROB) +PROP MKTAGACTION(PROP) +PUBL MKTAGACTION(PUBL) +QUAY MKTAGACTION(QUAY) +REFN MKTAGACTION(REFN) +RELA MKTAGACTION(RELA) +RELI MKTAGACTION(RELI) +REPO MKTAGACTION(REPO) +RESI MKTAGACTION(RESI) +RESN MKTAGACTION(RESN) +RETI MKTAGACTION(RETI) +RFN MKTAGACTION(RFN) +RIN MKTAGACTION(RIN) +ROLE MKTAGACTION(ROLE) +SEX MKTAGACTION(SEX) +SLGC MKTAGACTION(SLGC) +SLGS MKTAGACTION(SLGS) +SOUR MKTAGACTION(SOUR) +SPFX MKTAGACTION(SPFX) +SSN MKTAGACTION(SSN) +STAE MKTAGACTION(STAE) +STAT MKTAGACTION(STAT) +SUBM MKTAGACTION(SUBM) +SUBN MKTAGACTION(SUBN) +SURN MKTAGACTION(SURN) +TEMP MKTAGACTION(TEMP) +TEXT MKTAGACTION(TEXT) +TIME MKTAGACTION(TIME) +TITL MKTAGACTION(TITL) +TRLR MKTAGACTION(TRLR) +TYPE MKTAGACTION(TYPE) +VERS MKTAGACTION(VERS) +WIFE MKTAGACTION(WIFE) +WILL MKTAGACTION(WILL) + +{alphanum}+ { gedcom_lval.string = gedcom_text; + BEGIN(NORMAL); + return USERTAG; + } + +{delim} { gedcom_lval.string = gedcom_text; + return DELIM; + } + +{any_but_delim} { gedcom_lval.string = gedcom_text; + return ANYCHAR; + } + +{escape}/{non_at} { gedcom_lval.string = gedcom_text; + return ESCAPE; + } + +{pointer} { gedcom_lval.string = gedcom_text; + return POINTER; + } + + /* Due to the conversion of level numbers into brackets, the + terminator is not important, so no token is returned here. + Although not strictly according to the GEDCOM spec, we'll ignore + whitespace just before the terminator. + */ + +{gen_delim}*{terminator} { line_no++; BEGIN(INITIAL); } + + /* Eventually we have to return 1 closing bracket (for the trailer). + We can detect whether we have sent the closing bracket using the + level_diff (at eof, first it is 2, then we increment it ourselves) */ + +<> { if (level_diff == 2) { + level_diff++; + return CLOSE; + } + else { + yyterminate(); + } + } + +. { gedcom_error("Unexpected character: '%s'", gedcom_text); + return BADTOKEN; + } + +%% + +int gedcom_wrap() +{ + return 1; +} diff --git a/gedcom.y b/gedcom.y new file mode 100644 index 0000000..389a8d8 --- /dev/null +++ b/gedcom.y @@ -0,0 +1,2113 @@ +/* $Id$ */ +/* $Name$ */ + +/* WARNING: THIS PARSER RELIES HEAVILY ON SOME FEATURES OF BISON. + DON'T TRY TO USE IT WITH YACC, IT WON'T WORK... +*/ + +/* Design of the parser: + --------------------- + In general, a GEDCOM file contains records, each consisting of a line + (which we'll call a section), hierarchically containing other lines + (subsections of the section). + + This means that in general we have: + + A 'record' is a 'section' (sect) containing 'subsections' (subs) + Each 'subsection' (sub) is again a specific 'section' (sect) + + In parser notation, this means: + + record : sect + + sect : subs + + subs : | subs sub + + sub : sect_a | sect_b | ... + + This pattern is repeated throughout the parser for the different types of + sections. + + + Cardinality of the subsections: + ------------------------------- + Note that in the above, the order of the subsections is of no importance. + Indeed, this is the case in the GEDCOM grammar. However, this also makes + it difficult to check whether there are not too many subsections of a + specific type, or whether a mandatory subsection is indeed there. + + Suppose there is a section A that can contain 0 or 1 B section and + 2 C sections. + + This can be expressed in parser notation as follows: + + A : CC | BCC | CBC | CCB + + So, cardinality is indeed expressable. However, as the number of subsection + types and the limits grow bigger (and even theoretically limitless), listing + all possible permutations becomes quickly unfeasible. + + Much simpler is to say: + + A : subs + subs : | subs sub + sub : B | C + + and then check the cardinality in the semantic actions, which is the + solution chosen in the parser below, using the following macros: + + - OPEN() + Make a new context for the tag to count child tags in + + - OCCUR2(, , ) + Express that the tag should occur at least times and + at most tags within its parent + + What this actually does is the following. It increments the counter + for that tag and then checks whether the maximum is exceeded. If so, + then a parser error is produced. The minimum is not actually checked + by this macro, but it makes the statements more declarative. + + - OCCUR1(, ) + Express that the tag should occur at least times within + its parent (no upper limit) + + Actually, this only increments the counter for the tag, but it looks + very like the previous macro. + + If the minimum is 0, it is not necessary to express this constraint. + + - CHECKn(, ..., ) + This closes the context for the parent tag and checks whether the + given tags did effectively occur within the parent (i.e. + these are the tags that were mandatory). + + Since the values above are always 0 or 1 in GEDCOM, this is + sufficient. All sub-tags that declare a minimum of 1 in the OCCUR + macros should be listed in this macro here. + + The macros CHECK0 to CHECK4 are defined like this (the first one + has no arguments and is only used to close the parent context; note + that this is necessary for correct functioning). + + Example of usage: + + Only sections that have subsections need to use these macros. This can + be done like this (the OPEN and CHECK macros are used as mid-rule + actions around the subsections): + + head_sect : OPEN DELIM TAG_HEAD + { OPEN(HEAD) } + head_subs + { CHECK1(SOUR) } + CLOSE { } + + head_subs : + | head_subs head_sub + ; + + head_sub : head_sour_sect { OCCUR2(SOUR, 1, 1) } + | head_dest_sect { OCCUR2(DEST, 0, 1) } + | head_date_sect { OCCUR2(DATE, 0, 1) } + ; +*/ + +/* General notes: + + - The syntax analysis doesn't handle the contents of the line values + or their encoding; this is done in the semantic analysis. + + */ + +%{ +#include "gedcom.h" + +int count_level=0; +MECHANISM curr_mechanism=FAIL_PARSE; + +/* These are defined at the bottom of the file */ +void push_countarray(); +void set_parenttag(char* tag); +char* get_parenttag(); +void pop_countarray(); +int count_tag(int tag); +int check_occurrence(int tag); + +#define OPEN(PARENTTAG) \ + { ++count_level; \ + set_parenttag(#PARENTTAG); \ + push_countarray(); \ + } +#define CHK(TAG) \ + { if (!check_occurrence(TAG_##TAG)) { \ + char* parenttag = get_parenttag(); \ + gedcom_error("The tag '%s' is mandatory within '%s'", \ + #TAG, parenttag); \ + YYERROR; \ + } \ + } +#define POP \ + { pop_countarray(); \ + --count_level; \ + } +#define CHECK0 POP; +#define CHECK1(TAG1) { CHK(TAG1); POP; } +#define CHECK2(TAG1,TAG2) \ + { CHK(TAG1); CHK(TAG2); POP; } +#define CHECK3(TAG1,TAG2,TAG3) \ + { CHK(TAG1); CHK(TAG2); CHK(TAG3); POP; } +#define CHECK4(TAG1,TAG2,TAG3,TAG4) \ + { CHK(TAG1); CHK(TAG2); CHK(TAG3); CHK(TAG4); POP; } +#define OCCUR1(CHILDTAG, MIN) { count_tag(TAG_##CHILDTAG); } +#define OCCUR2(CHILDTAG, MIN, MAX) \ + { int num = count_tag(TAG_##CHILDTAG); \ + if (num > MAX) { \ + char* parenttag = get_parenttag(); \ + gedcom_error("The tag '%s' can maximally occur %d " \ + "time(s) within '%s'", \ + #CHILDTAG, MAX, parenttag); \ + YYERROR; \ + } \ + } +#define INVALID_TAG(CHILDTAG) \ + { char* parenttag = get_parenttag(); \ + gedcom_error("The tag '%s' is not a valid tag within '%s'", \ + CHILDTAG, parenttag); \ + YYERROR; \ + } +#define INVALID_TOP_TAG(CHILDTAG) \ + { gedcom_error("The tag '%s' is not a valid top-level tag", \ + CHILDTAG); \ + YYERROR; \ + } + +%} + +%union { + char *string; +} + +%token_table + +%token BADTOKEN +%token OPEN +%token CLOSE +%token ESCAPE +%token DELIM +%token ANYCHAR +%token POINTER +%token USERTAG +%token TAG_ABBR +%token TAG_ADDR +%token TAG_ADR1 +%token TAG_ADR2 +%token TAG_ADOP +%token TAG_AFN +%token TAG_AGE +%token TAG_AGNC +%token TAG_ALIA +%token TAG_ANCE +%token TAG_ANCI +%token TAG_ANUL +%token TAG_ASSO +%token TAG_AUTH +%token TAG_BAPL +%token TAG_BAPM +%token TAG_BARM +%token TAG_BASM +%token TAG_BIRT +%token TAG_BLES +%token TAG_BLOB +%token TAG_BURI +%token TAG_CALN +%token TAG_CAST +%token TAG_CAUS +%token TAG_CENS +%token TAG_CHAN +%token TAG_CHAR +%token TAG_CHIL +%token TAG_CHR +%token TAG_CHRA +%token TAG_CITY +%token TAG_CONC +%token TAG_CONF +%token TAG_CONL +%token TAG_CONT +%token TAG_COPR +%token TAG_CORP +%token TAG_CREM +%token TAG_CTRY +%token TAG_DATA +%token TAG_DATE +%token TAG_DEAT +%token TAG_DESC +%token TAG_DESI +%token TAG_DEST +%token TAG_DIV +%token TAG_DIVF +%token TAG_DSCR +%token TAG_EDUC +%token TAG_EMIG +%token TAG_ENDL +%token TAG_ENGA +%token TAG_EVEN +%token TAG_FAM +%token TAG_FAMC +%token TAG_FAMF +%token TAG_FAMS +%token TAG_FCOM +%token TAG_FILE +%token TAG_FORM +%token TAG_GEDC +%token TAG_GIVN +%token TAG_GRAD +%token TAG_HEAD +%token TAG_HUSB +%token TAG_IDNO +%token TAG_IMMI +%token TAG_INDI +%token TAG_LANG +%token TAG_LEGA +%token TAG_MARB +%token TAG_MARC +%token TAG_MARL +%token TAG_MARR +%token TAG_MARS +%token TAG_MEDI +%token TAG_NAME +%token TAG_NATI +%token TAG_NATU +%token TAG_NCHI +%token TAG_NICK +%token TAG_NMR +%token TAG_NOTE +%token TAG_NPFX +%token TAG_NSFX +%token TAG_OBJE +%token TAG_OCCU +%token TAG_ORDI +%token TAG_ORDN +%token TAG_PAGE +%token TAG_PEDI +%token TAG_PHON +%token TAG_PLAC +%token TAG_POST +%token TAG_PROB +%token TAG_PROP +%token TAG_PUBL +%token TAG_QUAY +%token TAG_REFN +%token TAG_RELA +%token TAG_RELI +%token TAG_REPO +%token TAG_RESI +%token TAG_RESN +%token TAG_RETI +%token TAG_RFN +%token TAG_RIN +%token TAG_ROLE +%token TAG_SEX +%token TAG_SLGC +%token TAG_SLGS +%token TAG_SOUR +%token TAG_SPFX +%token TAG_SSN +%token TAG_STAE +%token TAG_STAT +%token TAG_SUBM +%token TAG_SUBN +%token TAG_SURN +%token TAG_TEMP +%token TAG_TEXT +%token TAG_TIME +%token TAG_TITL +%token TAG_TRLR +%token TAG_TYPE +%token TAG_VERS +%token TAG_WIFE +%token TAG_WILL + +/* +%type anytag +*/ + +%% + +file : head_sect records trlr_sect { } + ; + +records : /* empty */ + | records record + ; + +record : fam_rec + | indiv_rec + | multim_rec + | note_rec + | repos_rec + | source_rec + | submis_rec + | submit_rec + | user_sect /* 0:M */ + ; + +/*********************************************************************/ +/**** Header ****/ +/*********************************************************************/ +head_sect : OPEN DELIM TAG_HEAD + { OPEN(HEAD) } + head_subs + { CHECK4(SOUR, SUBM, GEDC, CHAR) } + CLOSE { } + ; + +head_subs : /* empty */ + | head_subs head_sub + ; + +head_sub : head_sour_sect { OCCUR2(SOUR, 1, 1) } + | head_dest_sect { OCCUR2(DEST, 0, 1) } + | head_date_sect { OCCUR2(DATE, 0, 1) } + | head_subm_sect { OCCUR2(SUBM, 1, 1) } + | head_subn_sect { OCCUR2(SUBN, 0, 1) } + | head_file_sect { OCCUR2(FILE, 0, 1) } + | head_copr_sect { OCCUR2(COPR, 0, 1) } + | head_gedc_sect { OCCUR2(GEDC, 1, 1) } + | head_char_sect { OCCUR2(CHAR, 1, 1) } + | head_lang_sect { OCCUR2(LANG, 0, 1) } + | head_plac_sect { OCCUR2(PLAC, 0, 1) } + | head_note_sect { OCCUR2(NOTE, 0, 1) } + | user_sect /* 0:M */ + ; + +/* HEAD.SOUR */ +head_sour_sect : OPEN DELIM TAG_SOUR DELIM line_item + { OPEN(SOUR) } + head_sour_subs + { CHECK0 } + CLOSE + { } + ; + +head_sour_subs : /* empty */ + | head_sour_subs head_sour_sub + ; + +head_sour_sub : head_sour_vers_sect { OCCUR2(VERS, 0, 1) } + | head_sour_name_sect { OCCUR2(NAME, 0, 1) } + | head_sour_corp_sect { OCCUR2(CORP, 0, 1) } + | head_sour_data_sect { OCCUR2(DATA, 0, 1) } + ; +head_sour_vers_sect : OPEN DELIM TAG_VERS DELIM line_item CLOSE + { } + ; +head_sour_name_sect : OPEN DELIM TAG_NAME DELIM line_item CLOSE + { } + ; +head_sour_corp_sect : OPEN DELIM TAG_CORP DELIM line_item + { OPEN(CORP) } + head_sour_corp_subs + { CHECK0 } + CLOSE + { } + ; + +head_sour_corp_subs : /* empty */ + | head_sour_corp_subs head_sour_corp_sub + ; + +head_sour_corp_sub : addr_struc_sub /* 0:1 */ + ; + +head_sour_data_sect : OPEN DELIM TAG_DATA DELIM line_item + { OPEN(DATA) } + head_sour_data_subs + { CHECK0 } + CLOSE + { } + ; + +head_sour_data_subs : /* empty */ + | head_sour_data_subs head_sour_data_sub + ; + +head_sour_data_sub : head_sour_data_date_sect { OCCUR2(DATE, 0, 1) } + | head_sour_data_copr_sect { OCCUR2(COPR, 0, 1) } + ; + +head_sour_data_date_sect : OPEN DELIM TAG_DATE DELIM line_item CLOSE + { } + ; +head_sour_data_copr_sect : OPEN DELIM TAG_COPR DELIM line_item CLOSE + { } + ; + +/* HEAD.DEST */ +head_dest_sect : OPEN DELIM TAG_DEST DELIM line_item CLOSE + { } + ; + +/* HEAD.DATE */ +head_date_sect : OPEN DELIM TAG_DATE DELIM line_item + { OPEN(DATE) } + head_date_subs + { CHECK0 } + CLOSE + { } + ; + +head_date_subs : /* empty */ + | head_date_subs head_date_sub + ; + +head_date_sub : head_date_time_sect { OCCUR2(TIME, 0, 1) } + ; + +head_date_time_sect : OPEN DELIM TAG_TIME DELIM line_item CLOSE + { } + ; + +/* HEAD.SUBM */ +head_subm_sect : OPEN DELIM TAG_SUBM DELIM POINTER CLOSE + { } + ; +/* HEAD.SUBN */ +head_subn_sect : OPEN DELIM TAG_SUBN DELIM POINTER CLOSE + { } + ; +/* HEAD.FILE */ +head_file_sect : OPEN DELIM TAG_FILE DELIM line_item CLOSE + { } + ; +/* HEAD.COPR */ +head_copr_sect : OPEN DELIM TAG_COPR DELIM line_item CLOSE + { } + ; +/* HEAD.GEDC */ +head_gedc_sect : OPEN DELIM TAG_GEDC + { OPEN(GEDC) } + head_gedc_subs + { CHECK2(VERS, FORM) } + CLOSE + { } + ; + +head_gedc_subs : /* empty */ + | head_gedc_subs head_gedc_sub + ; + +head_gedc_sub : head_gedc_vers_sect { OCCUR2(VERS, 1, 1) } + | head_gedc_form_sect { OCCUR2(FORM, 1, 1) } + ; +head_gedc_vers_sect : OPEN DELIM TAG_VERS DELIM line_item CLOSE + { } + ; +head_gedc_form_sect : OPEN DELIM TAG_FORM DELIM line_item CLOSE + { } + ; + +/* HEAD.CHAR */ +head_char_sect : OPEN DELIM TAG_CHAR DELIM line_item + { OPEN(CHAR) } + head_char_subs + { CHECK0 } + CLOSE + { } + ; + +head_char_subs : /* empty */ + | head_char_subs head_char_sub + ; + +head_char_sub : head_char_vers_sect { OCCUR2(VERS, 0, 1) } + ; +head_char_vers_sect : OPEN DELIM TAG_VERS DELIM line_item CLOSE + { } + ; + +/* HEAD.LANG */ +head_lang_sect : OPEN DELIM TAG_LANG DELIM line_item CLOSE + { } + ; +/* HEAD.PLAC */ +head_plac_sect : OPEN DELIM TAG_PLAC + { OPEN(PLAC) } + head_plac_subs + { CHECK1(FORM) } + CLOSE + { } + ; + +head_plac_subs : /* empty */ + | head_plac_subs head_plac_sub + ; + +head_plac_sub : head_plac_form_sect { OCCUR2(FORM, 1, 1) } + ; +head_plac_form_sect : OPEN DELIM TAG_FORM DELIM line_item CLOSE + { } + ; + +/* HEAD.NOTE */ +head_note_sect : OPEN DELIM TAG_NOTE DELIM line_item + { OPEN(NOTE) } + head_note_subs + { CHECK0 } + CLOSE + { } + ; + +head_note_subs : /* empty */ + | head_note_subs head_note_sub + ; + +head_note_sub : continuation_sub /* 0:M */ + ; + +/*********************************************************************/ +/**** Trailer ****/ +/*********************************************************************/ +trlr_sect : OPEN DELIM TAG_TRLR CLOSE { } + ; + +/*********************************************************************/ +/**** Family record ****/ +/*********************************************************************/ +fam_rec : OPEN DELIM POINTER DELIM TAG_FAM + { OPEN(FAM) } + fam_subs + { CHECK0 } + CLOSE { } + ; + +fam_subs : /* empty */ + | fam_subs fam_sub + ; + +fam_sub : fam_event_struc_sub /* 0:M */ + | fam_husb_sect { OCCUR2(HUSB, 0, 1) } + | fam_wife_sect { OCCUR2(WIFE, 0, 1) } + | fam_chil_sect /* 0:M */ + | fam_nchi_sect { OCCUR2(NCHI, 0, 1) } + | fam_subm_sect /* 0:M */ + | lds_spouse_seal_sub /* 0:M */ + | source_cit_sub /* 0:M */ + | multim_link_sub /* 0:M */ + | note_struc_sub /* 0:M */ + | ident_struc_sub /* 0:1 */ + | change_date_sub /* 0:1 */ + | user_sect /* 0:M */ + ; + +/* FAM.HUSB */ +fam_husb_sect : OPEN DELIM TAG_HUSB DELIM POINTER CLOSE + { } + ; + +/* FAM.WIFE */ +fam_wife_sect : OPEN DELIM TAG_WIFE DELIM POINTER CLOSE + { } + ; + +/* FAM.CHIL */ +fam_chil_sect : OPEN DELIM TAG_CHIL DELIM POINTER CLOSE + { } + ; + +/* FAM.NCHI */ +fam_nchi_sect : OPEN DELIM TAG_NCHI DELIM line_item CLOSE + { } + ; + +/* FAM.SUBM */ +fam_subm_sect : OPEN DELIM TAG_SUBM DELIM POINTER CLOSE + { } + ; + +/*********************************************************************/ +/**** Individual record ****/ +/*********************************************************************/ +indiv_rec : OPEN DELIM POINTER DELIM TAG_INDI + { OPEN(INDI) } + indi_subs + { CHECK0 } + CLOSE { } + ; + +indi_subs : /* empty */ + | indi_subs indi_sub + ; + +indi_sub : indi_resn_sect { OCCUR2(RESN, 0, 1) } + | pers_name_struc_sub /* 0:M */ + | indi_sex_sect { OCCUR2(SEX, 0, 1) } + | indiv_even_struc_sub /* 0:M */ + | indiv_attr_struc_sub /* 0:M */ + | lds_indiv_ord_sub /* 0:M */ + | chi_fam_link_sub /* 0:M */ + | spou_fam_link_sub /* 0:M */ + | indi_subm_sect /* 0:M */ + | assoc_struc_sub /* 0:M */ + | indi_alia_sect /* 0:M */ + | indi_anci_sect /* 0:M */ + | indi_desi_sect /* 0:M */ + | source_cit_sub /* 0:M */ + | multim_link_sub /* 0:M */ + | note_struc_sub /* 0:M */ + | indi_rfn_sect { OCCUR2(RFN, 0, 1) } + | indi_afn_sect /* 0:M */ + | ident_struc_sub /* 0:1 */ + | change_date_sub /* 0:1 */ + | user_sect /* 0:M */ + ; + +/* INDI.RESN */ +indi_resn_sect : OPEN DELIM TAG_RESN DELIM line_item CLOSE { } + ; + +/* INDI.SEX */ +indi_sex_sect : OPEN DELIM TAG_SEX DELIM line_item CLOSE { } + ; + +/* INDI.SUBM */ +indi_subm_sect : OPEN DELIM TAG_SUBM DELIM POINTER CLOSE { } + ; + +/* INDI.ALIA */ +indi_alia_sect : OPEN DELIM TAG_ALIA DELIM POINTER CLOSE { } + ; + +/* INDI.ANCI */ +indi_anci_sect : OPEN DELIM TAG_ANCI DELIM POINTER CLOSE { } + ; + +/* INDI.DESI */ +indi_desi_sect : OPEN DELIM TAG_DESI DELIM POINTER CLOSE { } + ; + +/* INDI.RFN */ +indi_rfn_sect : OPEN DELIM TAG_RFN DELIM line_item CLOSE { } + ; + +/* INDI.AFN */ +indi_afn_sect : OPEN DELIM TAG_AFN DELIM line_item CLOSE { } + ; + +/*********************************************************************/ +/**** Multimedia record ****/ +/*********************************************************************/ +multim_rec : OPEN DELIM POINTER DELIM TAG_OBJE + { OPEN(OBJE) } + obje_subs + { CHECK2(FORM, BLOB) } + CLOSE { } + ; + +obje_subs : /* empty */ + | obje_subs obje_sub + ; + +obje_sub : obje_form_sect { OCCUR2(FORM, 1, 1) } + | obje_titl_sect { OCCUR2(TITL, 0, 1) } + | note_struc_sub /* 0:M */ + | obje_blob_sect { OCCUR2(BLOB, 1, 1) } + | obje_obje_sect { OCCUR2(OBJE, 0, 1) } + | ident_struc_sub /* 0:1 */ + | change_date_sub /* 0:1 */ + | user_sect /* 0:M */ + ; + +/* OBJE.FORM */ +obje_form_sect : OPEN DELIM TAG_FORM DELIM line_item CLOSE { } + ; + +/* OBJE.TITL */ +obje_titl_sect : OPEN DELIM TAG_TITL DELIM line_item CLOSE { } + ; + +/* OBJE.BLOB */ +obje_blob_sect : OPEN DELIM TAG_BLOB + { OPEN(BLOB) } + obje_blob_subs + { CHECK1(CONT) } + CLOSE { } + ; + +obje_blob_subs : /* empty */ + | obje_blob_subs obje_blob_sub + ; + +obje_blob_sub : obje_blob_cont_sect { OCCUR1(CONT, 1) } + ; + +obje_blob_cont_sect : OPEN DELIM TAG_CONT DELIM line_item CLOSE { } + ; + +/* OBJE.OBJE */ +obje_obje_sect : OPEN DELIM TAG_OBJE DELIM POINTER CLOSE { } + ; + +/*********************************************************************/ +/**** Note record ****/ +/*********************************************************************/ +note_rec : OPEN DELIM POINTER DELIM TAG_NOTE DELIM line_item + { OPEN(NOTE) } + note_subs + { CHECK0 } + CLOSE { } + ; + +note_subs : /* empty */ + | note_subs note_sub + ; + +note_sub : continuation_sub /* 0:M */ + | source_cit_sub /* 0:M */ + | ident_struc_sub /* 0:1 */ + | change_date_sub /* 0:1 */ + | user_sect /* 0:M */ + ; + +/*********************************************************************/ +/**** Repository record ****/ +/*********************************************************************/ +repos_rec : OPEN DELIM POINTER DELIM TAG_REPO + { OPEN(REPO) } + repo_subs + { CHECK0 } + CLOSE { } + ; + +repo_subs : /* empty */ + | repo_subs repo_sub + ; + +repo_sub : repo_name_sect { OCCUR2(NAME, 0, 1) } + | addr_struc_sub /* 0:1 */ + | note_struc_sub /* 0:M */ + | ident_struc_sub /* 0:1 */ + | change_date_sub /* 0:1 */ + | user_sect /* 0:M */ + ; + +/* REPO.NAME */ +repo_name_sect : OPEN DELIM TAG_NAME DELIM line_item CLOSE {} + ; + +/*********************************************************************/ +/**** Source record ****/ +/*********************************************************************/ +source_rec : OPEN DELIM POINTER DELIM TAG_SOUR + { OPEN(SOUR) } + sour_subs + { CHECK0 } + CLOSE { } + ; + +sour_subs : /* empty */ + | sour_subs sour_sub + ; + +sour_sub : sour_data_sect { OCCUR2(DATA, 0, 1) } + | sour_auth_sect { OCCUR2(AUTH, 0, 1) } + | sour_titl_sect { OCCUR2(TITL, 0, 1) } + | sour_abbr_sect { OCCUR2(ABBR, 0, 1) } + | sour_publ_sect { OCCUR2(PUBL, 0, 1) } + | sour_text_sect { OCCUR2(TEXT, 0, 1) } + | source_repos_cit_sub /* 0:1 */ + | multim_link_sub /* 0:M */ + | note_struc_sub /* 0:M */ + | ident_struc_sub /* 0:1 */ + | change_date_sub /* 0:1 */ + | user_sect /* 0:M */ + ; + +/* SOUR.DATA */ +sour_data_sect : OPEN DELIM TAG_DATA + { OPEN(DATA) } + sour_data_subs + { CHECK0 } + CLOSE { } + ; + +sour_data_subs : /* empty */ + | sour_data_subs sour_data_sub + ; + +sour_data_sub : sour_data_even_sect /* 0:M */ + | sour_data_agnc_sect { OCCUR2(AGNC, 0, 1) } + | note_struc_sub /* 0:M */ + ; + +sour_data_even_sect : OPEN DELIM TAG_EVEN DELIM line_item + { OPEN(EVEN) } + sour_data_even_subs + { CHECK0 } + CLOSE { } + ; + +sour_data_even_subs : /* empty */ + | sour_data_even_subs sour_data_even_sub + ; + +sour_data_even_sub : sour_data_even_date_sect { OCCUR2(DATE, 0, 1) } + | sour_data_even_plac_sect { OCCUR2(PLAC, 0, 1) } + ; + +sour_data_even_date_sect : OPEN DELIM TAG_DATE DELIM line_item CLOSE { } + ; + +sour_data_even_plac_sect : OPEN DELIM TAG_PLAC DELIM line_item CLOSE { } + ; + +sour_data_agnc_sect : OPEN DELIM TAG_AGNC DELIM line_item CLOSE { } + ; + +/* SOUR.AUTH */ +sour_auth_sect : OPEN DELIM TAG_AUTH DELIM line_item + { OPEN(AUTH) } + sour_auth_subs + { CHECK0 } + CLOSE { } + ; + +sour_auth_subs : /* empty */ + | sour_auth_subs sour_auth_sub + ; + +sour_auth_sub : continuation_sub /* 0:M */ + ; + +/* SOUR.TITL */ +sour_titl_sect : OPEN DELIM TAG_TITL DELIM line_item + { OPEN(TITL) } + sour_titl_subs + { CHECK0 } + CLOSE { } + ; + +sour_titl_subs : /* empty */ + | sour_titl_subs sour_titl_sub + ; + +sour_titl_sub : continuation_sub /* 0:M */ + ; + +/* SOUR.ABBR */ +sour_abbr_sect : OPEN DELIM TAG_ABBR DELIM line_item CLOSE { } + ; + +/* SOUR.PUBL */ +sour_publ_sect : OPEN DELIM TAG_PUBL DELIM line_item + { OPEN(PUBL) } + sour_publ_subs + { CHECK0 } + CLOSE { } + ; + +sour_publ_subs : /* empty */ + | sour_publ_subs sour_publ_sub + ; + +sour_publ_sub : continuation_sub /* 0:M */ + ; + +/* SOUR.TEXT */ +sour_text_sect : OPEN DELIM TAG_TEXT DELIM line_item + { OPEN(TEXT) } + sour_text_subs + { CHECK0 } + CLOSE { } + ; + +sour_text_subs : /* empty */ + | sour_text_subs sour_text_sub + ; + +sour_text_sub : continuation_sub /* 0:M */ + ; + +/*********************************************************************/ +/**** Submission record ****/ +/*********************************************************************/ +submis_rec : OPEN DELIM POINTER DELIM TAG_SUBN + { OPEN(SUBN) } + subn_subs + { CHECK0 } + CLOSE { } + ; + +subn_subs : /* empty */ + | subn_subs subn_sub + ; + +subn_sub : subn_subm_sect { OCCUR2(SUBM, 0, 1) } + | subn_famf_sect { OCCUR2(FAMF, 0, 1) } + | subn_temp_sect { OCCUR2(TEMP, 0, 1) } + | subn_ance_sect { OCCUR2(ANCE, 0, 1) } + | subn_desc_sect { OCCUR2(DESC, 0, 1) } + | subn_ordi_sect { OCCUR2(ORDI, 0, 1) } + | subn_rin_sect { OCCUR2(RIN, 0, 1) } + | user_sect /* 0:M */ + ; + +/* SUBN.SUBM */ +subn_subm_sect : OPEN DELIM TAG_SUBM DELIM POINTER CLOSE { } + ; + +/* SUBN.FAMF */ +subn_famf_sect : OPEN DELIM TAG_FAMF DELIM line_item CLOSE { } + ; + +/* SUBN.TEMP */ +subn_temp_sect : OPEN DELIM TAG_TEMP DELIM line_item CLOSE { } + ; + +/* SUBN.ANCE */ +subn_ance_sect : OPEN DELIM TAG_ANCE DELIM line_item CLOSE { } + ; + +/* SUBN.DESC */ +subn_desc_sect : OPEN DELIM TAG_DESC DELIM line_item CLOSE { } + ; + +/* SUBN.ORDI */ +subn_ordi_sect : OPEN DELIM TAG_ORDI DELIM line_item CLOSE { } + ; + +/* SUBN.RIN */ +subn_rin_sect : OPEN DELIM TAG_RIN DELIM line_item CLOSE { } + ; + +/*********************************************************************/ +/**** Submitter record ****/ +/*********************************************************************/ +submit_rec : OPEN DELIM POINTER DELIM TAG_SUBM + { OPEN(SUBM) } + subm_subs + { CHECK1(NAME) } + CLOSE { } + ; + +subm_subs : /* empty */ + | subm_subs subm_sub + ; + +subm_sub : subm_name_sect { OCCUR2(NAME, 0, 1) } + | addr_struc_sub /* 0:1 */ + | multim_link_sub /* 0:M */ + | subm_lang_sect { OCCUR2(LANG, 0, 3) } + | subm_rfn_sect { OCCUR2(RFN, 0, 1) } + | subm_rin_sect { OCCUR2(RIN, 0, 1) } + | change_date_sub /* 0:1 */ + | user_sect /* 0:M */ + ; + +/* SUBM.NAME */ +subm_name_sect : OPEN DELIM TAG_NAME DELIM line_item CLOSE { } + ; + +/* SUBM.LANG */ +subm_lang_sect : OPEN DELIM TAG_LANG DELIM line_item CLOSE { } + ; + +/* SUBM.RFN */ +subm_rfn_sect : OPEN DELIM TAG_RFN DELIM line_item CLOSE { } + ; + +/* SUBM.RIN */ +subm_rin_sect : OPEN DELIM TAG_RIN DELIM line_item CLOSE { } + ; + +/*********************************************************************/ +/**** Substructures ****/ +/*********************************************************************/ + +/* ADDRESS STRUCTURE */ +addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) } + | phon_sect { OCCUR2(PHON, 0, 3) } + ; + +addr_sect : OPEN DELIM TAG_ADDR DELIM line_item + { OPEN(ADDR) } + addr_subs + { CHECK0 } + CLOSE { } + ; + +addr_subs : /* empty */ + | addr_subs addr_sub + ; + +addr_sub : addr_cont_sect /* 0:M */ + | addr_adr1_sect { OCCUR2(ADR1, 0, 1) } + | addr_adr2_sect { OCCUR2(ADR2, 0, 1) } + | addr_city_sect { OCCUR2(CITY, 0, 1) } + | addr_stae_sect { OCCUR2(STAE, 0, 1) } + | addr_post_sect { OCCUR2(POST, 0, 1) } + | addr_ctry_sect { OCCUR2(CTRY, 0, 1) } + ; + +addr_cont_sect : OPEN DELIM TAG_CONT DELIM line_item CLOSE { } + ; +addr_adr1_sect : OPEN DELIM TAG_ADR1 DELIM line_item CLOSE { } + ; +addr_adr2_sect : OPEN DELIM TAG_ADR2 DELIM line_item CLOSE { } + ; +addr_city_sect : OPEN DELIM TAG_CITY DELIM line_item CLOSE { } + ; +addr_stae_sect : OPEN DELIM TAG_STAE DELIM line_item CLOSE { } + ; +addr_post_sect : OPEN DELIM TAG_POST DELIM line_item CLOSE { } + ; +addr_ctry_sect : OPEN DELIM TAG_CTRY DELIM line_item CLOSE { } + ; + +phon_sect : OPEN DELIM TAG_PHON DELIM line_item CLOSE { } + ; + +/* ASSOCIATION STRUCTURE */ +assoc_struc_sub : asso_sect /* 0:M */ + ; + +asso_sect : OPEN DELIM TAG_ASSO DELIM POINTER + { OPEN(ASSO) } + asso_subs + { CHECK2(TYPE,RELA) } + CLOSE { } + ; + +asso_subs : /* empty */ + | asso_type_sect { OCCUR2(TYPE, 1, 1) } + | asso_rela_sect { OCCUR2(RELA, 1, 1) } + | note_struc_sub + | source_cit_sub + ; + +asso_type_sect : OPEN DELIM TAG_TYPE DELIM line_item CLOSE { } + ; + +asso_rela_sect : OPEN DELIM TAG_RELA DELIM line_item CLOSE { } + ; + +/* CHANGE DATE */ +change_date_sub : change_date_chan_sect { OCCUR2(CHAN, 0, 1) } + ; + +change_date_chan_sect : OPEN DELIM TAG_CHAN + { OPEN(CHAN) } + change_date_chan_subs + { CHECK1(DATE) } + CLOSE { } + ; + +change_date_chan_subs : /* empty */ + | change_date_chan_subs change_date_chan_sub + ; + +change_date_chan_sub : change_date_date_sect { OCCUR2(DATE, 1, 1) } + | note_struc_sub + ; + +change_date_date_sect : OPEN DELIM TAG_DATE DELIM line_item + { OPEN(DATE) } + change_date_date_subs + { CHECK0 } + CLOSE { } + ; + +change_date_date_subs : /* empty */ + | change_date_date_subs change_date_date_sub + ; + +change_date_date_sub : change_date_date_time_sect { OCCUR2(TIME, 0, 1) } + ; + +change_date_date_time_sect : OPEN DELIM TAG_TIME DELIM line_item CLOSE { } + ; + +/* CHILD TO FAMILY LINK */ +chi_fam_link_sub : famc_sect /* 0:M */ + ; + +famc_sect : OPEN DELIM TAG_FAMC DELIM POINTER + { OPEN(FAMC) } + famc_subs + { CHECK0 } + CLOSE { } + ; + +famc_subs : /* empty */ + | famc_subs famc_sub + ; + +famc_sub : famc_pedi_sect /* 0:M */ + | note_struc_sub + ; + +famc_pedi_sect : OPEN DELIM TAG_PEDI DELIM line_item CLOSE { } + ; + +/* CONTINUATION SUBSECTIONS */ +continuation_sub : cont_sect /* 0:M */ + | conc_sect /* 0:M */ + ; + +cont_sect : OPEN DELIM TAG_CONT DELIM line_item CLOSE { } + ; + +conc_sect : OPEN DELIM TAG_CONC DELIM line_item CLOSE { } + ; + +/* EVENT DETAIL */ +event_detail_sub : event_detail_type_sect { OCCUR2(TYPE, 0, 1) } + | event_detail_date_sect { OCCUR2(DATE, 0, 1) } + | place_struc_sub + | addr_struc_sub + | event_detail_age_sect { OCCUR2(AGE, 0, 1) } + | event_detail_agnc_sect { OCCUR2(AGNC, 0, 1) } + | event_detail_caus_sect { OCCUR2(CAUS, 0, 1) } + | source_cit_sub + | multim_link_sub + | note_struc_sub + ; + +event_detail_type_sect : OPEN DELIM TAG_TYPE DELIM line_item CLOSE { } + ; +event_detail_date_sect : OPEN DELIM TAG_DATE DELIM line_item CLOSE { } + ; +event_detail_age_sect : OPEN DELIM TAG_AGE DELIM line_item CLOSE { } + ; +event_detail_agnc_sect : OPEN DELIM TAG_AGNC DELIM line_item CLOSE { } + ; +event_detail_caus_sect : OPEN DELIM TAG_CAUS DELIM line_item CLOSE { } + ; + +/* FAMILY EVENT STRUCTURE */ +fam_event_struc_sub : fam_event_sect + | fam_gen_even_sect /* 0:M */ + ; + +fam_event_sect : OPEN DELIM fam_event_tag opt_value fam_event_subs + { CHECK0 } + CLOSE { } + ; + +fam_event_tag : TAG_ANUL { OPEN(ANUL) } + | TAG_CENS { OPEN(CENS) } + | TAG_DIV { OPEN(DIV) } + | TAG_DIVF { OPEN(DIVF) } + | TAG_ENGA { OPEN(ENGA) } + | TAG_MARR { OPEN(MARR) } + | TAG_MARB { OPEN(MARB) } + | TAG_MARC { OPEN(MARC) } + | TAG_MARL { OPEN(MARL) } + | TAG_MARS { OPEN(MARS) } + ; + +fam_event_subs : /* empty */ + | fam_event_subs fam_event_sub + ; + +fam_event_sub : event_detail_sub + | fam_even_husb_sect { OCCUR2(HUSB, 0, 1) } + | fam_even_wife_sect { OCCUR2(WIFE, 0, 1) } + ; + +fam_even_husb_sect : OPEN DELIM TAG_HUSB + { OPEN(HUSB) } + fam_even_husb_subs + { CHECK1(AGE) } + CLOSE { } + ; + +fam_even_husb_subs : /* empty */ + | fam_even_husb_subs fam_even_husb_sub + ; + +fam_even_husb_sub : fam_even_husb_age_sect { OCCUR2(AGE, 1, 1) } + ; + +fam_even_husb_age_sect : OPEN DELIM TAG_AGE DELIM line_item CLOSE { } + ; + +fam_even_wife_sect : OPEN DELIM TAG_WIFE + { OPEN(HUSB) } + fam_even_husb_subs + { CHECK1(AGE) } + CLOSE { } + ; + +fam_gen_even_sect : OPEN DELIM TAG_EVEN + { OPEN(EVEN) } + fam_gen_even_subs + { CHECK0 } + CLOSE { } + ; + +fam_gen_even_subs : /* empty */ + | fam_gen_even_subs fam_gen_even_sub + ; + +fam_gen_even_sub : event_detail_sub + | fam_even_husb_sect { OCCUR2(HUSB, 0, 1) } + | fam_even_wife_sect { OCCUR2(WIFE, 0, 1) } + ; + +/* IDENTIFICATION STRUCTURE */ +ident_struc_sub : ident_refn_sect /* 0:M */ + | ident_rin_sect { OCCUR2(RIN, 0, 1) } + ; + +ident_refn_sect : OPEN DELIM TAG_REFN DELIM line_item + { OPEN(REFN) } + ident_refn_subs + { CHECK0 } + CLOSE { } + ; + +ident_refn_subs : /* empty */ + | ident_refn_subs ident_refn_sub + ; + +ident_refn_sub : ident_refn_type_sect { OCCUR2(TYPE, 0, 1) } + ; + +ident_refn_type_sect : OPEN DELIM TAG_TYPE DELIM line_item CLOSE { } + ; + +ident_rin_sect : OPEN DELIM TAG_RIN DELIM line_item CLOSE { } + ; + +/* INDIVIDUAL ATTRIBUTE STRUCTURE */ +indiv_attr_struc_sub : indiv_cast_sect /* 0:M */ + | indiv_dscr_sect /* 0:M */ + | indiv_educ_sect /* 0:M */ + | indiv_idno_sect /* 0:M */ + | indiv_nati_sect /* 0:M */ + | indiv_nchi_sect /* 0:M */ + | indiv_nmr_sect /* 0:M */ + | indiv_occu_sect /* 0:M */ + | indiv_prop_sect /* 0:M */ + | indiv_reli_sect /* 0:M */ + | indiv_resi_sect /* 0:M */ + | indiv_ssn_sect /* 0:M */ + | indiv_titl_sect /* 0:M */ + ; + +indiv_cast_sect : OPEN DELIM TAG_CAST DELIM line_item + { OPEN(CAST) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_dscr_sect : OPEN DELIM TAG_DSCR DELIM line_item + { OPEN(DSCR) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_educ_sect : OPEN DELIM TAG_EDUC DELIM line_item + { OPEN(EDUC) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_idno_sect : OPEN DELIM TAG_IDNO DELIM line_item + { OPEN(IDNO) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_nati_sect : OPEN DELIM TAG_NATI DELIM line_item + { OPEN(NATI) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_nchi_sect : OPEN DELIM TAG_NCHI DELIM line_item + { OPEN(NCHI) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_nmr_sect : OPEN DELIM TAG_NMR DELIM line_item + { OPEN(NMR) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_occu_sect : OPEN DELIM TAG_OCCU DELIM line_item + { OPEN(OCCU) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_prop_sect : OPEN DELIM TAG_PROP DELIM line_item + { OPEN(PROP) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_reli_sect : OPEN DELIM TAG_RELI DELIM line_item + { OPEN(RELI) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_resi_sect : OPEN DELIM TAG_RESI + { OPEN(RESI) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_ssn_sect : OPEN DELIM TAG_SSN DELIM line_item + { OPEN(SSN) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; +indiv_titl_sect : OPEN DELIM TAG_TITL DELIM line_item + { OPEN(TITL) } + indiv_attr_event_subs + { CHECK0 } + CLOSE { } + ; + +indiv_attr_event_subs : /* empty */ + | indiv_attr_event_subs indiv_attr_event_sub + ; + +indiv_attr_event_sub : event_detail_sub + ; + +/* INDIVIDUAL EVENT STRUCTURE */ +indiv_even_struc_sub : indiv_birt_sect + | indiv_gen_sect + | indiv_adop_sect /* 0:M */ + | indiv_even_sect /* 0:M */ + ; + +indiv_birt_sect : OPEN DELIM indiv_birt_tag opt_value indiv_birt_subs + { CHECK0 } + CLOSE { } + ; + +indiv_birt_tag : TAG_BIRT { OPEN(BIRT) } + | TAG_CHR { OPEN(CHR) } + ; + +indiv_birt_subs : /* empty */ + | indiv_birt_subs indiv_birt_sub + ; + +indiv_birt_sub : event_detail_sub + | indiv_birt_famc_sect { OCCUR2(FAMC,0, 1) } + ; + +indiv_birt_famc_sect : OPEN DELIM TAG_FAMC DELIM POINTER CLOSE { } + ; + +indiv_gen_sect : OPEN DELIM indiv_gen_tag opt_value indiv_gen_subs + { CHECK0 } + CLOSE { } + ; + +indiv_gen_tag : TAG_DEAT { OPEN(DEAT) } + | TAG_BURI { OPEN(BURI) } + | TAG_CREM { OPEN(CREM) } + | TAG_BAPM { OPEN(BAPM) } + | TAG_BARM { OPEN(BARM) } + | TAG_BASM { OPEN(BASM) } + | TAG_BLES { OPEN(BLES) } + | TAG_CHRA { OPEN(CHRA) } + | TAG_CONF { OPEN(CONF) } + | TAG_FCOM { OPEN(FCOM) } + | TAG_ORDN { OPEN(ORDN) } + | TAG_NATU { OPEN(NATU) } + | TAG_EMIG { OPEN(EMIG) } + | TAG_IMMI { OPEN(IMMI) } + | TAG_CENS { OPEN(CENS) } + | TAG_PROB { OPEN(PROB) } + | TAG_WILL { OPEN(WILL) } + | TAG_GRAD { OPEN(GRAD) } + | TAG_RETI { OPEN(RETI) } + ; + +indiv_gen_subs : /* empty */ + | indiv_gen_subs indiv_gen_sub + ; + +indiv_gen_sub : event_detail_sub + ; + +indiv_adop_sect : OPEN DELIM TAG_ADOP opt_value + { OPEN(ADOP) } + indiv_adop_subs + { CHECK0 } + CLOSE { } + ; + +indiv_adop_subs : /* empty */ + | indiv_adop_subs indiv_adop_sub + ; + +indiv_adop_sub : event_detail_sub + | indiv_adop_famc_sect { OCCUR2(FAMC,0, 1) } + ; + +indiv_adop_famc_sect : OPEN DELIM TAG_FAMC DELIM POINTER + { OPEN(FAMC) } + indiv_adop_famc_subs + { CHECK0 } + CLOSE { } + ; + +indiv_adop_famc_subs : /* empty */ + | indiv_adop_famc_subs indiv_adop_famc_sub + ; + +indiv_adop_famc_sub : indiv_adop_famc_adop_sect { OCCUR2(ADOP,0, 1) } + ; + +indiv_adop_famc_adop_sect : OPEN DELIM TAG_ADOP DELIM line_item CLOSE { } + ; + +indiv_even_sect : OPEN DELIM TAG_EVEN + { OPEN(EVEN) } + indiv_gen_subs + { CHECK0 } + CLOSE { } + ; + +/* LDS INDIVIDUAL ORDINANCE */ +lds_indiv_ord_sub : lio_bapl_sect /* 0:M */ + | lio_slgc_sect /* 0:M */ + ; + +lio_bapl_sect : OPEN DELIM lio_bapl_tag lio_bapl_subs + { CHECK0 } + CLOSE { } + ; + +lio_bapl_tag : TAG_BAPL { OPEN(BAPL) } + | TAG_CONL { OPEN(CONL) } + | TAG_ENDL { OPEN(ENDL) } + ; + +lio_bapl_subs : /* empty */ + | lio_bapl_subs lio_bapl_sub + ; + +lio_bapl_sub : lio_bapl_stat_sect { OCCUR2(STAT, 0, 1) } + | lio_bapl_date_sect { OCCUR2(DATE, 0, 1) } + | lio_bapl_temp_sect { OCCUR2(TEMP, 0, 1) } + | lio_bapl_plac_sect { OCCUR2(PLAC, 0, 1) } + | source_cit_sub + | note_struc_sub + ; + +lio_bapl_stat_sect : OPEN DELIM TAG_STAT DELIM line_item CLOSE { } + ; +lio_bapl_date_sect : OPEN DELIM TAG_DATE DELIM line_item CLOSE { } + ; +lio_bapl_temp_sect : OPEN DELIM TAG_TEMP DELIM line_item CLOSE { } + ; +lio_bapl_plac_sect : OPEN DELIM TAG_PLAC DELIM line_item CLOSE { } + ; + +lio_slgc_sect : OPEN DELIM TAG_SLGC + { OPEN(SLGC) } + lio_slgc_subs + { CHECK1(FAMC) } + CLOSE { } + ; + +lio_slgc_subs : /* empty */ + | lio_slgc_subs lio_slgc_sub + ; + +lio_slgc_sub : lio_bapl_sub + | lio_slgc_famc_sect { OCCUR2(FAMC, 1, 1) } + ; + +lio_slgc_famc_sect : OPEN DELIM TAG_FAMC DELIM POINTER CLOSE { } + ; + +/* LDS SPOUSE SEALING */ +lds_spouse_seal_sub : lss_slgs_sect + ; + +lss_slgs_sect : OPEN DELIM TAG_SLGS + { OPEN(SLGS) } + lss_slgs_subs + { CHECK0 } + CLOSE { } + ; + +lss_slgs_subs : /* empty */ + | lss_slgs_subs lss_slgs_sub + ; + +lss_slgs_sub : lss_slgs_stat_sect { OCCUR2(STAT, 0, 1) } + | lss_slgs_date_sect { OCCUR2(DATE, 0, 1) } + | lss_slgs_temp_sect { OCCUR2(TEMP, 0, 1) } + | lss_slgs_plac_sect { OCCUR2(PLAC, 0, 1) } + | source_cit_sub + | note_struc_sub + ; + +lss_slgs_stat_sect : OPEN DELIM TAG_STAT DELIM line_item CLOSE { } + ; +lss_slgs_date_sect : OPEN DELIM TAG_DATE DELIM line_item CLOSE { } + ; +lss_slgs_temp_sect : OPEN DELIM TAG_TEMP DELIM line_item CLOSE { } + ; +lss_slgs_plac_sect : OPEN DELIM TAG_PLAC DELIM line_item CLOSE { } + ; + +/* MULTIMEDIA LINK */ +multim_link_sub : multim_obje_link_sect + | multim_obje_emb_sect + ; + +multim_obje_link_sect : OPEN DELIM TAG_OBJE DELIM POINTER CLOSE { } + ; + +multim_obje_emb_sect : OPEN DELIM TAG_OBJE + { OPEN(OBJE) } + multim_obje_emb_subs + { CHECK2(FORM,FILE) } + CLOSE { } + ; + +multim_obje_emb_subs : /* empty */ + | multim_obje_emb_subs multim_obje_emb_sub + ; + +multim_obje_emb_sub : multim_obje_form_sect { OCCUR2(FORM, 1, 1) } + | multim_obje_titl_sect { OCCUR2(TITL, 0, 1) } + | multim_obje_file_sect { OCCUR2(FILE, 1, 1) } + | note_struc_sub + ; + +multim_obje_form_sect : OPEN DELIM TAG_FORM DELIM line_item CLOSE { } + ; +multim_obje_titl_sect : OPEN DELIM TAG_TITL DELIM line_item CLOSE { } + ; +multim_obje_file_sect : OPEN DELIM TAG_FILE DELIM line_item CLOSE { } + ; + +/* NOTE STRUCTURE */ +note_struc_sub : note_struc_link_sect /* 0:M */ + | note_struc_emb_sect /* 0:M */ + ; + +note_struc_link_sect : OPEN DELIM TAG_NOTE DELIM POINTER + { OPEN(NOTE) } + note_struc_link_subs + { CHECK0 } + CLOSE { } + ; + +note_struc_link_subs : /* empty */ + | note_struc_link_subs note_struc_link_sub + ; + +note_struc_link_sub : source_cit_sub + ; + +note_struc_emb_sect : OPEN DELIM TAG_NOTE opt_line_item + { OPEN(NOTE) } + note_struc_emb_subs + { CHECK0 } + CLOSE { } + ; + +note_struc_emb_subs : /* empty */ + | note_struc_emb_subs note_struc_emb_sub + ; + +note_struc_emb_sub : continuation_sub + | source_cit_sub + ; + +/* PERSONAL NAME STRUCTURE */ +pers_name_struc_sub : pers_name_sect /* 0:M */ + ; + +pers_name_sect : OPEN DELIM TAG_NAME DELIM line_item + { OPEN(NAME) } + pers_name_subs + { CHECK0 } + CLOSE { } + ; + +pers_name_subs : /* empty */ + | pers_name_subs pers_name_sub + ; + +pers_name_sub : pers_name_npfx_sect { OCCUR2(NPFX, 0, 1) } + | pers_name_givn_sect { OCCUR2(GIVN, 0, 1) } + | pers_name_nick_sect { OCCUR2(NICK, 0, 1) } + | pers_name_spfx_sect { OCCUR2(SPFX, 0, 1) } + | pers_name_surn_sect { OCCUR2(SURN, 0, 1) } + | pers_name_nsfx_sect { OCCUR2(NSFX, 0, 1) } + | source_cit_sub + | note_struc_sub + ; + +pers_name_npfx_sect : OPEN DELIM TAG_NPFX DELIM line_item CLOSE { } + ; +pers_name_givn_sect : OPEN DELIM TAG_GIVN DELIM line_item CLOSE { } + ; +pers_name_nick_sect : OPEN DELIM TAG_NICK DELIM line_item CLOSE { } + ; +pers_name_spfx_sect : OPEN DELIM TAG_SPFX DELIM line_item CLOSE { } + ; +pers_name_surn_sect : OPEN DELIM TAG_SURN DELIM line_item CLOSE { } + ; +pers_name_nsfx_sect : OPEN DELIM TAG_NSFX DELIM line_item CLOSE { } + ; + +/* PLACE STRUCTURE */ +place_struc_sub : place_struc_plac_sect /* 0:M */ + ; + +place_struc_plac_sect : OPEN DELIM TAG_PLAC DELIM line_item + { OPEN(PLAC) } + place_struc_plac_subs + { CHECK0 } + CLOSE { } + ; + +place_struc_plac_subs : /* empty */ + | place_struc_plac_subs place_struc_plac_sub + ; + +place_struc_plac_sub : place_plac_form_sect { OCCUR2(FORM, 0, 1) } + | source_cit_sub + | note_struc_sub + ; + +place_plac_form_sect : OPEN DELIM TAG_FORM DELIM line_item CLOSE { } + ; + +/* SOURCE_CITATION */ +source_cit_sub : source_cit_link_sect /* 0:M */ + | source_cit_emb_sect /* 0:M */ + ; + +source_cit_link_sect : OPEN DELIM TAG_SOUR DELIM POINTER + { OPEN(SOUR) } + source_cit_link_subs + { CHECK0 } + CLOSE { } + ; + +source_cit_link_subs : /* empty */ + | source_cit_link_subs source_cit_link_sub + ; + +source_cit_link_sub : source_cit_page_sect { OCCUR2(PAGE, 0, 1) } + | source_cit_even_sect { OCCUR2(EVEN, 0, 1) } + | source_cit_data_sect { OCCUR2(DATA, 0, 1) } + | source_cit_quay_sect { OCCUR2(QUAY, 0, 1) } + | multim_link_sub + | note_struc_sub + ; + +source_cit_page_sect : OPEN DELIM TAG_PAGE DELIM line_item CLOSE { } + ; + +source_cit_even_sect : OPEN DELIM TAG_EVEN DELIM line_item + { OPEN(EVEN) } + source_cit_even_subs + { CHECK0 } + CLOSE { } + ; + +source_cit_even_subs : /* empty */ + | source_cit_even_subs source_cit_even_sub + ; + +source_cit_even_sub : source_cit_even_role_sect { OCCUR2(ROLE, 0, 1) } + ; + +source_cit_even_role_sect : OPEN DELIM TAG_ROLE DELIM line_item CLOSE { } + ; + +source_cit_data_sect : OPEN DELIM TAG_DATA + { OPEN(DATA) } + source_cit_data_subs + { CHECK0 } + CLOSE { } + ; + +source_cit_data_subs : /* empty */ + | source_cit_data_subs source_cit_data_sub + ; + +source_cit_data_sub : source_cit_data_date_sect { OCCUR2(DATE, 0, 1) } + | source_cit_text_sect /* 0:M */ + ; + +source_cit_data_date_sect : OPEN DELIM TAG_DATE DELIM line_item CLOSE { } + ; + +source_cit_text_sect : OPEN DELIM TAG_TEXT DELIM line_item + { OPEN(TEXT) } + source_cit_text_subs + { CHECK0 } + CLOSE { } + ; + +source_cit_text_subs : /* empty */ + | source_cit_text_subs source_cit_text_sub + ; + +source_cit_text_sub : continuation_sub + ; + +source_cit_quay_sect : OPEN DELIM TAG_QUAY DELIM line_item CLOSE { } + ; + +source_cit_emb_sect : OPEN DELIM TAG_SOUR DELIM line_item + { OPEN(SOUR) } + source_cit_emb_subs + { CHECK0 } + CLOSE { } + ; + +source_cit_emb_subs : /* empty */ + | source_cit_emb_subs source_cit_emb_sub + ; + +source_cit_emb_sub : continuation_sub + | source_cit_text_sect /* 0:M */ + | note_struc_sub + ; + +/* SOURCE REPOSITORY CITATION */ +source_repos_cit_sub : source_repos_repo_sect { OCCUR2(REPO, 0, 1) } + ; + +source_repos_repo_sect : OPEN DELIM TAG_REPO DELIM POINTER + { OPEN(REPO) } + source_repos_repo_subs + { CHECK0 } + CLOSE { } + ; + +source_repos_repo_subs : /* empty */ + | source_repos_repo_subs source_repos_repo_sub + ; + +source_repos_repo_sub : note_struc_sub + | caln_sect /* 0:M */ + ; + +caln_sect : OPEN DELIM TAG_CALN DELIM line_item + { OPEN(CALN) } + caln_subs + { CHECK0 } + CLOSE { } + ; + +caln_subs : /* empty */ + | caln_subs caln_sub + ; + +caln_sub : caln_medi_sect { OCCUR2(MEDI, 0, 1) } + ; + +caln_medi_sect : OPEN DELIM TAG_MEDI DELIM line_item CLOSE { } + ; + +/* SPOUSE TO FAMILY LINK */ +spou_fam_link_sub : spou_fam_fams_sect /* 0:M */ + ; + +spou_fam_fams_sect : OPEN DELIM TAG_FAMS DELIM POINTER + { OPEN(FAMS) } + spou_fam_fams_subs + { CHECK0 } + CLOSE { } + ; + +spou_fam_fams_subs : /* empty */ + | spou_fam_fams_subs spou_fam_fams_sub + ; + +spou_fam_fams_sub : note_struc_sub + ; + +/*********************************************************************/ +/**** General ****/ +/*********************************************************************/ + +user_sect : OPEN DELIM opt_xref USERTAG + { if ($4[0] != '_') { + gedcom_error("Undefined tag (and not a valid user tag): %s", + $4); + YYERROR; + } + } + opt_value user_sects CLOSE { } + ; + +user_sects : /* empty */ { } + | user_sects user_sect { } + ; + +opt_xref : /* empty */ { } + | POINTER DELIM { } + ; + +opt_value : /* empty */ { } + | DELIM line_value { } + ; + +line_value : POINTER { } + | line_item { } + ; + +opt_line_item : /* empty */ { } + | DELIM line_item { } + ; + +line_item : anychar { } + | ESCAPE { } + | line_item anychar { } + | line_item ESCAPE { } + ; + +anychar : ANYCHAR { } + | DELIM { } + ; + +/* +gen_sect : OPEN DELIM opt_xref anytag + { INVALID_TAG($4); } + opt_value opt_sects CLOSE + { } + ; + +gen_rec : OPEN DELIM opt_xref anytag + { INVALID_TOP_TAG($4) } + opt_value opt_sects CLOSE + { } + ; + +opt_sects : { } + | opt_sects gen_sect { } + ; + +anytag : TAG_ABBR + | TAG_ADDR + | TAG_ADR1 + | TAG_ADR2 { } + | TAG_ADOP { } + | TAG_AFN { } + | TAG_AGE { } + | TAG_AGNC { } + | TAG_ALIA { } + | TAG_ANCE { } + | TAG_ANCI { } + | TAG_ANUL { } + | TAG_ASSO { } + | TAG_AUTH { } + | TAG_BAPL { } + | TAG_BAPM { } + | TAG_BARM { } + | TAG_BASM { } + | TAG_BIRT { } + | TAG_BLES { } + | TAG_BLOB { } + | TAG_BURI { } + | TAG_CALN { } + | TAG_CAST { } + | TAG_CAUS { } + | TAG_CENS { } + | TAG_CHAN { } + | TAG_CHAR { } + | TAG_CHIL { } + | TAG_CHR { } + | TAG_CHRA { } + | TAG_CITY { } + | TAG_CONC { } + | TAG_CONF { } + | TAG_CONL { } + | TAG_CONT { } + | TAG_COPR { } + | TAG_CORP { } + | TAG_CREM { } + | TAG_CTRY { } + | TAG_DATA { } + | TAG_DATE { } + | TAG_DEAT { } + | TAG_DESC { } + | TAG_DESI { } + | TAG_DEST { } + | TAG_DIV { } + | TAG_DIVF { } + | TAG_DSCR { } + | TAG_EDUC { } + | TAG_EMIG { } + | TAG_ENDL { } + | TAG_ENGA { } + | TAG_EVEN { } + | TAG_FAM { } + | TAG_FAMC { } + | TAG_FAMS { } + | TAG_FCOM { } + | TAG_FILE { } + | TAG_FORM { } + | TAG_GEDC { } + | TAG_GIVN { } + | TAG_GRAD { } + | TAG_HEAD { } + | TAG_HUSB { } + | TAG_IDNO { } + | TAG_IMMI { } + | TAG_INDI { } + | TAG_LANG { } + | TAG_LEGA { } + | TAG_MARB { } + | TAG_MARC { } + | TAG_MARL { } + | TAG_MARR { } + | TAG_MARS { } + | TAG_MEDI { } + | TAG_NAME { } + | TAG_NATI { } + | TAG_NCHI { } + | TAG_NICK { } + | TAG_NMR { } + | TAG_NOTE { } + | TAG_NPFX { } + | TAG_NSFX { } + | TAG_OBJE { } + | TAG_OCCU { } + | TAG_ORDI { } + | TAG_ORDN { } + | TAG_PAGE { } + | TAG_PEDI { } + | TAG_PHON { } + | TAG_PLAC { } + | TAG_POST { } + | TAG_PROB { } + | TAG_PROP { } + | TAG_PUBL { } + | TAG_QUAY { } + | TAG_REFN { } + | TAG_RELA { } + | TAG_RELI { } + | TAG_REPO { } + | TAG_RESI { } + | TAG_RESN { } + | TAG_RETI { } + | TAG_RFN { } + | TAG_RIN { } + | TAG_ROLE { } + | TAG_SEX { } + | TAG_SLGC { } + | TAG_SLGS { } + | TAG_SOUR { } + | TAG_SPFX { } + | TAG_SSN { } + | TAG_STAE { } + | TAG_STAT { } + | TAG_SUBM { } + | TAG_SUBN { } + | TAG_SURN { } + | TAG_TEMP { } + | TAG_TEXT { } + | TAG_TIME { } + | TAG_TITL { } + | TAG_TRLR { } + | TAG_TYPE { } + | TAG_VERS { } + | TAG_WIFE { } + | TAG_WILL { } +*/ +%% + +/* Functions that handle the counting of subtags */ + +int* count_arrays[MAXGEDCOMLEVEL+1]; +char tag_stack[MAXGEDCOMLEVEL+1][MAXSTDTAGLENGTH+1]; + +void push_countarray() +{ + int *count = NULL; + if (count_level > MAXGEDCOMLEVEL) { + gedcom_error("Internal error: count array overflow"); + exit(1); + } + else { + count = (int *)calloc(YYNTOKENS, sizeof(int)); + if (count == NULL) { int *count = count_arrays[count_level]; + + gedcom_error("Internal error: count array calloc error"); + exit(1); + } + else { + count_arrays[count_level] = count; + } + } +} + +void set_parenttag(char* tag) +{ + strncpy(tag_stack[count_level], tag, MAXSTDTAGLENGTH+1); +} + +char* get_parenttag() +{ + return tag_stack[count_level]; +} + +int count_tag(int tag) +{ + int *count = count_arrays[count_level]; + return ++count[tag - GEDCOMTAGOFFSET]; +} + +int check_occurrence(int tag) +{ + int *count = count_arrays[count_level]; + return (count[tag - GEDCOMTAGOFFSET] > 0); +} + +void pop_countarray() +{ + int *count; + if (count_level < 0) { + gedcom_error("Internal error: count array underflow"); + exit(1); + } + else { + count = count_arrays[count_level]; + free(count); + count_arrays[count_level] = NULL; + } +} + +/* Enabling debug mode */ + +void gedcom_enable_debug() +{ +#if YYDEBUG != 0 + gedcom_debug = 1; +#endif +} + +/* Setting the error mechanism */ + +void gedcom_set_error_handling(MECHANISM mechanism) +{ + curr_mechanism = mechanism; +} + diff --git a/standalone.c b/standalone.c new file mode 100644 index 0000000..a699e41 --- /dev/null +++ b/standalone.c @@ -0,0 +1,26 @@ +/* $Id$ */ +/* $Name$ */ + +#include "gedcom.h" + +int main(int argc, char* argv[]) +{ + if ((argc > 1) && !strncmp(argv[1], "-d", 2)) + gedcom_enable_debug(); + gedcom_set_error_handling(IGNORE_RECORD); + gedcom_parse(); +} + +int gedcom_error(char* s, ...) +{ + int res; + va_list ap; + + va_start(ap, s); + fprintf(stderr, "Line %d: ", line_no); + res = vfprintf(stderr, s, ap); + fprintf(stderr, "\n"); + va_end(ap); + + return res; +} diff --git a/t/allged.ged b/t/allged.ged new file mode 100644 index 0000000..3139859 --- /dev/null +++ b/t/allged.ged @@ -0,0 +1,1159 @@ +0 HEAD +1 CHAR ASCII +2 VERS Version number of ASCII (whatever it means) +1 SOUR APPROVED_SOURCE_NAME +2 VERS Version number of source-program +2 NAME Name of source-program +2 CORP Corporation name +3 ADDR Corporation address line 1 +4 CONT Corporation address line 2 +4 CONT Corporation address line 3 +4 CONT Corporation address line 4 +4 ADR1 Corporation address line 1 +4 ADR2 Corporation address line 2 +4 CITY Corporation address city +4 STAE Corporation address state +4 POST Corporation address ZIP code +4 CTRY Corporation address country +3 PHON Corporation phone number 1 +3 PHON Corporation phone number 2 +3 PHON Corporation phone number 3 (last one!) +2 DATA Name of source data +3 DATE 1 JAN 1998 +3 COPR Copyright of source data +1 DEST Destination of transmission +1 DATE 1 JAN 1998 +2 TIME 13:57:24.80 +1 SUBM @SUBMITTER@ +1 SUBN @SUBMISSION@ +1 FILE ALLGED.GED +1 COPR (C) 1997-2000 by H. Eichmann. You can use and distribute this file freely as long as you do not charge for it +1 GEDC +2 VERS 5.5 +2 FORM LINEAGE-LINKED +1 LANG language +1 NOTE A general note about this file: +2 CONT It demonstrates most of the data which can be submitted using GEDCOM5.5. It shows the relatives of PERSON1: +2 CONT His 2 wifes (PERSON2, PERSON8), his parents (father: PERSON5, mother not given), +2 CONT adoptive parents (mother: PERSON6, father not given) and his 3 children (PERSON3, PERSON4 and PERSON7). +2 CONT In PERSON1, FAMILY1, SUBMITTER, SUBMISSION and SOURCE1 as many datafields as possible are used. +2 CONT All other individuals/families contain no data. Note, that many data tags can appear more than once +2 CONT (in this transmission this is demonstrated with tags: NAME, OCCU, PLACE and NOTE. Seek the word 'another'. +2 CONT The data transmitted here do not make sence. Just the HEAD.DATE tag contains the date of the creation +2 CONT of this file and will change in future Versions! +2 CONT This file is created by H. Eichmann: h.eichmann@@gmx.de. Feel free to copy and use it for any +2 CONT non-commercial purpose. For the creation the GEDCOM standard Release 5.5 (2 JAN 1996) has been used. +2 CONT Copyright: The church of Jesus Christ of latter-day saints, gedcom@@gedcom.org +2 CONT Download it (the GEDCOM 5.5 specs) from: ftp.gedcom.com/pub/genealogy/gedcom. +2 CONT Some Specials: This line is very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long but not too long (255 caharcters is the limit). +2 CONT This @@ (commercial at) character may only appear ONCE! +2 CONT Note continued here. The word TE +2 CONC ST should not be broken! +1 _MYOWNTAG This is a non-standard tag. Not recommended but allowed +0 @SUBMITTER@ SUBM +1 NAME /Submitter-Name/ +1 ADDR Submitter address line 1 +2 CONT Submitter address line 2 +2 CONT Submitter address line 3 +2 CONT Submitter address line 4 +2 ADR1 Submitter address line 1 +2 ADR2 Submitter address line 2 +2 CITY Submitter address city +2 STAE Submitter address state +2 POST Submitter address ZIP code +2 CTRY Submitter address country +1 PHON Submitter phone number 1 +1 PHON Submitter phone number 2 +1 PHON Submitter phone number 3 (last one!) +1 LANG English +1 CHAN +2 DATE 19 JUN 2000 +3 TIME 12:34:56.789 +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 _MYOWNTAG This is a non-standard tag. Not recommended but allowed +0 @SUBMISSION@ SUBN +1 _MYOWNTAG SUBN does not allow NOTE tags :-(( so, here is my not: SUBN seems to be LDS internal data. The sample data I put in here are probably nonsence. +1 SUBM @SUBMITTER@ +1 FAMF NameOfFamilyFile +1 TEMP Abreviated temple code +1 ANCE 1 +1 DESC 1 +1 ORDI yes +0 @PERSON1@ INDI +1 NAME given name /surname/jr. +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE BEF 1 JAN 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 0 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE Personal Name note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 NAME another name /surname/ +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE AFT 1 JAN 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 1 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE Personal Name note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 SEX M +1 BIRT +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 2 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE BIRTH event note (the event of entering into life) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 FAMC @PARENTS@ +1 CHR +2 DATE BEF 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE CHRISTENING event note (the religious event (not LDS) of baptizing and/or naming a child) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 CHR +2 DATE AFT 30 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE Alternative CHRISTENING event note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 DEAT +2 DATE BET 31 DEC 1997 AND 1 JAN 1998 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE DEATH event note (the event when mortal life terminates) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 BURI +2 DATE ABT 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE BURIAL event note (the event of the proper disposing of the mortal remains of a deceased person) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 CREM Y +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE Cremation event note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 ADOP +2 DATE CAL 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE ADOPTION event note (pertaining to creation of a child-parent relationship that does not exist biologically) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 FAMC @ADOPTIVE_PARENTS@ +3 ADOP BOTH +1 BAPM +2 DATE EST 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE BAPTISM event note (the event of baptism (not LDS), performed in infancy or later. See also BAPL, above, and CHR) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 BARM +2 DATE INT 31 DEC 1997 (12/31/97) +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE BAR_MITZVAH event note (the ceremonial event held when a Jewish boy reaches age 13) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 BASM +2 DATE FROM 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE BAS_MITZVAH event note (the ceremonial event held when a Jewish girl reaches age 13, also known as "Bat Mitzvah.") +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 BLES +2 DATE TO 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE BLESSING event note (a religious event of bestowing divine care or intercession. Sometimes given in connection with a naming ceremony) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 CHRA +2 DATE FROM 31 DEC 1997 TO 1 FEB 1998 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE ADULT_CHRISTENING event note (the religious event (not LDS) of baptizing and/or naming an adult person) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 CONF +2 DATE @#DGREGORIAN@ 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE CONFIRMATION event note (the religious event (not LDS) of conferring the gift of the Holy Ghost and, among protestants, full church membership) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 FCOM +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE FIRST_COMMUNION event note (a religious rite, the first act of sharing in the Lord's supper as part of church worship) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 ORDN +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE ORDINATION event note (a religious event of receiving authority to act in religious matters) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 NATU +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE NATURALIZATION event note (the event of obtaining citizenship) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 EMIG +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE EMIGRATION event note (an event of leaving one's homeland with the intent of residing elsewhere) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 IMMI +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE IMMIGRATION event note (an event of entering into a new locality with the intent of residing there) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 CENS +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE CENSUS event note (the event of the periodic count of the population for a designated locality, such as a national or state Census) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 PROB +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE PROBATE event note (an event of judicial determination of the validity of a will. May indicate several related court activities over several dates) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 WILL +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE WILL event note (a legal document treated as an event, by which a person disposes of his or her estate, to take effect after death. The event date is the date the will was signed while the person was alive. See also PROBate) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 GRAD +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE GRADUATION event note (an event of awarding educational diplomas or degrees to individuals) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 RETI +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE RETIREMENT event note (an event of exiting an occupational relationship with an employer after a qualifying time period) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 EVEN +2 TYPE Event type +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE EVENT note (a noteworthy happening related to an individual, a group, or an organization) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 CAST Cast name +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE CASTE event note (the name of an individual's rank or status in society, based on racial or religious differences, or differences in wealth, inherited rank, profession, occupation, etc) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 DSCR Physical description +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE PHY_DESCRIPTION event note (the physical characteristics of a person, place, or thing) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 EDUC Education +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE EDUCATION event note (Indicator of a level of education attained) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 IDNO 6942 +2 TYPE type of ID number +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE IDENT_NUMBER event note (A number assigned to identify a person within some significant external system) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 NATI National or tribe origin +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE NATIONALITY event note (the national heritage of an individual) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 NCHI 42 +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE Children number event note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 NMR 42 +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE Marriages number event note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 OCCU Occupation +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE OCCUPATION event note (The type of work or profession of an individual) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 OCCU Another occupation +2 DATE 31 DEC 1998 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE Occupation event note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 PROP Possessions +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE PROPERTY event note (pertaining to possessions such as real estate or other property of interest) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 RELI Religion +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE RELIGION event note (a religious denomination to which a person is affiliated or for which a record applies) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 RESI +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE RESIDENCE event note (The act of dwelling at an address for a period of time) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 SSN 6942 +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE SOC_SEC_NUMBER event note (a number assigned by the United States Social Security Administration. Used for tax identification purposes) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 TITL Nobility title +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE TITLE event note (a description of a specific writing or other work, such as the title of a book when used in a source context, or a formal designation used by an individual in connection with positions of royalty or other social status, +3 CONT such as Grand Duke) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 FAMC @PARENTS@ +2 PEDI birth +2 NOTE Note about the link to parents +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 NOTE Another note about the link to parents +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 FAMC @ADOPTIVE_PARENTS@ +2 PEDI adopted +2 NOTE Note about the link to adoptive parents +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 FAMS @FAMILY1@ +2 NOTE Note about the link to spouse +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 NOTE Another note about the link to spouse +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 FAMS @FAMILY2@ +1 SOUR @SOURCE1@ +2 PAGE 42 +2 DATA +3 DATE 31 DEC 1900 +3 TEXT a sample text +4 CONT Sample text continued here. The word TE +4 CONC ST should not be broken! +2 QUAY 0 +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 OBJE +2 FORM gif +2 TITL A gif picture +2 FILE \\network\drive\path\file name.gif +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 NOTE A note about the inidvidual +2 CONT Note continued here. The word TE +2 CONC ST should not be broken! +1 CHAN +2 DATE 1 APR 1998 +3 TIME 12:34:56.789 +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 _MYOWNTAG This is a non-standard tag. Not recommended but allowed +0 @PERSON2@ INDI +1 NAME /Wife/ +1 SEX F +1 FAMS @FAMILY1@ +0 @PERSON3@ INDI +1 NAME /Child 1/ +1 FAMC @FAMILY1@ +0 @PERSON4@ INDI +1 NAME /Child 2/ +1 FAMC @FAMILY1@ +0 @PERSON5@ INDI +1 NAME /Father/ +1 SEX M +1 FAMS @PARENTS@ +0 @PERSON6@ INDI +1 NAME /Adoptive mother/ +1 SEX F +1 FAMS @ADOPTIVE_PARENTS@ +0 @PERSON7@ INDI +1 NAME /Child 3/ +1 FAMC @FAMILY2@ +0 @PERSON8@ INDI +1 NAME /2nd Wife/ +1 SEX F +1 FAMS @FAMILY2@ +0 @FAMILY1@ FAM +1 ANUL +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE ANNULMENT event note (declaring a marriage void from the beginning (never existed)) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y +2 WIFE +3 AGE 42y 6m +1 CENS +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE CENSUS event note (the event of the periodic count of the population for a designated locality, such as a national or state Census) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y 6m 9d +2 WIFE +3 AGE 6m 9d +1 DIV +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE DIVORCE event note (an event of dissolving a marriage through civil action) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y 3d +2 WIFE +3 AGE 42m +1 DIVF +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE DIVORCE_FILED event note (an event of filing for a divorce by a spouse) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42d +2 WIFE +3 AGE CHILD +1 ENGA +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE ENGAGEMENT event note (an event of recording or announcing an agreement between two people to become married) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y +2 WIFE +3 AGE STILLBORN +1 MARR +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE MARRIAGE event note (a legal, common-law, or customary event of creating a family unit of a man and a woman as husband and wife) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y +2 WIFE +3 AGE 42y 6m +1 MARB +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE MARRIAGE_BANN event note (an event of an official public notice given that two people intend to marry) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y +2 WIFE +3 AGE 42y 6m +1 MARC +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE MARR_CONTRACT event note (an event of recording a formal agreement of marriage, including the prenuptial agreement in which marriage partners reach agreement about the property rights of one or both, securing property to their children) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y +2 WIFE +3 AGE >42y 6m +1 MARL +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE MARR_LICENSE event note (an event of obtaining a legal license to marry) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y +2 WIFE +3 AGE <42y 6m +1 MARS +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE MARR_SETTLEMENT event note (an event of creating an agreement between two people contemplating marriage, at which time they agree to release or modify property rights that would otherwise arise from the marriage) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y +2 WIFE +3 AGE INFANT +1 EVEN +2 TYPE Other event type +2 DATE 31 DEC 1997 +2 PLAC The place +2 SOUR @SOURCE1@ +3 PAGE 42 +3 DATA +4 DATE 31 DEC 1900 +4 TEXT a sample text +5 CONT Sample text continued here. The word TE +5 CONC ST should not be broken! +3 QUAY 3 +3 NOTE A note +4 CONT Note continued here. The word TE +4 CONC ST should not be broken! +2 NOTE EVENT note (a noteworthy happening related to an individual, a group, or an organization) +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +2 HUSB +3 AGE 42y +2 WIFE +3 AGE 42y 6m +1 HUSB @PERSON1@ +1 WIFE @PERSON2@ +1 CHIL @PERSON3@ +1 CHIL @PERSON4@ +1 NCHI 42 +1 SOUR @SOURCE1@ +2 PAGE 42 +2 DATA +3 DATE 31 DEC 1900 +3 TEXT a sample text +4 CONT Sample text continued here. The word TE +4 CONC ST should not be broken! +2 QUAY 0 +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 OBJE +2 FORM bmp +2 TITL A bmp picture +2 FILE \\network\drive\path\file name.bmp +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 NOTE A note about the family +2 CONT Note continued here. The word TE +2 CONC ST should not be broken! +1 CHAN +2 DATE 1 APR 1998 +3 TIME 12:34:56.789 +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 _MYOWNTAG This is a non-standard tag. Not recommended but allowed +0 @PARENTS@ FAM +1 HUSB @PERSON5@ +1 CHIL @PERSON1@ +0 @ADOPTIVE_PARENTS@ FAM +1 WIFE @PERSON6@ +1 CHIL @PERSON1@ +0 @FAMILY2@ FAM +1 HUSB @PERSON1@ +1 WIFE @PERSON8@ +1 CHIL @PERSON7@ +0 @SOURCE1@ SOUR +1 DATA +2 EVEN BIRT, CHR +3 DATE FROM 1 JAN 1980 TO 1 FEB 1982 +3 PLAC Place +2 EVEN DEAT +3 DATE FROM 1 JAN 1980 TO 1 FEB 1982 +3 PLAC Another place +2 AGNC Resposible agency +2 NOTE A note about whatever +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 AUTH Author of source +2 CONT Author continued here. The word TE +2 CONC ST should not be broken! +1 TITL Title of source +2 CONT Title continued here. The word TE +2 CONC ST should not be broken! +1 ABBR Short title +1 PUBL Source publication facts +2 CONT Publication facts continued here. The word TE +2 CONC ST should not be broken! +1 TEXT Citation from source +2 CONT Citation continued here. The word TE +2 CONC ST should not be broken! +1 OBJE +2 FORM bmp +2 TITL A bmp picture +2 FILE \\network\drive\path\file name.bmp +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 NOTE A note about the family +2 CONT Note continued here. The word TE +2 CONC ST should not be broken! +1 CHAN +2 DATE 1 APR 1998 +3 TIME 12:34:56.789 +2 NOTE A note +3 CONT Note continued here. The word TE +3 CONC ST should not be broken! +1 _MYOWNTAG This is a non-standard tag. Not recommended but allowed +0 _MYOWNTAG This is a non-standard tag. Not recommended but allowed +0 TRLR diff --git a/t/ansel.ged b/t/ansel.ged new file mode 100644 index 0000000..e01c470 --- /dev/null +++ b/t/ansel.ged @@ -0,0 +1,315 @@ +0 HEAD +1 CHAR ANSEL +1 SOUR REGISTERED_SOURCE_NAME +1 GEDC +2 VERS 5.5 +2 FORM Lineage-Linked +1 NOTE This GEDCOM transmission contains a charcter set test. It consists +2 CONT of a single family (two parents, many children). The parents are empty +2 CONT in the ANSEL version of the transmission. The children contain the +2 CONT combined letters and the special charcters (value > 128). +2 CONT The NAME tag of each 'person' is the name of the characters tested +2 CONT within the person. The BIRT.PLAC and DEAT.PLAC tags contain the +2 CONT test-strings. +2 CONT The first children contain special characters. Here the test string +2 CONT is 'character name (test character), ...' where 'character name' +2 CONT is the name of the character (like 'british pound') and +2 CONT 'test character' is a single byte representing this character +2 CONT in ANSEL. +2 CONT The last children contain combined characters. The name tag gives +2 CONT the name of the non-spacing character tested within the 'person'. +2 CONT Within the name the hex-values of the non-spacing character is given +2 CONT in ANSEL and UNICODE. The test strings contain the whole latin +2 CONT alphabet combined with this non-spacing character: captial letters +2 CONT in the BIRT.PLAC tag and small letters in the DEAT.PLAC tag. +2 CONT Example: One 'person' is named 'circle above'. The BIRT.PLAC +2 CONT tag contains all 26 capital letters with a small ring on top. +2 CONT Note: Not all charcters can be displayed on all computers. +2 CONT This strongly depends on the installed fonts and codepages. +2 CONT Many of the combined characters generated here do not even have +2 CONT a UNICDOE code point! +2 CONT This file based mainly on the GEDCOM 5.5 specification +2 CONT (see: ftp.gedcom.org/pub/genealogy/gedcom/gedcom55.zip) +2 CONT and on an updated ANSEL description in: +2 CONT http://www.gendex.com/gedcom55/55gcappd.htm +1 SUBM @SUBMITTER@ +1 DATE 20 JAN 1998 +0 @SUBMITTER@ SUBM +1 NAME /H. Eichmann/ +1 ADDR email: h.eichmann@@gmx.de +0 @FATHER@ INDI +1 NAME /cyrillic (not possible in ANSEL)/ +1 SEX M +1 FAMS @FAMILY@ +0 @MOTHER@ INDI +1 NAME /greek (not possible in ANSEL)/ +1 SEX F +1 FAMS @FAMILY@ +0 @CHILD0@ INDI +1 FAMC @FAMILY@ +1 NAME /Special Characters 0/ +1 BIRT +2 PLAC slash l - uppercase (¡), slash o - uppercase (¢), slash d - uppercase (£), thorn - uppercase (¤) +1 DEAT +2 PLAC ligature ae - uppercase (¥), ligature oe - uppercase (¦), miagkii znak (§), middle dot (¨), musical flat (©) +0 @CHILD1@ INDI +1 FAMC @FAMILY@ +1 NAME /Special Characters 1/ +1 BIRT +2 PLAC patent mark (ª), plus-or-minus («), hook o - uppercase (¬), hook u - uppercase (­) +1 DEAT +2 PLAC alif (®), ayn (°), slash l - lowercase (±), slash o - lowercase (²), slash d - lowercase (³) +0 @CHILD2@ INDI +1 FAMC @FAMILY@ +1 NAME /Special Characters 2/ +1 BIRT +2 PLAC thorn - lowercase (´), ligature ae - lowercase (µ), ligature oe - lowercase (¶), tverdyi znak (·) +1 DEAT +2 PLAC dotless i - lowercase (¸), british pound (¹), eth (º), hook o - lowercase (¼), hook u - lowercase (½) +0 @CHILD3@ INDI +1 FAMC @FAMILY@ +1 NAME /Special Characters 3/ +1 BIRT +2 PLAC degree sign (À), script l (Á), phonograph copyright mark (Â), copyright symbol (Ã) +1 DEAT +2 PLAC musical sharp (Ä), inverted question mark (Å), inverted exclamation mark (Æ), es zet (Ï) +0 @CHILD4@ INDI +1 FAMC @FAMILY@ +1 NAME code: E0 (Unicode: hook above, 0309)/low rising tone mark/ +1 BIRT +2 PLAC àAàBàCàDàEàFàGàHàIàJàKàLàMàNàOàPàQàRàSàTàUàVàWàXàYàZ +1 DEAT +2 PLAC àaàbàcàdàeàfàgàhàiàjàkàlàmànàoàpàqàràsàtàuàvàwàxàyàz +0 @CHILD5@ INDI +1 FAMC @FAMILY@ +1 NAME code: E1 (Unicode: grave, 0300)/grave accent/ +1 BIRT +2 PLAC áAáBáCáDáEáFáGáHáIáJáKáLáMáNáOáPáQáRáSáTáUáVáWáXáYáZ +1 DEAT +2 PLAC áaábácádáeáfágáháiájákálámánáoápáqárásátáuáváwáxáyáz +0 @CHILD6@ INDI +1 FAMC @FAMILY@ +1 NAME code: E2 (Unicode: acute, 0301)/acute accent/ +1 BIRT +2 PLAC âAâBâCâDâEâFâGâHâIâJâKâLâMâNâOâPâQâRâSâTâUâVâWâXâYâZ +1 DEAT +2 PLAC âaâbâcâdâeâfâgâhâiâjâkâlâmânâoâpâqârâsâtâuâvâwâxâyâz +0 @CHILD7@ INDI +1 FAMC @FAMILY@ +1 NAME code: E3 (Unicode: circumflex, 0302)/circumflex accent/ +1 BIRT +2 PLAC ãAãBãCãDãEãFãGãHãIãJãKãLãMãNãOãPãQãRãSãTãUãVãWãXãYãZ +1 DEAT +2 PLAC ãaãbãcãdãeãfãgãhãiãjãkãlãmãnãoãpãqãrãsãtãuãvãwãxãyãz +0 @CHILD8@ INDI +1 FAMC @FAMILY@ +1 NAME code: E4 (Unicode: tilde, 0303)/tilde/ +1 BIRT +2 PLAC äAäBäCäDäEäFäGäHäIäJäKäLäMäNäOäPäQäRäSäTäUäVäWäXäYäZ +1 DEAT +2 PLAC äaäbäcädäeäfägähäiäjäkälämänäoäpäqäräsätäuäväwäxäyäz +0 @CHILD9@ INDI +1 FAMC @FAMILY@ +1 NAME code: E5 (Unicode: macron, 0304)/macron/ +1 BIRT +2 PLAC åAåBåCåDåEåFåGåHåIåJåKåLåMåNåOåPåQåRåSåTåUåVåWåXåYåZ +1 DEAT +2 PLAC åaåbåcådåeåfågåhåiåjåkålåmånåoåpåqåråsåtåuåvåwåxåyåz +0 @CHILD10@ INDI +1 FAMC @FAMILY@ +1 NAME code: E6 (Unicode: breve, 0306)/breve/ +1 BIRT +2 PLAC æAæBæCæDæEæFæGæHæIæJæKæLæMæNæOæPæQæRæSæTæUæVæWæXæYæZ +1 DEAT +2 PLAC æaæbæcædæeæfægæhæiæjækælæmænæoæpæqæræsætæuævæwæxæyæz +0 @CHILD11@ INDI +1 FAMC @FAMILY@ +1 NAME code: E7 (Unicode: dot above, 0307)/dot above/ +1 BIRT +2 PLAC çAçBçCçDçEçFçGçHçIçJçKçLçMçNçOçPçQçRçSçTçUçVçWçXçYçZ +1 DEAT +2 PLAC çaçbçcçdçeçfçgçhçiçjçkçlçmçnçoçpçqçrçsçtçuçvçwçxçyçz +0 @CHILD12@ INDI +1 FAMC @FAMILY@ +1 NAME code: E8 (Unicode: diaeresis, 0308)/umlaut (dieresis)/ +1 BIRT +2 PLAC èAèBèCèDèEèFèGèHèIèJèKèLèMèNèOèPèQèRèSèTèUèVèWèXèYèZ +1 DEAT +2 PLAC èaèbècèdèeèfègèhèièjèkèlèmènèoèpèqèrèsètèuèvèwèxèyèz +0 @CHILD13@ INDI +1 FAMC @FAMILY@ +1 NAME code: E9 (Unicode: caron, 030C)/hacek/ +1 BIRT +2 PLAC éAéBéCéDéEéFéGéHéIéJéKéLéMéNéOéPéQéRéSéTéUéVéWéXéYéZ +1 DEAT +2 PLAC éaébécédéeéfégéhéiéjékéléménéoépéqérésétéuévéwéxéyéz +0 @CHILD14@ INDI +1 FAMC @FAMILY@ +1 NAME code: EA (Unicode: ring above, 030A)/circle above (angstrom)/ +1 BIRT +2 PLAC êAêBêCêDêEêFêGêHêIêJêKêLêMêNêOêPêQêRêSêTêUêVêWêXêYêZ +1 DEAT +2 PLAC êaêbêcêdêeêfêgêhêiêjêkêlêmênêoêpêqêrêsêtêuêvêwêxêyêz +0 @CHILD15@ INDI +1 FAMC @FAMILY@ +1 NAME code: EB (Unicode: ligature left half, FE20)/ligature, left half/ +1 BIRT +2 PLAC ëAëBëCëDëEëFëGëHëIëJëKëLëMëNëOëPëQëRëSëTëUëVëWëXëYëZ +1 DEAT +2 PLAC ëaëbëcëdëeëfëgëhëiëjëkëlëmënëoëpëqërësëtëuëvëwëxëyëz +0 @CHILD16@ INDI +1 FAMC @FAMILY@ +1 NAME code: EC (Unicode: ligature right half, FE21)/ligature, right half/ +1 BIRT +2 PLAC ìAìBìCìDìEìFìGìHìIìJìKìLìMìNìOìPìQìRìSìTìUìVìWìXìYìZ +1 DEAT +2 PLAC ìaìbìcìdìeìfìgìhìiìjìkìlìmìnìoìpìqìrìsìtìuìvìwìxìyìz +0 @CHILD17@ INDI +1 FAMC @FAMILY@ +1 NAME code: ED (Unicode: comma above right, 0315)/high comma, off center/ +1 BIRT +2 PLAC íAíBíCíDíEíFíGíHíIíJíKíLíMíNíOíPíQíRíSíTíUíVíWíXíYíZ +1 DEAT +2 PLAC íaíbícídíeífígíhíiíjíkílímíníoípíqírísítíuívíwíxíyíz +0 @CHILD18@ INDI +1 FAMC @FAMILY@ +1 NAME code: EE (Unicode: double acute, 030B)/double acute accent/ +1 BIRT +2 PLAC îAîBîCîDîEîFîGîHîIîJîKîLîMîNîOîPîQîRîSîTîUîVîWîXîYîZ +1 DEAT +2 PLAC îaîbîcîdîeîfîgîhîiîjîkîlîmînîoîpîqîrîsîtîuîvîwîxîyîz +0 @CHILD19@ INDI +1 FAMC @FAMILY@ +1 NAME code: EF (Unicode: candrabindu, 0310)/candrabindu/ +1 BIRT +2 PLAC ïAïBïCïDïEïFïGïHïIïJïKïLïMïNïOïPïQïRïSïTïUïVïWïXïYïZ +1 DEAT +2 PLAC ïaïbïcïdïeïfïgïhïiïjïkïlïmïnïoïpïqïrïsïtïuïvïwïxïyïz +0 @CHILD20@ INDI +1 FAMC @FAMILY@ +1 NAME code: F0 (Unicode: cedilla, 0327)/cedilla/ +1 BIRT +2 PLAC ðAðBðCðDðEðFðGðHðIðJðKðLðMðNðOðPðQðRðSðTðUðVðWðXðYðZ +1 DEAT +2 PLAC ðaðbðcðdðeðfðgðhðiðjðkðlðmðnðoðpðqðrðsðtðuðvðwðxðyðz +0 @CHILD21@ INDI +1 FAMC @FAMILY@ +1 NAME code: F1 (Unicode: ogonek, 0328)/right hook/ +1 BIRT +2 PLAC ñAñBñCñDñEñFñGñHñIñJñKñLñMñNñOñPñQñRñSñTñUñVñWñXñYñZ +1 DEAT +2 PLAC ñañbñcñdñeñfñgñhñiñjñkñlñmñnñoñpñqñrñsñtñuñvñwñxñyñz +0 @CHILD22@ INDI +1 FAMC @FAMILY@ +1 NAME code: F2 (Unicode: dot below, 0323)/dot below/ +1 BIRT +2 PLAC òAòBòCòDòEòFòGòHòIòJòKòLòMòNòOòPòQòRòSòTòUòVòWòXòYòZ +1 DEAT +2 PLAC òaòbòcòdòeòfògòhòiòjòkòlòmònòoòpòqòròsòtòuòvòwòxòyòz +0 @CHILD23@ INDI +1 FAMC @FAMILY@ +1 NAME code: F3 (Unicode: diaeresis below, 0324)/double dot below/ +1 BIRT +2 PLAC óAóBóCóDóEóFóGóHóIóJóKóLóMóNóOóPóQóRóSóTóUóVóWóXóYóZ +1 DEAT +2 PLAC óaóbócódóeófógóhóiójókólómónóoópóqórósótóuóvówóxóyóz +0 @CHILD24@ INDI +1 FAMC @FAMILY@ +1 NAME code: F4 (Unicode: ring below, 0325)/circle below/ +1 BIRT +2 PLAC ôAôBôCôDôEôFôGôHôIôJôKôLôMôNôOôPôQôRôSôTôUôVôWôXôYôZ +1 DEAT +2 PLAC ôaôbôcôdôeôfôgôhôiôjôkôlômônôoôpôqôrôsôtôuôvôwôxôyôz +0 @CHILD25@ INDI +1 FAMC @FAMILY@ +1 NAME code: F5 (Unicode: double low line, 0333)/double underscore/ +1 BIRT +2 PLAC õAõBõCõDõEõFõGõHõIõJõKõLõMõNõOõPõQõRõSõTõUõVõWõXõYõZ +1 DEAT +2 PLAC õaõbõcõdõeõfõgõhõiõjõkõlõmõnõoõpõqõrõsõtõuõvõwõxõyõz +0 @CHILD26@ INDI +1 FAMC @FAMILY@ +1 NAME code: F6 (Unicode: line below, 0332)/underscore/ +1 BIRT +2 PLAC öAöBöCöDöEöFöGöHöIöJöKöLöMöNöOöPöQöRöSöTöUöVöWöXöYöZ +1 DEAT +2 PLAC öaöböcödöeöfögöhöiöjökölömönöoöpöqörösötöuövöwöxöyöz +0 @CHILD27@ INDI +1 FAMC @FAMILY@ +1 NAME code: F7 (Unicode: comma below, 0326)/left hook/ +1 BIRT +2 PLAC ÷A÷B÷C÷D÷E÷F÷G÷H÷I÷J÷K÷L÷M÷N÷O÷P÷Q÷R÷S÷T÷U÷V÷W÷X÷Y÷Z +1 DEAT +2 PLAC ÷a÷b÷c÷d÷e÷f÷g÷h÷i÷j÷k÷l÷m÷n÷o÷p÷q÷r÷s÷t÷u÷v÷w÷x÷y÷z +0 @CHILD28@ INDI +1 FAMC @FAMILY@ +1 NAME code: F8 (Unicode: left half ring below, 031C)/right cedilla/ +1 BIRT +2 PLAC øAøBøCøDøEøFøGøHøIøJøKøLøMøNøOøPøQøRøSøTøUøVøWøXøYøZ +1 DEAT +2 PLAC øaøbøcødøeøføgøhøiøjøkølømønøoøpøqørøsøtøuøvøwøxøyøz +0 @CHILD29@ INDI +1 FAMC @FAMILY@ +1 NAME code: F9 (Unicode: breve below, 032E)/half circle below/ +1 BIRT +2 PLAC ùAùBùCùDùEùFùGùHùIùJùKùLùMùNùOùPùQùRùSùTùUùVùWùXùYùZ +1 DEAT +2 PLAC ùaùbùcùdùeùfùgùhùiùjùkùlùmùnùoùpùqùrùsùtùuùvùwùxùyùz +0 @CHILD30@ INDI +1 FAMC @FAMILY@ +1 NAME code: FA (Unicode: double tilde left half, FE22)/double tilde, left half/ +1 BIRT +2 PLAC úAúBúCúDúEúFúGúHúIúJúKúLúMúNúOúPúQúRúSúTúUúVúWúXúYúZ +1 DEAT +2 PLAC úaúbúcúdúeúfúgúhúiújúkúlúmúnúoúpúqúrúsútúuúvúwúxúyúz +0 @CHILD31@ INDI +1 FAMC @FAMILY@ +1 NAME code: FB (Unicode: double tilde right half, FE23)/double tilde, right half/ +1 BIRT +2 PLAC ûAûBûCûDûEûFûGûHûIûJûKûLûMûNûOûPûQûRûSûTûUûVûWûXûYûZ +1 DEAT +2 PLAC ûaûbûcûdûeûfûgûhûiûjûkûlûmûnûoûpûqûrûsûtûuûvûwûxûyûz +0 @CHILD32@ INDI +1 FAMC @FAMILY@ +1 NAME code: FE (Unicode: comma above, 0313)/high comma, centered/ +1 BIRT +2 PLAC þAþBþCþDþEþFþGþHþIþJþKþLþMþNþOþPþQþRþSþTþUþVþWþXþYþZ +1 DEAT +2 PLAC þaþbþcþdþeþfþgþhþiþjþkþlþmþnþoþpþqþrþsþtþuþvþwþxþyþz +0 @FAMILY@ FAM +1 HUSB @FATHER@ +1 WIFE @MOTHER@ +1 CHIL @CHILD0@ +1 CHIL @CHILD1@ +1 CHIL @CHILD2@ +1 CHIL @CHILD3@ +1 CHIL @CHILD4@ +1 CHIL @CHILD5@ +1 CHIL @CHILD6@ +1 CHIL @CHILD7@ +1 CHIL @CHILD8@ +1 CHIL @CHILD9@ +1 CHIL @CHILD10@ +1 CHIL @CHILD11@ +1 CHIL @CHILD12@ +1 CHIL @CHILD13@ +1 CHIL @CHILD14@ +1 CHIL @CHILD15@ +1 CHIL @CHILD16@ +1 CHIL @CHILD17@ +1 CHIL @CHILD18@ +1 CHIL @CHILD19@ +1 CHIL @CHILD20@ +1 CHIL @CHILD21@ +1 CHIL @CHILD22@ +1 CHIL @CHILD23@ +1 CHIL @CHILD24@ +1 CHIL @CHILD25@ +1 CHIL @CHILD26@ +1 CHIL @CHILD27@ +1 CHIL @CHILD28@ +1 CHIL @CHILD29@ +1 CHIL @CHILD30@ +1 CHIL @CHILD31@ +1 CHIL @CHILD32@ +0 TRLR