parser with preprocessing works

This commit is contained in:
vrd
2023-02-25 18:24:43 +02:00
parent 176ca1c85a
commit 222c3e43be
+31 -27
View File
@@ -27,14 +27,13 @@ namespace /* internal */
} }
}; };
char* it_data;
char* end_data; /* past the end pointer */ char* end_data; /* past the end pointer */
unsigned line = 1; unsigned line = 1;
pair<person_id, person_id> prev_parents(Nobody, Nobody);
/* state */ /* state */
void (*state)(); /* current state */ void state_neutral(char* it_data);
void state_neutral(); void state_person(char*& it_data);
void state_person();
/* void state_person_attribute() */ /* void state_person_attribute() */
/* result */ /* result */
@@ -54,7 +53,7 @@ namespace /* internal */
exit(1); exit(1);
} }
void proceedToNameEnd() void proceedToNameEnd(char*& it_data)
{ {
while(it_data < end_data && while(it_data < end_data &&
*it_data != ',' && *it_data != ',' &&
@@ -67,7 +66,7 @@ namespace /* internal */
} }
Sex findSex() Sex findSex(char*& it_data)
{ {
Sex res = M; Sex res = M;
if(*it_data == ',') if(*it_data == ',')
@@ -87,7 +86,7 @@ namespace /* internal */
return res; return res;
} }
I32 processDatePart() I32 processDatePart(char*& it_data)
{ {
I32 sign = 1; I32 sign = 1;
I32 val = 0; I32 val = 0;
@@ -118,25 +117,25 @@ namespace /* internal */
unexpected_end(); unexpected_end();
} }
EventTime processDate() /* todo validate */ EventTime processDate(char*& it_data) /* todo validate */
{ {
EventTime date; EventTime date;
date.year = processDatePart(); date.year = processDatePart(it_data);
if(*it_data == '.') if(*it_data == '.')
{ {
++it_data; ++it_data;
date.month = processDatePart(); date.month = processDatePart(it_data);
if(*it_data == '.') if(*it_data == '.')
{ {
++it_data; ++it_data;
date.day = processDatePart(); date.day = processDatePart(it_data);
} }
} }
return date; return date;
} }
pair<person_id, person_id> processParents() pair<person_id, person_id> processParents(char*& it_data)
{ {
pair<person_id, person_id> res(Nobody, Nobody); pair<person_id, person_id> res(Nobody, Nobody);
string name; /* todo dont use string */ string name; /* todo dont use string */
@@ -144,7 +143,6 @@ namespace /* internal */
{ {
switch(*it_data) switch(*it_data)
{ {
/* case '-':todo */
case ',': case ',':
if(res.first == Nobody) if(res.first == Nobody)
res.first = cur_tree->findId(name.data()); res.first = cur_tree->findId(name.data());
@@ -154,13 +152,18 @@ namespace /* internal */
/* todo */exit(1); /* todo */exit(1);
name.clear(); name.clear();
break; break;
case '-':
if(name.empty() && res.first == Nobody)
return prev_parents;
else
unexpected_char('-');
case '\n': case '\n':
++line; ++line;
if(res.first == Nobody) if(res.first == Nobody)
res.first = cur_tree->findId(name.data()); res.first = cur_tree->findId(name.data());
else else
res.second = cur_tree->findId(name.data()); res.second = cur_tree->findId(name.data());
return res; return prev_parents = res;
default: default:
name.push_back(*it_data); name.push_back(*it_data);
} }
@@ -168,7 +171,7 @@ namespace /* internal */
} }
vector<person_id> parseSpouses() vector<person_id> parseSpouses(char*& it_data)
{ {
vector<person_id> res; vector<person_id> res;
string name; string name;
@@ -198,14 +201,14 @@ namespace /* internal */
return res; return res;
} }
void state_neutral() void state_neutral(char* it_data)
{ {
for(; it_data < end_data; ++it_data) for(; it_data < end_data; ++it_data)
{ {
switch(*it_data) switch(*it_data)
{ {
default: default:
state_person(); state_person(it_data);
break; break;
case '\n': case '\n':
++line; ++line;
@@ -219,7 +222,7 @@ namespace /* internal */
} }
} }
void state_person() void state_person(char*& it_data)
{ {
char* name_start = it_data; char* name_start = it_data;
pair<person_id, person_id> parents(Nobody, Nobody); pair<person_id, person_id> parents(Nobody, Nobody);
@@ -227,11 +230,11 @@ namespace /* internal */
EventTime birth{}; EventTime birth{};
EventTime death{}; EventTime death{};
proceedToNameEnd(); proceedToNameEnd(it_data);
/* string_view name(name_start, it_data); */ /* string_view name(name_start, it_data); */
string name(name_start, it_data); string name(name_start, it_data);
Sex sex = findSex(); Sex sex = findSex(it_data);
for(; it_data < end_data; ++it_data) for(; it_data < end_data; ++it_data)
{ {
@@ -247,19 +250,19 @@ namespace /* internal */
{ {
case 'b': case 'b':
it_data += 2; it_data += 2;
birth = processDate(); birth = processDate(it_data);
break; break;
case 'd': case 'd':
it_data += 2; it_data += 2;
death = processDate(); death = processDate(it_data);
break; break;
case 'p': case 'p':
it_data += 2; it_data += 2;
parents = processParents(); parents = processParents(it_data);
break; break;
case 's': case 's':
it_data += 2; it_data += 2;
spouses = parseSpouses(); spouses = parseSpouses(it_data);
break; break;
default: default:
unexpected_char(it_data[-1]); unexpected_char(it_data[-1]);
@@ -282,6 +285,9 @@ namespace /* internal */
/* break; */ /* break; */
} }
} }
cur_tree->addPerson(name.c_str(), sex, parents.first, parents.second, birth, death);
for(person_id spouse: spouses)
cur_tree->addRelation(spouse, Spouse, cur_tree->last());
} }
alloced preprocess(MappedFile file) /* remove whitespace and comments */ alloced preprocess(MappedFile file) /* remove whitespace and comments */
@@ -320,10 +326,8 @@ Tree parseTftFile(MappedFile file)
cur_tree = &result; cur_tree = &result;
alloced preprocessed = preprocess(file); alloced preprocessed = preprocess(file);
it_data = preprocessed.data;
/* end_data = preprocessed.end; */
state_neutral(); state_neutral(preprocessed.data);
return result; return result;
} }