mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 11:42:49 -06:00
added linearizeAll
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
PgfLinearizer::TreeNode::TreeNode(PgfLinearizer *linearizer)
|
PgfLinearizer::TreeNode::TreeNode(PgfLinearizer *linearizer)
|
||||||
{
|
{
|
||||||
this->next = linearizer->root;
|
this->next = linearizer->prev;
|
||||||
this->next_arg = NULL;
|
this->next_arg = NULL;
|
||||||
this->args = linearizer->args;
|
this->args = linearizer->args;
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ PgfLinearizer::TreeNode::TreeNode(PgfLinearizer *linearizer)
|
|||||||
this->n_hoas_vars = 0;
|
this->n_hoas_vars = 0;
|
||||||
this->hoas_vars = NULL;
|
this->hoas_vars = NULL;
|
||||||
|
|
||||||
linearizer->root= this;
|
linearizer->prev = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeNode::linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, PgfLParam *r)
|
void PgfLinearizer::TreeNode::linearize_arg(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t d, PgfLParam *r)
|
||||||
@@ -202,6 +202,11 @@ bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
|
|||||||
|
|
||||||
ref<PgfPResult> pres = *vector_elem(lin->res, lin_index);
|
ref<PgfPResult> pres = *vector_elem(lin->res, lin_index);
|
||||||
|
|
||||||
|
// Unbind all variables
|
||||||
|
for (size_t j = 0; j < var_count; j++) {
|
||||||
|
var_values[j] = (size_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
TreeNode *arg = args;
|
TreeNode *arg = args;
|
||||||
while (arg != NULL) {
|
while (arg != NULL) {
|
||||||
@@ -265,16 +270,12 @@ bool PgfLinearizer::TreeLinNode::resolve(PgfLinearizer *linearizer)
|
|||||||
|
|
||||||
if (arg == NULL) {
|
if (arg == NULL) {
|
||||||
value = eval_param(&pres->param);
|
value = eval_param(&pres->param);
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// Unbind all variables
|
|
||||||
for (size_t j = 0; j < var_count; j++) {
|
|
||||||
var_values[j] = (size_t) -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (lin_index <= lin->res->len);
|
lin_index = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeLinNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
|
void PgfLinearizer::TreeLinNode::check_category(PgfLinearizer *linearizer, PgfText *cat)
|
||||||
@@ -339,13 +340,15 @@ PgfLinearizer::TreeLindefNode::TreeLindefNode(PgfLinearizer *linearizer, PgfText
|
|||||||
bool PgfLinearizer::TreeLindefNode::resolve(PgfLinearizer *linearizer)
|
bool PgfLinearizer::TreeLindefNode::resolve(PgfLinearizer *linearizer)
|
||||||
{
|
{
|
||||||
if (lincat == 0) {
|
if (lincat == 0) {
|
||||||
lin_index++;
|
return (lin_index = !lin_index);
|
||||||
return (lin_index <= 1);
|
|
||||||
} else {
|
} else {
|
||||||
ref<PgfPResult> pres = *vector_elem(lincat->res, lin_index);
|
ref<PgfPResult> pres = *vector_elem(lincat->res, lin_index);
|
||||||
value = eval_param(&pres->param);
|
value = eval_param(&pres->param);
|
||||||
lin_index++;
|
lin_index++;
|
||||||
return (lin_index <= lincat->n_lindefs);
|
if (lin_index <= lincat->n_lindefs)
|
||||||
|
return true;
|
||||||
|
lin_index = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +418,10 @@ bool PgfLinearizer::TreeLinrefNode::resolve(PgfLinearizer *linearizer)
|
|||||||
{
|
{
|
||||||
ref<PgfConcrLincat> lincat = args->get_lincat(linearizer);
|
ref<PgfConcrLincat> lincat = args->get_lincat(linearizer);
|
||||||
lin_index++;
|
lin_index++;
|
||||||
return (lincat->n_lindefs+lin_index <= lincat->res->len);
|
if (lincat->n_lindefs+lin_index <= lincat->res->len)
|
||||||
|
return true;
|
||||||
|
lin_index = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::TreeLinrefNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
|
void PgfLinearizer::TreeLinrefNode::linearize(PgfLinearizationOutputIface *out, PgfLinearizer *linearizer, size_t lindex)
|
||||||
@@ -474,8 +480,8 @@ PgfLinearizer::PgfLinearizer(PgfPrintContext *ctxt, ref<PgfConcr> concr, PgfMars
|
|||||||
{
|
{
|
||||||
this->concr = concr;
|
this->concr = concr;
|
||||||
this->m = m;
|
this->m = m;
|
||||||
this->root = NULL;
|
this->prev = NULL;
|
||||||
this->first = NULL;
|
this->next = NULL;
|
||||||
this->args = NULL;
|
this->args = NULL;
|
||||||
this->capit = CAPIT_NONE;
|
this->capit = CAPIT_NONE;
|
||||||
this->pre_stack = NULL;
|
this->pre_stack = NULL;
|
||||||
@@ -487,10 +493,16 @@ PgfLinearizer::PgfLinearizer(PgfPrintContext *ctxt, ref<PgfConcr> concr, PgfMars
|
|||||||
|
|
||||||
PgfLinearizer::~PgfLinearizer()
|
PgfLinearizer::~PgfLinearizer()
|
||||||
{
|
{
|
||||||
while (first != NULL) {
|
while (prev != NULL) {
|
||||||
TreeNode *next = first->next;
|
TreeNode *prev_next = prev->next;
|
||||||
delete first;
|
delete prev;
|
||||||
first = next;
|
prev = prev_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (next != NULL) {
|
||||||
|
TreeNode *next_next = next->next;
|
||||||
|
delete next;
|
||||||
|
next = next_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (pre_stack != NULL) {
|
while (pre_stack != NULL) {
|
||||||
@@ -512,32 +524,40 @@ PgfLinearizer::~PgfLinearizer()
|
|||||||
|
|
||||||
bool PgfLinearizer::resolve()
|
bool PgfLinearizer::resolve()
|
||||||
{
|
{
|
||||||
TreeNode *node = first;
|
for (;;) {
|
||||||
while (node != NULL) {
|
if (!prev || prev->resolve(this)) {
|
||||||
if (!node->resolve(this))
|
if (next == NULL)
|
||||||
return false;
|
return true;
|
||||||
node = node->next;
|
TreeNode *next_next = next->next;
|
||||||
|
next->next = prev;
|
||||||
|
prev = next;
|
||||||
|
next = next_next;
|
||||||
|
} else {
|
||||||
|
TreeNode *prev_next = prev->next;
|
||||||
|
prev->next = next;
|
||||||
|
next = prev;
|
||||||
|
prev = prev_next;
|
||||||
|
if (prev == NULL)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfLinearizer::reverse_and_label(bool add_linref)
|
void PgfLinearizer::reverse_and_label(bool add_linref)
|
||||||
{
|
{
|
||||||
if (add_linref)
|
if (add_linref)
|
||||||
new TreeLinrefNode(this, root);
|
new TreeLinrefNode(this, prev);
|
||||||
|
|
||||||
// Reverse the list of nodes and label them with fid;
|
// Reverse the list of nodes and label them with fid;
|
||||||
int fid = 0;
|
int fid = 0;
|
||||||
TreeNode *node = root;
|
while (prev != NULL) {
|
||||||
while (node != NULL) {
|
TreeNode *tmp = prev->next;
|
||||||
TreeNode *tmp = node->next;
|
|
||||||
|
|
||||||
node->fid = fid++;
|
prev->fid = fid++;
|
||||||
node->next = first;
|
prev->next = next;
|
||||||
|
|
||||||
first = node;
|
next = prev;
|
||||||
node = tmp;
|
prev = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
|
|||||||
~TreeLitNode() { free(literal); };
|
~TreeLitNode() { free(literal); };
|
||||||
};
|
};
|
||||||
|
|
||||||
TreeNode *root;
|
TreeNode *prev;
|
||||||
TreeNode *first;
|
TreeNode *next;
|
||||||
TreeNode *args;
|
TreeNode *args;
|
||||||
|
|
||||||
enum CapitState { CAPIT_NONE, CAPIT_FIRST, CAPIT_ALL };
|
enum CapitState { CAPIT_NONE, CAPIT_FIRST, CAPIT_ALL };
|
||||||
@@ -136,11 +136,11 @@ public:
|
|||||||
bool resolve();
|
bool resolve();
|
||||||
void reverse_and_label(bool add_linref);
|
void reverse_and_label(bool add_linref);
|
||||||
void linearize(PgfLinearizationOutputIface *out, size_t lindex) {
|
void linearize(PgfLinearizationOutputIface *out, size_t lindex) {
|
||||||
root->linearize(out, this, lindex);
|
prev->linearize(out, this, lindex);
|
||||||
flush_pre_stack(out, NULL);
|
flush_pre_stack(out, NULL);
|
||||||
}
|
}
|
||||||
ref<PgfConcrLincat> get_lincat() {
|
ref<PgfConcrLincat> get_lincat() {
|
||||||
return root->get_lincat(this);
|
return prev->get_lincat(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~PgfLinearizer();
|
~PgfLinearizer();
|
||||||
|
|||||||
@@ -2015,6 +2015,37 @@ PgfText *pgf_linearize(PgfDB *db, PgfConcrRevision revision,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PGF_API
|
||||||
|
PgfText **pgf_linearize_all(PgfDB *db, PgfConcrRevision revision,
|
||||||
|
PgfExpr expr, PgfPrintContext *ctxt,
|
||||||
|
PgfMarshaller *m, size_t *n_variants,
|
||||||
|
PgfExn* err)
|
||||||
|
{
|
||||||
|
*n_variants = 0;
|
||||||
|
PgfText **variants = NULL;
|
||||||
|
|
||||||
|
PGF_API_BEGIN {
|
||||||
|
DB_scope scope(db, READER_SCOPE);
|
||||||
|
|
||||||
|
ref<PgfConcr> concr = PgfDB::revision2concr(revision);
|
||||||
|
PgfLinearizationOutput out;
|
||||||
|
PgfLinearizer linearizer(ctxt, concr, m);
|
||||||
|
m->match_expr(&linearizer, expr);
|
||||||
|
linearizer.reverse_and_label(true);
|
||||||
|
|
||||||
|
while (linearizer.resolve()) {
|
||||||
|
linearizer.linearize(&out, 0);
|
||||||
|
variants = (PgfText **) realloc(variants, ((*n_variants)+1)*sizeof(PgfText **));
|
||||||
|
variants[(*n_variants)++] = out.get_text();
|
||||||
|
}
|
||||||
|
|
||||||
|
return variants;
|
||||||
|
} PGF_API_END
|
||||||
|
|
||||||
|
free(variants);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
PGF_API
|
PGF_API
|
||||||
PgfText **pgf_tabular_linearize(PgfDB *db, PgfConcrRevision revision,
|
PgfText **pgf_tabular_linearize(PgfDB *db, PgfConcrRevision revision,
|
||||||
PgfExpr expr, PgfPrintContext *ctxt,
|
PgfExpr expr, PgfPrintContext *ctxt,
|
||||||
|
|||||||
@@ -622,7 +622,23 @@ linearize c e =
|
|||||||
|
|
||||||
-- | Generates all possible linearizations of an expression
|
-- | Generates all possible linearizations of an expression
|
||||||
linearizeAll :: Concr -> Expr -> [String]
|
linearizeAll :: Concr -> Expr -> [String]
|
||||||
linearizeAll lang e = error "TODO: linearizeAll"
|
linearizeAll c e =
|
||||||
|
unsafePerformIO $
|
||||||
|
withForeignPtr (c_revision c) $ \c_revision ->
|
||||||
|
bracket (newStablePtr e) freeStablePtr $ \c_e ->
|
||||||
|
withForeignPtr marshaller $ \m ->
|
||||||
|
alloca $ \p_n_fields ->
|
||||||
|
bracket (withPgfExn "linearizeAll" (pgf_linearize_all (c_db c) c_revision c_e nullPtr m p_n_fields)) free $ \c_texts -> do
|
||||||
|
n_fields <- peek p_n_fields
|
||||||
|
peekTexts n_fields c_texts
|
||||||
|
where
|
||||||
|
peekTexts 0 c_texts = return []
|
||||||
|
peekTexts n c_texts = do
|
||||||
|
c_text <- peek c_texts
|
||||||
|
text <- peekText c_text
|
||||||
|
free c_text
|
||||||
|
texts <- peekTexts (n-1) (c_texts `plusPtr` (#size PgfText*))
|
||||||
|
return (text:texts)
|
||||||
|
|
||||||
-- | Generates a table of linearizations for an expression
|
-- | Generates a table of linearizations for an expression
|
||||||
tabularLinearize :: Concr -> Expr -> [(String, String)]
|
tabularLinearize :: Concr -> Expr -> [(String, String)]
|
||||||
|
|||||||
@@ -209,6 +209,8 @@ foreign import ccall pgf_has_linearization :: Ptr PgfDB -> Ptr Concr -> Ptr PgfT
|
|||||||
|
|
||||||
foreign import ccall pgf_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfExn -> IO (Ptr PgfText)
|
foreign import ccall pgf_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfExn -> IO (Ptr PgfText)
|
||||||
|
|
||||||
|
foreign import ccall pgf_linearize_all :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr CSize -> Ptr PgfExn -> IO (Ptr (Ptr PgfText))
|
||||||
|
|
||||||
foreign import ccall pgf_tabular_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr CSize -> Ptr PgfExn -> IO (Ptr (Ptr PgfText))
|
foreign import ccall pgf_tabular_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr CSize -> Ptr PgfExn -> IO (Ptr (Ptr PgfText))
|
||||||
|
|
||||||
foreign import ccall pgf_bracketed_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfLinearizationOutputIface -> Ptr PgfExn -> IO ()
|
foreign import ccall pgf_bracketed_linearize :: Ptr PgfDB -> Ptr Concr -> StablePtr Expr -> Ptr PgfPrintContext -> Ptr PgfMarshaller -> Ptr PgfLinearizationOutputIface -> Ptr PgfExn -> IO ()
|
||||||
|
|||||||
Reference in New Issue
Block a user