mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-09-15 23:06:01 -06:00
use overlapping intervals to detect unifiable terms
This commit is contained in:
@@ -41,13 +41,13 @@ class PGF_INTERNAL_DECL interval_map {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cmp;
|
int cmp;
|
||||||
if (node->start < start)
|
if (start < node->start)
|
||||||
cmp = -1;
|
cmp = -1;
|
||||||
else if (node->start > start)
|
else if (start > node->start)
|
||||||
cmp = 1;
|
cmp = 1;
|
||||||
else if (node->end < end)
|
else if (end < node->end)
|
||||||
cmp = -1;
|
cmp = -1;
|
||||||
else if (node->end > end)
|
else if (end > node->end)
|
||||||
cmp = 1;
|
cmp = 1;
|
||||||
else
|
else
|
||||||
cmp = 0;
|
cmp = 0;
|
||||||
@@ -74,13 +74,13 @@ class PGF_INTERNAL_DECL interval_map {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cmp;
|
int cmp;
|
||||||
if (node->start < start)
|
if (start < node->start)
|
||||||
cmp = -1;
|
cmp = -1;
|
||||||
else if (node->start > start)
|
else if (start > node->start)
|
||||||
cmp = 1;
|
cmp = 1;
|
||||||
else if (node->end < end)
|
else if (end < node->end)
|
||||||
cmp = -1;
|
cmp = -1;
|
||||||
else if (node->end > end)
|
else if (end > node->end)
|
||||||
cmp = 1;
|
cmp = 1;
|
||||||
else
|
else
|
||||||
cmp = 0;
|
cmp = 0;
|
||||||
@@ -383,6 +383,113 @@ public:
|
|||||||
iterator end() const {
|
iterator end() const {
|
||||||
return iterator();
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Overlaps {
|
||||||
|
Node *root;
|
||||||
|
interval_t i;
|
||||||
|
|
||||||
|
public:
|
||||||
|
class iterator {
|
||||||
|
struct Parent {
|
||||||
|
Node *node;
|
||||||
|
Parent *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parent *spine;
|
||||||
|
size_t start, end;
|
||||||
|
|
||||||
|
public:
|
||||||
|
iterator() {
|
||||||
|
spine = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator(Node *node, size_t start, size_t end) {
|
||||||
|
this->start = start;
|
||||||
|
this->end = end;
|
||||||
|
|
||||||
|
spine = NULL;
|
||||||
|
for (;;) {
|
||||||
|
Parent *parent;
|
||||||
|
while (node != NULL && start <= node->max) {
|
||||||
|
parent = new Parent;
|
||||||
|
parent->node = node;
|
||||||
|
parent->next = spine;
|
||||||
|
spine = parent;
|
||||||
|
node = node->left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spine == NULL || (start <= spine->node->end && end >= spine->node->start))
|
||||||
|
return;
|
||||||
|
|
||||||
|
parent = spine->next;
|
||||||
|
node = spine->node->right;
|
||||||
|
delete spine;
|
||||||
|
spine = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const iterator other) const {
|
||||||
|
return this->spine == other.spine;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator !=(const iterator other) const {
|
||||||
|
return this->spine != other.spine;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<interval_t,V&> operator *() const {
|
||||||
|
return std::pair<interval_t,V&>
|
||||||
|
(interval_t(spine->node->start,spine->node->end)
|
||||||
|
,spine->node->value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator ++() {
|
||||||
|
for (;;) {
|
||||||
|
Parent *parent = spine->next;
|
||||||
|
Node *node = spine->node->right;
|
||||||
|
delete spine;
|
||||||
|
spine = parent;
|
||||||
|
|
||||||
|
while (node != NULL && start <= node->max) {
|
||||||
|
parent = new Parent;
|
||||||
|
parent->node = node;
|
||||||
|
parent->next = spine;
|
||||||
|
spine = parent;
|
||||||
|
node = node->left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spine == NULL || (start <= spine->node->end && end >= spine->node->start))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~iterator() {
|
||||||
|
while (spine != NULL) {
|
||||||
|
Parent *parent = spine->next;
|
||||||
|
delete spine;
|
||||||
|
spine = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlaps(Node *root, interval_t i) {
|
||||||
|
this->root = root;
|
||||||
|
this->i = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator begin() const {
|
||||||
|
return iterator(root,i.first,i.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() const {
|
||||||
|
return iterator();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlaps overlaps(interval_t interval)
|
||||||
|
{
|
||||||
|
return Overlaps(this->root, interval);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -43,8 +43,12 @@ PgfAbstractParser::CCat::~CCat()
|
|||||||
|
|
||||||
PgfAbstractParser::Cont::~Cont()
|
PgfAbstractParser::Cont::~Cont()
|
||||||
{
|
{
|
||||||
for (Item *item : suspended) {
|
for (auto it1 : suspended) {
|
||||||
delete item;
|
for (auto it2 : it1.second) {
|
||||||
|
for (Item *item : it2.second) {
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,10 +66,8 @@ PgfAbstractParser::~PgfAbstractParser()
|
|||||||
for (auto it : state->conts1) {
|
for (auto it : state->conts1) {
|
||||||
delete it.second;
|
delete it.second;
|
||||||
}
|
}
|
||||||
for (auto it1 : state->conts2) {
|
for (auto it : state->conts2) {
|
||||||
for (auto it2 : it1.second) {
|
delete it.second;
|
||||||
delete it2.second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
State *next = state->next;
|
State *next = state->next;
|
||||||
@@ -123,12 +125,23 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lincat != 0) {
|
if (lincat != 0) {
|
||||||
suspend(state,lincat,item);
|
Cont *&cont = state->conts1[lincat];
|
||||||
|
if (cont == NULL) {
|
||||||
|
cont = new Cont;
|
||||||
|
cont->ccat = NULL;
|
||||||
|
cont->lincat = lincat;
|
||||||
|
cont->state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
interval_t value_i = item->interval(item->rule->args[symcat->d]);
|
||||||
|
interval_t lin_idx_i = item->interval(ref<PgfLParam>::from_ptr(&symcat->r));
|
||||||
|
auto &suspended = cont->suspended[value_i][lin_idx_i];
|
||||||
|
suspended.push_back(item);
|
||||||
|
|
||||||
|
suspend(cont,item,suspended.size());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
interval_t lin_idx = item->interval(ref<PgfLParam>::from_ptr(&symcat->r));
|
Cont *&cont = state->conts2[ccat];
|
||||||
|
|
||||||
Cont *&cont = state->conts2[ccat][lin_idx];
|
|
||||||
if (cont == NULL) {
|
if (cont == NULL) {
|
||||||
cont = new Cont;
|
cont = new Cont;
|
||||||
cont->ccat = ccat;
|
cont->ccat = ccat;
|
||||||
@@ -139,9 +152,12 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
|
|||||||
cont->state = state;
|
cont->state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
cont->suspended.push_back(item);
|
interval_t value_i = item->interval(item->rule->args[symcat->d]);
|
||||||
|
interval_t lin_idx_i = item->interval(ref<PgfLParam>::from_ptr(&symcat->r));
|
||||||
|
auto &suspended = cont->suspended[value_i][lin_idx_i];
|
||||||
|
suspended.push_back(item);
|
||||||
|
|
||||||
if (cont->suspended.size() == 1) {
|
if (suspended.size() == 1) {
|
||||||
if (ccat->fid <= initial_fid) {
|
if (ccat->fid <= initial_fid) {
|
||||||
size_t n_items = 0;
|
size_t n_items = 0;
|
||||||
vector<ref<PgfItem>> items =
|
vector<ref<PgfItem>> items =
|
||||||
@@ -163,7 +179,7 @@ void PgfAbstractParser::symbol(Item *item, const PgfTextSpot &spot, bool bind, P
|
|||||||
if (it1 != next->completed.end()) {
|
if (it1 != next->completed.end()) {
|
||||||
auto *it2 = it1->second.lookup(ccat->value);
|
auto *it2 = it1->second.lookup(ccat->value);
|
||||||
if (it2 != NULL) {
|
if (it2 != NULL) {
|
||||||
auto *it3 = it2->lookup(lin_idx);
|
auto *it3 = it2->lookup(lin_idx_i);
|
||||||
if (it3 != NULL) {
|
if (it3 != NULL) {
|
||||||
CCat *arg = *it3;
|
CCat *arg = *it3;
|
||||||
Item *new_item = new (item) Item;
|
Item *new_item = new (item) Item;
|
||||||
@@ -292,21 +308,27 @@ void PgfAbstractParser::complete(Item *item, const PgfTextSpot &spot, bool bind)
|
|||||||
if (ccat->prods.size() == 1) {
|
if (ccat->prods.size() == 1) {
|
||||||
if (ccat->cont->ccat == NULL)
|
if (ccat->cont->ccat == NULL)
|
||||||
bu_predict(state, ccat);
|
bu_predict(state, ccat);
|
||||||
size_t n_items = ccat->cont->suspended.size();
|
|
||||||
for (size_t i = 0; i < n_items; i++) {
|
for (auto it1 : ccat->cont->suspended.overlaps(ccat->value)) {
|
||||||
Item *new_item = new (ccat->cont->suspended[i]) Item;
|
for (auto it2 : it1.second.overlaps(ccat->lin_idx)) {
|
||||||
combine(state,new_item,ccat);
|
size_t n_items = it2.second.size();
|
||||||
};
|
for (size_t i = 0; i < n_items; i++) {
|
||||||
|
Item *new_item = new (it2.second[i]) Item;
|
||||||
|
combine(state,new_item,ccat);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
State *next = state;
|
State *next = state;
|
||||||
while (next != NULL) {
|
while (next != NULL) {
|
||||||
for (auto it : next->conts2[ccat]) {
|
Cont *cont = next->conts2[ccat];
|
||||||
interval_t lin_idx = it.first;
|
if (cont != NULL) {
|
||||||
Cont *cont = it.second;
|
for (auto it1 : cont->suspended) {
|
||||||
if (cont != NULL) {
|
for (auto it2 : it1.second) {
|
||||||
Item *item = cont->suspended[0];
|
Item *item = it2.second[0];
|
||||||
auto symcat = ref<PgfSymbolCat>::untagged(item->syms[item->dot]);
|
auto symcat = ref<PgfSymbolCat>::untagged(item->syms[item->dot]);
|
||||||
td_predict(next,cont,prod,item,item->rule->args[symcat->d],ref<PgfLParam>::from_ptr(&symcat->r));
|
td_predict(next,cont,prod,item,item->rule->args[symcat->d],ref<PgfLParam>::from_ptr(&symcat->r));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next = next->next;
|
next = next->next;
|
||||||
@@ -1267,23 +1289,13 @@ void PgfParser::symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym)
|
|||||||
process(item, spot, true);
|
process(item, spot, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfParser::suspend(State *state,ref<PgfConcrLincat> lincat,Item *item)
|
void PgfParser::suspend(Cont *cont,Item *item,size_t n_suspended)
|
||||||
{
|
{
|
||||||
Cont *&cont = state->conts1[lincat];
|
if (n_suspended == 1) {
|
||||||
if (cont == NULL) {
|
|
||||||
cont = new Cont;
|
|
||||||
cont->ccat = NULL;
|
|
||||||
cont->lincat = lincat;
|
|
||||||
cont->state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
cont->suspended.push_back(item);
|
|
||||||
|
|
||||||
if (cont->suspended.size() == 1) {
|
|
||||||
std::function<void(ref<PgfSymbolCCat>,size_t,vector<ref<PgfItem>>)> f =
|
std::function<void(ref<PgfSymbolCCat>,size_t,vector<ref<PgfItem>>)> f =
|
||||||
[this,state,item,cont](ref<PgfSymbolCCat> symcf, size_t n_items, vector<ref<PgfItem>> items) {
|
[this,item,cont](ref<PgfSymbolCCat> symcf, size_t n_items, vector<ref<PgfItem>> items) {
|
||||||
|
|
||||||
PgfItem *xitem = items[0];
|
ref<PgfItem> xitem = items[0];
|
||||||
|
|
||||||
Item *new_item = new (item) Item;
|
Item *new_item = new (item) Item;
|
||||||
PgfSymbol sym = new_item->rule->syms[new_item->dot];
|
PgfSymbol sym = new_item->rule->syms[new_item->dot];
|
||||||
@@ -1308,21 +1320,21 @@ void PgfParser::suspend(State *state,ref<PgfConcrLincat> lincat,Item *item)
|
|||||||
arg_ccat->covered = true;
|
arg_ccat->covered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->completed[cont][symcf->value][symcf->lin_idx] = arg_ccat;
|
cont->state->completed[cont][symcf->value][symcf->lin_idx] = arg_ccat;
|
||||||
|
|
||||||
new_item->dot++;
|
new_item->dot++;
|
||||||
new_item->args[sym_cat->d] = arg_ccat;
|
new_item->args[sym_cat->d] = arg_ccat;
|
||||||
|
|
||||||
process(new_item, state->start, false);
|
process(new_item, cont->state->start, false);
|
||||||
};
|
};
|
||||||
phrasetable_iter(concr->phrasetable,lincat,f);
|
phrasetable_iter(concr->phrasetable,cont->lincat,f);
|
||||||
} else {
|
} else {
|
||||||
auto it1 = state->completed.find(cont);
|
auto it1 = cont->state->completed.find(cont);
|
||||||
if (it1 != state->completed.end()) {
|
if (it1 != cont->state->completed.end()) {
|
||||||
for (auto it2 : it1->second) {
|
for (auto it2 : it1->second) {
|
||||||
for (auto it3 : it2.second) {
|
for (auto it3 : it2.second) {
|
||||||
Item *new_item = new (item) Item;
|
Item *new_item = new (item) Item;
|
||||||
combine(state, new_item, it3.second);
|
combine(cont->state, new_item, it3.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1452,30 +1464,20 @@ void PgfParseTableMaker::symbol_bind(Item *item, const PgfTextSpot &spot, PgfSym
|
|||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfParseTableMaker::suspend(State *state,ref<PgfConcrLincat> lincat,Item *item)
|
void PgfParseTableMaker::suspend(Cont *cont,Item *item,size_t n_suspended)
|
||||||
{
|
{
|
||||||
Cont *&cont = state->conts1[lincat];
|
for (auto it1 : cont->state->completed[cont]) {
|
||||||
if (cont == NULL) {
|
|
||||||
cont = new Cont;
|
|
||||||
cont->ccat = NULL;
|
|
||||||
cont->lincat = lincat;
|
|
||||||
cont->state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
cont->suspended.push_back(item);
|
|
||||||
|
|
||||||
for (auto it1 : state->completed[cont]) {
|
|
||||||
for (auto it2 : it1.second) {
|
for (auto it2 : it1.second) {
|
||||||
CCat *ccat = it2.second;
|
CCat *ccat = it2.second;
|
||||||
if (ccat != NULL) {
|
if (ccat != NULL) {
|
||||||
Item *new_item = new (item) Item;
|
Item *new_item = new (item) Item;
|
||||||
combine(state,new_item,ccat);
|
combine(cont->state,new_item,ccat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pitem = clone_item(item);
|
auto pitem = clone_item(item);
|
||||||
auto acat = ref<PgfSymbolACat>::from_ptr((PgfSymbolACat*) &lincat->name);
|
auto acat = ref<PgfSymbolACat>::from_ptr((PgfSymbolACat*) &cont->lincat->name);
|
||||||
auto phrasetable = phrasetable_insert(concr->phrasetable,acat.tagged(),pitem);
|
auto phrasetable = phrasetable_insert(concr->phrasetable,acat.tagged(),pitem);
|
||||||
concr->phrasetable = phrasetable;
|
concr->phrasetable = phrasetable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ protected:
|
|||||||
PgfTextSpot start, end;
|
PgfTextSpot start, end;
|
||||||
bool needs_bind;
|
bool needs_bind;
|
||||||
std::map<ref<PgfConcrLincat>,Cont*> conts1;
|
std::map<ref<PgfConcrLincat>,Cont*> conts1;
|
||||||
std::map<CCat*,interval_map<Cont*>> conts2;
|
std::map<CCat*,Cont*> conts2;
|
||||||
std::map<Cont*,interval_map<interval_map<CCat*>>> completed;
|
std::map<Cont*,interval_map<interval_map<CCat*>>> completed;
|
||||||
|
|
||||||
State *next;
|
State *next;
|
||||||
@@ -111,7 +111,7 @@ protected:
|
|||||||
CCat *ccat;
|
CCat *ccat;
|
||||||
ref<PgfConcrLincat> lincat;
|
ref<PgfConcrLincat> lincat;
|
||||||
State *state;
|
State *state;
|
||||||
std::vector<Item*> suspended;
|
interval_map<interval_map<std::vector<Item*>>> suspended;
|
||||||
|
|
||||||
~Cont();
|
~Cont();
|
||||||
};
|
};
|
||||||
@@ -215,7 +215,7 @@ protected:
|
|||||||
virtual State *new_state(const PgfTextSpot &start)=0;
|
virtual State *new_state(const PgfTextSpot &start)=0;
|
||||||
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym)=0;
|
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym)=0;
|
||||||
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym)=0;
|
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym)=0;
|
||||||
virtual void suspend(State *state,ref<PgfConcrLincat> lincat, Item *item)=0;
|
virtual void suspend(Cont *cont, Item *item, size_t n_suspended)=0;
|
||||||
virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx)=0;
|
virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx)=0;
|
||||||
virtual void bu_predict(State *state, CCat *ccat)=0;
|
virtual void bu_predict(State *state, CCat *ccat)=0;
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ class PGF_INTERNAL_DECL PgfParser : private PgfAbstractParser, public PgfExprEnu
|
|||||||
virtual State *new_state(const PgfTextSpot &start);
|
virtual State *new_state(const PgfTextSpot &start);
|
||||||
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym);
|
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym);
|
||||||
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym);
|
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym);
|
||||||
virtual void suspend(State *state,ref<PgfConcrLincat> lincat, Item *item);
|
virtual void suspend(Cont *cont,Item *item,size_t n_suspended);
|
||||||
virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx);
|
virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx);
|
||||||
virtual void bu_predict(State *state, CCat *ccat);
|
virtual void bu_predict(State *state, CCat *ccat);
|
||||||
|
|
||||||
@@ -288,8 +288,8 @@ private:
|
|||||||
virtual State *new_state(const PgfTextSpot &start);
|
virtual State *new_state(const PgfTextSpot &start);
|
||||||
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym);
|
virtual void symbol_token(Item *item, const PgfTextSpot &spot, bool bind, PgfSymbol sym);
|
||||||
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym);
|
virtual void symbol_bind(Item *item, const PgfTextSpot &spot, PgfSymbol sym);
|
||||||
virtual void suspend(State *state,ref<PgfConcrLincat> lincat,Item *item);
|
virtual void suspend(Cont *cont, Item *item, size_t n_suspended);
|
||||||
virtual void final_item(State *state,CCat *ccat,Item *item,interval_t value,interval_t lin_idx);
|
virtual void final_item(State *state, CCat *ccat,Item *item,interval_t value,interval_t lin_idx);
|
||||||
virtual void bu_predict(State *state, CCat *ccat);
|
virtual void bu_predict(State *state, CCat *ccat);
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|||||||
Reference in New Issue
Block a user