mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-09-15 14:56:00 -06:00
implement linearization with lindef
This commit is contained in:
@@ -217,8 +217,6 @@ PgfLinearizer::TreeLinNode::TreeLinNode(PgfLinearizer *linearizer, ref<PgfConcrL
|
|||||||
|
|
||||||
bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
|
bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
|
||||||
{
|
{
|
||||||
vector<PgfHypo> hypos = lin->absfun->type->hypos;
|
|
||||||
|
|
||||||
while (rule_index < lin->rules.size()) {
|
while (rule_index < lin->rules.size()) {
|
||||||
Item *item = new (lin->rules[rule_index]) Item();
|
Item *item = new (lin->rules[rule_index]) Item();
|
||||||
item->rule = lin->rules[rule_index];
|
item->rule = lin->rules[rule_index];
|
||||||
@@ -226,8 +224,6 @@ bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
TreeNode *arg = args;
|
TreeNode *arg = args;
|
||||||
while (arg != NULL) {
|
while (arg != NULL) {
|
||||||
arg->check_category(linearizer, &hypos[i].type->name);
|
|
||||||
|
|
||||||
if (!item->instantiate(item->rule->args[i], arg->value))
|
if (!item->instantiate(item->rule->args[i], arg->value))
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
@@ -275,10 +271,9 @@ bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeLinNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
|
bool PgfLinearizer::TreeLinNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
|
||||||
{
|
{
|
||||||
if (textcmp(&lin->absfun->type->name, cat) != 0)
|
return (textcmp(&lin->absfun->type->name, cat) == 0);
|
||||||
throw pgf_error("An attempt to linearize an expression which is not type correct");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeLinNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
|
void PgfLinearizer::TreeLinNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
|
||||||
@@ -361,32 +356,36 @@ PgfLinearizer::TreeLindefNode::TreeLindefNode(PgfLinearizer *linearizer, PgfText
|
|||||||
|
|
||||||
bool PgfLinearizer::TreeLindefNode::resolve(PgfLinearizer *linearizer)
|
bool PgfLinearizer::TreeLindefNode::resolve(PgfLinearizer *linearizer)
|
||||||
{
|
{
|
||||||
/* while (rule_index < lincat->n_lindefs2) {
|
if (lincat == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
while (rule_index < lincat->n_lindefs) {
|
||||||
ref<PgfConcrRule> rule = lincat->rules[rule_index];
|
ref<PgfConcrRule> rule = lincat->rules[rule_index];
|
||||||
Item *item = new (rule) Item();
|
Item *item = new (rule) Item();
|
||||||
|
item->rule = rule;
|
||||||
|
|
||||||
size_t max_value = 1;
|
size_t max_value = 1;
|
||||||
for (size_t i = 0; i < item->vars.size(); i++) {
|
for (size_t i = 0; i < item->vars.size(); i++) {
|
||||||
if (item->vars[i] == 0)
|
if (item->vars[i] == 0)
|
||||||
max_value *= item->rule->vars[i].range;
|
max_value *= item->rule->ranges[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t value = 0; value < max_value; value++) {
|
for (size_t value = 0; value < max_value; value++) {
|
||||||
|
Item *new_item = new (item) Item;
|
||||||
|
|
||||||
size_t v = value;
|
size_t v = value;
|
||||||
for (size_t i = 0; i < item->vars.size(); i++) {
|
for (size_t i = 0; i < new_item->vars.size(); i++) {
|
||||||
if (item->vars[i] == 0) {
|
if (new_item->vars[i] == 0) {
|
||||||
size_t range = item->rule->vars[i].range;
|
size_t range = new_item->rule->ranges[i];
|
||||||
item->vars[i] = v % range;
|
new_item->vars[i] = (v % range)+1;
|
||||||
v = v / range;
|
v = v / range;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item *new_item = new (item) Item;
|
size_t lin_idx = new_item->eval(new_item->rule->lin_idx);
|
||||||
|
|
||||||
size_t lin_idx = item->eval(new_item->rule->lin_idx);
|
|
||||||
items[lin_idx] = new_item;
|
items[lin_idx] = new_item;
|
||||||
|
|
||||||
this->value = item->eval(new_item->rule->res);
|
this->value = new_item->eval(new_item->rule->res);
|
||||||
}
|
}
|
||||||
delete item;
|
delete item;
|
||||||
|
|
||||||
@@ -399,19 +398,19 @@ bool PgfLinearizer::TreeLindefNode::resolve(PgfLinearizer *linearizer)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeLindefNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
|
bool PgfLinearizer::TreeLindefNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
|
||||||
{
|
{
|
||||||
lincat = namespace_lookup(linearizer->concr->lincats, cat);
|
lincat = namespace_lookup(linearizer->concr->lincats, cat);
|
||||||
if (lincat == 0)
|
if (lincat != 0)
|
||||||
throw pgf_error("Cannot find a lincat for a category");
|
this->items = new Item*[lincat->fields.size()]();
|
||||||
this->items = new Item*[lincat->fields.size()]();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeLindefNode::linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, PgfLParam *r)
|
void PgfLinearizer::TreeLindefNode::linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r)
|
||||||
{
|
{
|
||||||
linearizer->flush_pre_stack(out, literal);
|
linearizer->flush_pre_stack(out, literal);
|
||||||
out->symbol_token(literal);
|
out->symbol_token(literal);
|
||||||
@@ -425,39 +424,42 @@ void PgfLinearizer::TreeLindefNode::linearize_arg(PgfLinearizationOutputIface *o
|
|||||||
|
|
||||||
void PgfLinearizer::TreeLindefNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
|
void PgfLinearizer::TreeLindefNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
|
||||||
{
|
{
|
||||||
/* if (lincat != 0) {
|
if (lincat==0) {
|
||||||
PgfText *field = &*lincat->fields[lindex];
|
linearize_arg(out, linearizer, 0, 0);
|
||||||
if (linearizer->pre_stack == NULL)
|
return;
|
||||||
out->begin_phrase(&lincat->name, fid, field, fun);
|
}
|
||||||
else {
|
|
||||||
BracketStack *bracket = new BracketStack();
|
|
||||||
bracket->next = linearizer->pre_stack->bracket_stack;
|
|
||||||
bracket->begin = true;
|
|
||||||
bracket->fid = fid;
|
|
||||||
bracket->cat = &lincat->name;
|
|
||||||
bracket->field = field;
|
|
||||||
bracket->fun = fun;
|
|
||||||
linearizer->pre_stack->bracket_stack = bracket;
|
|
||||||
}
|
|
||||||
|
|
||||||
ref<PgfSequence> seq = lincat->seqs[(rule_index-1)*lincat->fields.size() + lindex];
|
PgfText *cat = &lincat->name;
|
||||||
// linearize_seq(out, linearizer, seq);
|
PgfText *field = &*lincat->fields[lindex];
|
||||||
|
|
||||||
if (linearizer->pre_stack == NULL)
|
if (linearizer->pre_stack == NULL)
|
||||||
out->end_phrase(&lincat->name, fid, field, fun);
|
out->begin_phrase(cat, fid, field, linearizer->wild);
|
||||||
else {
|
else {
|
||||||
BracketStack *bracket = new BracketStack();
|
BracketStack *bracket = new BracketStack();
|
||||||
bracket->next = linearizer->pre_stack->bracket_stack;
|
bracket->next = linearizer->pre_stack->bracket_stack;
|
||||||
bracket->begin = false;
|
bracket->begin = true;
|
||||||
bracket->fid = fid;
|
bracket->fid = fid;
|
||||||
bracket->cat = &lincat->name;
|
bracket->cat = cat;
|
||||||
bracket->field = field;
|
bracket->field = field;
|
||||||
bracket->fun = fun;
|
bracket->fun = linearizer->wild;
|
||||||
linearizer->pre_stack->bracket_stack = bracket;
|
linearizer->pre_stack->bracket_stack = bracket;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
linearize_arg(out, linearizer, 0, NULL);
|
linearize_item(out, linearizer,
|
||||||
}*/
|
items[lindex],items[lindex]->rule->syms.as_vector());
|
||||||
|
|
||||||
|
if (linearizer->pre_stack == NULL)
|
||||||
|
out->end_phrase(cat, fid, field, linearizer->wild);
|
||||||
|
else {
|
||||||
|
BracketStack *bracket = new BracketStack();
|
||||||
|
bracket->next = linearizer->pre_stack->bracket_stack;
|
||||||
|
bracket->begin = false;
|
||||||
|
bracket->fid = fid;
|
||||||
|
bracket->cat = cat;
|
||||||
|
bracket->field = field;
|
||||||
|
bracket->fun = linearizer->wild;
|
||||||
|
linearizer->pre_stack->bracket_stack = bracket;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<PgfConcrLincat> PgfLinearizer::TreeLindefNode::get_lincat(PgfLinearizer *linearizer)
|
ref<PgfConcrLincat> PgfLinearizer::TreeLindefNode::get_lincat(PgfLinearizer *linearizer)
|
||||||
@@ -562,10 +564,9 @@ PgfLinearizer::TreeLitNode::TreeLitNode(PgfLinearizer *linearizer, ref<PgfConcrL
|
|||||||
this->literal = lit;
|
this->literal = lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeLitNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
|
bool PgfLinearizer::TreeLitNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
|
||||||
{
|
{
|
||||||
if (textcmp(&lincat->name, cat) != 0)
|
return (textcmp(&lincat->name, cat) == 0);
|
||||||
throw pgf_error("An attempt to linearize an expression which is not type correct");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeLitNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
|
void PgfLinearizer::TreeLitNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
|
||||||
@@ -599,6 +600,7 @@ PgfLinearizer::PgfLinearizer(PgfPrintContext *ctxt, ref<PgfConcr> concr, PgfMars
|
|||||||
this->args = NULL;
|
this->args = NULL;
|
||||||
this->capit = CAPIT_NONE;
|
this->capit = CAPIT_NONE;
|
||||||
this->pre_stack = NULL;
|
this->pre_stack = NULL;
|
||||||
|
this->type_error = false;
|
||||||
this->wild = (PgfText*) malloc(sizeof(PgfText)+2);
|
this->wild = (PgfText*) malloc(sizeof(PgfText)+2);
|
||||||
this->wild->size = 1;
|
this->wild->size = 1;
|
||||||
this->wild->text[0] = '_';
|
this->wild->text[0] = '_';
|
||||||
@@ -638,6 +640,10 @@ PgfLinearizer::~PgfLinearizer()
|
|||||||
|
|
||||||
bool PgfLinearizer::resolve()
|
bool PgfLinearizer::resolve()
|
||||||
{
|
{
|
||||||
|
if (type_error) {
|
||||||
|
throw pgf_error("An attempt to linearize an expression which is not type correct");
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!prev || prev->resolve(this)) {
|
if (!prev || prev->resolve(this)) {
|
||||||
if (next == NULL)
|
if (next == NULL)
|
||||||
@@ -768,9 +774,19 @@ PgfExpr PgfLinearizer::emeta(PgfMetaId meta)
|
|||||||
PgfExpr PgfLinearizer::efun(PgfText *name)
|
PgfExpr PgfLinearizer::efun(PgfText *name)
|
||||||
{
|
{
|
||||||
ref<PgfConcrLin> lin = namespace_lookup(concr->lins, name);
|
ref<PgfConcrLin> lin = namespace_lookup(concr->lins, name);
|
||||||
if (lin != 0)
|
if (lin != 0) {
|
||||||
|
TreeNode *node = args;
|
||||||
|
size_t i = 0;
|
||||||
|
vector<PgfHypo> hypos = lin->absfun->type->hypos;
|
||||||
|
while (node != NULL) {
|
||||||
|
if (!node->check_category(this, &hypos[i].type->name)) {
|
||||||
|
type_error = true;
|
||||||
|
}
|
||||||
|
node = node->next_arg; i++;
|
||||||
|
}
|
||||||
|
|
||||||
return (PgfExpr) new TreeLinNode(this, lin);
|
return (PgfExpr) new TreeLinNode(this, lin);
|
||||||
else {
|
} else {
|
||||||
printer.puts("[");
|
printer.puts("[");
|
||||||
printer.efun(name);
|
printer.efun(name);
|
||||||
printer.puts("]");
|
printer.puts("]");
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
|
|||||||
|
|
||||||
TreeNode(PgfLinearizer *linearizer);
|
TreeNode(PgfLinearizer *linearizer);
|
||||||
virtual bool resolve(PgfLinearizer *linearizer) { return true; };
|
virtual bool resolve(PgfLinearizer *linearizer) { return true; };
|
||||||
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat)=0;
|
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat)=0;
|
||||||
virtual void linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
|
virtual void linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
|
||||||
virtual void linearize_var(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
|
virtual void linearize_var(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
|
||||||
virtual void linearize_item(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, Item *item, vector<PgfSymbol> syms);
|
virtual void linearize_item(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, Item *item, vector<PgfSymbol> syms);
|
||||||
@@ -98,7 +98,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
|
|||||||
|
|
||||||
TreeLinNode(PgfLinearizer *linearizer, ref<PgfConcrLin> lin);
|
TreeLinNode(PgfLinearizer *linearizer, ref<PgfConcrLin> lin);
|
||||||
virtual bool resolve(PgfLinearizer *linearizer);
|
virtual bool resolve(PgfLinearizer *linearizer);
|
||||||
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat);
|
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat);
|
||||||
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
||||||
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
||||||
virtual ~TreeLinNode();
|
virtual ~TreeLinNode();
|
||||||
@@ -113,8 +113,8 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
|
|||||||
|
|
||||||
TreeLindefNode(PgfLinearizer *linearizer, PgfText *fun, PgfText *lit);
|
TreeLindefNode(PgfLinearizer *linearizer, PgfText *fun, PgfText *lit);
|
||||||
virtual bool resolve(PgfLinearizer *linearizer);
|
virtual bool resolve(PgfLinearizer *linearizer);
|
||||||
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat);
|
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat);
|
||||||
virtual void linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, PgfLParam *r);
|
virtual void linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, size_t r);
|
||||||
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
||||||
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
||||||
~TreeLindefNode();
|
~TreeLindefNode();
|
||||||
@@ -126,7 +126,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
|
|||||||
|
|
||||||
TreeLinrefNode(PgfLinearizer *linearizer, TreeNode *root);
|
TreeLinrefNode(PgfLinearizer *linearizer, TreeNode *root);
|
||||||
virtual bool resolve(PgfLinearizer *linearizer);
|
virtual bool resolve(PgfLinearizer *linearizer);
|
||||||
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat) {};
|
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat) { return true; };
|
||||||
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
||||||
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
||||||
~TreeLinrefNode();
|
~TreeLinrefNode();
|
||||||
@@ -137,7 +137,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
|
|||||||
PgfText *literal;
|
PgfText *literal;
|
||||||
|
|
||||||
TreeLitNode(PgfLinearizer *linearizer, ref<PgfConcrLincat> lincat, PgfText *lit);
|
TreeLitNode(PgfLinearizer *linearizer, ref<PgfConcrLincat> lincat, PgfText *lit);
|
||||||
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat);
|
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat);
|
||||||
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
||||||
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
||||||
~TreeLitNode() { free(literal); };
|
~TreeLitNode() { free(literal); };
|
||||||
@@ -146,7 +146,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
|
|||||||
struct TreeChunksNode : public TreeNode {
|
struct TreeChunksNode : public TreeNode {
|
||||||
TreeChunksNode(PgfLinearizer *linearizer);
|
TreeChunksNode(PgfLinearizer *linearizer);
|
||||||
virtual bool resolve(PgfLinearizer *linearizer);
|
virtual bool resolve(PgfLinearizer *linearizer);
|
||||||
virtual void check_category(PgfLinearizer *linearizer, PgfText *cat);
|
virtual bool check_category(PgfLinearizer *linearizer, PgfText *cat);
|
||||||
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
virtual void linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex);
|
||||||
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
virtual ref<PgfConcrLincat> get_lincat(PgfLinearizer *linearizer);
|
||||||
};
|
};
|
||||||
@@ -183,6 +183,7 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
|
|||||||
PreStack *pre_stack;
|
PreStack *pre_stack;
|
||||||
void flush_pre_stack(PgfLinearizationOutputIface *out, PgfText *token);
|
void flush_pre_stack(PgfLinearizationOutputIface *out, PgfText *token);
|
||||||
|
|
||||||
|
bool type_error;
|
||||||
PgfText *wild;
|
PgfText *wild;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
Reference in New Issue
Block a user