summaryrefslogtreecommitdiff
path: root/src/runtime/c/pgf
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/c/pgf')
-rw-r--r--src/runtime/c/pgf/data.h4
-rw-r--r--src/runtime/c/pgf/graphviz.c5
-rw-r--r--src/runtime/c/pgf/linearizer.c16
-rw-r--r--src/runtime/c/pgf/linearizer.h2
-rw-r--r--src/runtime/c/pgf/parser.c46
-rw-r--r--src/runtime/c/pgf/parseval.c11
-rw-r--r--src/runtime/c/pgf/reader.c171
-rw-r--r--src/runtime/c/pgf/reader.h6
8 files changed, 200 insertions, 61 deletions
diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h
index 131201132..6bfd5d334 100644
--- a/src/runtime/c/pgf/data.h
+++ b/src/runtime/c/pgf/data.h
@@ -99,6 +99,7 @@ typedef struct {
PgfFlags* aflags;
PgfCIdMap* funs; // |-> PgfAbsFun*
PgfCIdMap* cats; // |-> PgfAbsCat*
+ PgfAbsFun* abs_lin_fun;
} PgfAbstr;
struct PgfPGF {
@@ -241,6 +242,9 @@ struct PgfConcr {
PgfCIdMap* cnccats;
PgfCallbacksMap* callbacks;
int total_cats;
+
+ GuPool* pool; // if the language is loaded separately then this is the pool
+ GuFinalizer fin; // and this is the finalizer in the pool of the whole grammar
};
extern GU_DECLARE_TYPE(PgfConcr, abstract);
diff --git a/src/runtime/c/pgf/graphviz.c b/src/runtime/c/pgf/graphviz.c
index 11ecabe40..9410c68a6 100644
--- a/src/runtime/c/pgf/graphviz.c
+++ b/src/runtime/c/pgf/graphviz.c
@@ -260,7 +260,10 @@ pgf_graphviz_parse_tree(PgfConcr* concr, PgfExpr expr, GuOut* out, GuExn* err)
GuPool* tmp_pool = gu_local_pool();
GuEnum* cts =
- pgf_lzr_concretize(concr, expr, tmp_pool);
+ pgf_lzr_concretize(concr, expr, err, tmp_pool);
+ if (!gu_ok(err))
+ return;
+
PgfCncTree ctree = gu_next(cts, PgfCncTree, tmp_pool);
if (gu_variant_is_null(ctree)) {
gu_pool_free(tmp_pool);
diff --git a/src/runtime/c/pgf/linearizer.c b/src/runtime/c/pgf/linearizer.c
index 732bce75a..0f8473639 100644
--- a/src/runtime/c/pgf/linearizer.c
+++ b/src/runtime/c/pgf/linearizer.c
@@ -618,8 +618,17 @@ pgf_cnc_tree_enum_next(GuEnum* self, void* to, GuPool* pool)
}
PgfCncTreeEnum*
-pgf_lzr_concretize(PgfConcr* concr, PgfExpr expr, GuPool* pool)
+pgf_lzr_concretize(PgfConcr* concr, PgfExpr expr, GuExn* err, GuPool* pool)
{
+ if (concr->fun_indices == NULL ||
+ concr->coerce_idx == NULL) {
+ GuExnData* err_data = gu_raise(err, PgfExn);
+ if (err_data) {
+ err_data->data = "The concrete syntax is not loaded";
+ return NULL;
+ }
+ }
+
PgfLzn* lzn = gu_new(PgfLzn, pool);
lzn->concr = concr;
lzn->expr = expr;
@@ -947,7 +956,10 @@ pgf_linearize(PgfConcr* concr, PgfExpr expr, GuOut* out, GuExn* err)
GuPool* tmp_pool = gu_local_pool();
GuEnum* cts =
- pgf_lzr_concretize(concr, expr, tmp_pool);
+ pgf_lzr_concretize(concr, expr, err, tmp_pool);
+ if (!gu_ok(err))
+ return;
+
PgfCncTree ctree = gu_next(cts, PgfCncTree, tmp_pool);
if (!gu_variant_is_null(ctree)) {
ctree = pgf_lzr_wrap_linref(ctree, tmp_pool);
diff --git a/src/runtime/c/pgf/linearizer.h b/src/runtime/c/pgf/linearizer.h
index e483824b0..b1d96b027 100644
--- a/src/runtime/c/pgf/linearizer.h
+++ b/src/runtime/c/pgf/linearizer.h
@@ -28,7 +28,7 @@ typedef GuEnum PgfCncTreeEnum;
/// Begin enumerating concrete syntax variants.
PgfCncTreeEnum*
-pgf_lzr_concretize(PgfConcr* concr, PgfExpr expr, GuPool* pool);
+pgf_lzr_concretize(PgfConcr* concr, PgfExpr expr, GuExn* err, GuPool* pool);
typedef struct {
} PgfLinNonExist;
diff --git a/src/runtime/c/pgf/parser.c b/src/runtime/c/pgf/parser.c
index 676e0ca29..8f58026ed 100644
--- a/src/runtime/c/pgf/parser.c
+++ b/src/runtime/c/pgf/parser.c
@@ -2438,6 +2438,16 @@ pgf_parse_with_heuristics(PgfConcr* concr, PgfCId cat, GuString sentence,
GuExn* err,
GuPool* pool, GuPool* out_pool)
{
+ if (concr->sequences == NULL ||
+ concr->pre_sequences == NULL ||
+ concr->cnccats == NULL) {
+ GuExnData* err_data = gu_raise(err, PgfExn);
+ if (err_data) {
+ err_data->data = "The concrete syntax is not loaded";
+ return NULL;
+ }
+ }
+
// Begin parsing a sentence with the specified category
PgfParsing* ps =
pgf_parsing_init(concr, cat, 0, sentence, heuristics, err, pool, out_pool);
@@ -2552,6 +2562,14 @@ void
pgf_lookup_morpho(PgfConcr *concr, GuString sentence,
PgfMorphoCallback* callback, GuExn* err)
{
+ if (concr->sequences == NULL) {
+ GuExnData* err_data = gu_raise(err, PgfExn);
+ if (err_data) {
+ err_data->data = "The concrete syntax is not loaded";
+ return;
+ }
+ }
+
PgfSequence* seq = (PgfSequence*)
gu_seq_binsearch(concr->sequences, pgf_sequence_order,
PgfSequence, (void*) sentence);
@@ -2577,21 +2595,23 @@ gu_fullform_enum_next(GuEnum* self, void* to, GuPool* pool)
PgfFullFormState* st = gu_container(self, PgfFullFormState, en);
PgfFullFormEntry* entry = NULL;
- size_t n_seqs = gu_seq_length(st->sequences);
- while (st->seq_idx < n_seqs) {
- PgfSymbols* syms = gu_seq_index(st->sequences, PgfSequence, st->seq_idx)->syms;
- GuString tokens = pgf_get_tokens(syms, 0, pool);
- if (strlen(tokens) > 0 &&
- gu_seq_index(st->sequences, PgfSequence, st->seq_idx)->idx != NULL) {
- entry = gu_new(PgfFullFormEntry, pool);
- entry->tokens = tokens;
- entry->idx = gu_seq_index(st->sequences, PgfSequence, st->seq_idx)->idx;
-
+ if (st->sequences != NULL) {
+ size_t n_seqs = gu_seq_length(st->sequences);
+ while (st->seq_idx < n_seqs) {
+ PgfSymbols* syms = gu_seq_index(st->sequences, PgfSequence, st->seq_idx)->syms;
+ GuString tokens = pgf_get_tokens(syms, 0, pool);
+ if (strlen(tokens) > 0 &&
+ gu_seq_index(st->sequences, PgfSequence, st->seq_idx)->idx != NULL) {
+ entry = gu_new(PgfFullFormEntry, pool);
+ entry->tokens = tokens;
+ entry->idx = gu_seq_index(st->sequences, PgfSequence, st->seq_idx)->idx;
+
+ st->seq_idx++;
+ break;
+ }
+
st->seq_idx++;
- break;
}
-
- st->seq_idx++;
}
*((PgfFullFormEntry**) to) = entry;
diff --git a/src/runtime/c/pgf/parseval.c b/src/runtime/c/pgf/parseval.c
index c96eac56a..0090a5942 100644
--- a/src/runtime/c/pgf/parseval.c
+++ b/src/runtime/c/pgf/parseval.c
@@ -171,8 +171,15 @@ pgf_parseval(PgfConcr* concr, PgfExpr expr, PgfCId cat,
{
GuPool* pool = gu_new_pool();
+ GuExn* err = gu_new_exn(NULL, gu_kind(type), pool);
+
GuEnum* en_lins1 =
- pgf_lzr_concretize(concr, expr, pool);
+ pgf_lzr_concretize(concr, expr, err, pool);
+ if (!gu_ok(err)) {
+ gu_pool_free(pool);
+ return false;
+ }
+
PgfCncTree ctree1 = gu_next(en_lins1, PgfCncTree, pool);
if (gu_variant_is_null(ctree1)) {
gu_pool_free(pool);
@@ -213,7 +220,7 @@ pgf_parseval(PgfConcr* concr, PgfExpr expr, PgfCId cat,
}
GuEnum* en_lins2 =
- pgf_lzr_concretize(concr, ep->expr, pool);
+ pgf_lzr_concretize(concr, ep->expr, err, pool);
PgfCncTree ctree2 = gu_next(en_lins2, PgfCncTree, pool);
if (gu_variant_is_null(ctree2)) {
gu_pool_free(pool);
diff --git a/src/runtime/c/pgf/reader.c b/src/runtime/c/pgf/reader.c
index 067d0a35d..ba9f3e30f 100644
--- a/src/runtime/c/pgf/reader.c
+++ b/src/runtime/c/pgf/reader.c
@@ -577,6 +577,17 @@ pgf_read_abstract(PgfReader* rdr, PgfAbstr* abstract)
abstract->cats = pgf_read_abscats(rdr, abstract);
gu_return_on_exn(rdr->err, );
+
+ abstract->abs_lin_fun = gu_new(PgfAbsFun, rdr->opool);
+ abstract->abs_lin_fun->name = "_";
+ abstract->abs_lin_fun->type = gu_new(PgfType, rdr->opool);
+ abstract->abs_lin_fun->type->hypos = NULL;
+ abstract->abs_lin_fun->type->cid = "_";
+ abstract->abs_lin_fun->type->n_exprs = 0;
+ abstract->abs_lin_fun->arity = 0;
+ abstract->abs_lin_fun->defns = NULL;
+ abstract->abs_lin_fun->ep.prob = INFINITY;
+ abstract->abs_lin_fun->ep.expr = gu_null_variant;
}
static PgfCIdMap*
@@ -864,7 +875,7 @@ pgf_read_funid(PgfReader* rdr, PgfConcr* concr)
}
static void
-pgf_read_lindefs(PgfReader* rdr, PgfAbsFun* abs_lin_fun, PgfConcr* concr)
+pgf_read_lindefs(PgfReader* rdr, PgfConcr* concr)
{
size_t len = pgf_read_len(rdr);
gu_return_on_exn(rdr->err, );
@@ -878,14 +889,14 @@ pgf_read_lindefs(PgfReader* rdr, PgfAbsFun* abs_lin_fun, PgfConcr* concr)
ccat->lindefs = gu_new_seq(PgfCncFun*, n_funs, rdr->opool);
for (size_t j = 0; j < n_funs; j++) {
PgfCncFun* fun = pgf_read_funid(rdr, concr);
- fun->absfun = abs_lin_fun;
+ fun->absfun = concr->abstr->abs_lin_fun;
gu_seq_set(ccat->lindefs, PgfCncFun*, j, fun);
}
}
}
static void
-pgf_read_linrefs(PgfReader* rdr, PgfAbsFun* abs_lin_fun, PgfConcr* concr)
+pgf_read_linrefs(PgfReader* rdr, PgfConcr* concr)
{
size_t len = pgf_read_len(rdr);
gu_return_on_exn(rdr->err, );
@@ -899,7 +910,7 @@ pgf_read_linrefs(PgfReader* rdr, PgfAbsFun* abs_lin_fun, PgfConcr* concr)
ccat->linrefs = gu_new_seq(PgfCncFun*, n_funs, rdr->opool);
for (size_t j = 0; j < n_funs; j++) {
PgfCncFun* fun = pgf_read_funid(rdr, concr);
- fun->absfun = abs_lin_fun;
+ fun->absfun = concr->abstr->abs_lin_fun;
gu_seq_set(ccat->linrefs, PgfCncFun*, j, fun);
}
}
@@ -1147,54 +1158,139 @@ pgf_read_ccat_cb(GuMapItor* fn, const void* key, void* value, GuExn* err)
// pgf_ccat_set_viterbi_prob(ccat);
}
-static PgfConcr*
-pgf_read_concrete(PgfReader* rdr, PgfAbstr* abstr, PgfAbsFun* abs_lin_fun)
+void
+pgf_read_concrete_content(PgfReader* rdr, PgfConcr* concr)
{
- PgfConcr* concr = gu_new(PgfConcr, rdr->opool);
-
- concr->name =
- pgf_read_cid(rdr, rdr->opool);
- gu_return_on_exn(rdr->err, NULL);
-
- concr->abstr = abstr;
-
- concr->cflags =
- pgf_read_flags(rdr);
- gu_return_on_exn(rdr->err, NULL);
-
- concr->printnames =
+ concr->printnames =
pgf_read_printnames(rdr);
- gu_return_on_exn(rdr->err, NULL);
-
- concr->sequences =
+ gu_return_on_exn(rdr->err,);
+
+ concr->sequences =
pgf_read_sequences(rdr);
- gu_return_on_exn(rdr->err, NULL);
+ gu_return_on_exn(rdr->err,);
concr->pre_sequences = gu_new_buf(PgfSequence, rdr->opool);
concr->cncfuns =
- pgf_read_cncfuns(rdr, abstr, concr);
- gu_return_on_exn(rdr->err, NULL);
+ pgf_read_cncfuns(rdr, concr->abstr, concr);
+ gu_return_on_exn(rdr->err,);
concr->ccats =
gu_new_int_map(PgfCCat*, &gu_null_struct, rdr->opool);
concr->fun_indices = gu_map_type_new(PgfCncFunOverloadMap, rdr->opool);
concr->coerce_idx = gu_map_type_new(PgfCncOverloadMap, rdr->opool);
- pgf_read_lindefs(rdr, abs_lin_fun, concr);
- pgf_read_linrefs(rdr, abs_lin_fun, concr);
+ pgf_read_lindefs(rdr, concr);
+ pgf_read_linrefs(rdr, concr);
pgf_read_ccats(rdr, concr);
- concr->cnccats = pgf_read_cnccats(rdr, abstr, concr);
+ concr->cnccats = pgf_read_cnccats(rdr, concr->abstr, concr);
concr->callbacks = pgf_new_callbacks_map(concr, rdr->opool);
concr->total_cats = pgf_read_int(rdr);
GuMapItor clo1 = { pgf_read_ccat_cb };
gu_map_iter(concr->ccats, &clo1, NULL);
+}
+
+static void
+pgf_read_concrete_init_header(PgfConcr* concr)
+{
+ concr->printnames = NULL;
+ concr->sequences = NULL;
+ concr->pre_sequences = NULL;
+ concr->cncfuns = NULL;
+ concr->ccats = NULL;
+ concr->fun_indices = NULL;
+ concr->coerce_idx = NULL;
+ concr->cnccats = NULL;
+ concr->callbacks = NULL;
+ concr->total_cats = 0;
+}
+
+static void
+gu_concr_fini(GuFinalizer* fin)
+{
+ PgfConcr* concr = gu_container(fin, PgfConcr, fin);
+
+ if (concr->pool != NULL) {
+ pgf_read_concrete_init_header(concr);
+ gu_pool_free(concr->pool);
+ concr->pool = NULL;
+ }
+}
+
+static PgfConcr*
+pgf_read_concrete(PgfReader* rdr, PgfAbstr* abstr, bool with_content)
+{
+ PgfConcr* concr = gu_new(PgfConcr, rdr->opool);
+
+ concr->name =
+ pgf_read_cid(rdr, rdr->opool);
+ gu_return_on_exn(rdr->err, NULL);
+
+ concr->abstr = abstr;
+
+ concr->cflags =
+ pgf_read_flags(rdr);
+ gu_return_on_exn(rdr->err, NULL);
+
+ concr->pool = NULL;
+
+ if (with_content)
+ pgf_read_concrete_content(rdr, concr);
+ else {
+ pgf_read_concrete_init_header(concr);
+
+ concr->fin.fn = gu_concr_fini;
+ gu_pool_finally(rdr->opool, &concr->fin);
+ }
+ gu_return_on_exn(rdr->err, NULL);
return concr;
}
+void
+pgf_concrete_load(PgfConcr* concr, GuIn* in, GuExn* err)
+{
+ if (concr->pool != NULL)
+ return; // already loaded
+
+ GuPool* pool = gu_new_pool();
+ GuPool* tmp_pool = gu_local_pool();
+
+ PgfReader* rdr = pgf_new_reader(in, pool, tmp_pool, err);
+
+ PgfCId name =
+ pgf_read_cid(rdr, rdr->tmp_pool);
+ gu_return_on_exn(rdr->err, );
+
+ if (strcmp(name, concr->name) != 0) {
+ GuExnData* err_data = gu_raise(rdr->err, PgfExn);
+ if (err_data) {
+ err_data->data = "This file contains different concrete syntax";
+ gu_pool_free(tmp_pool);
+ gu_pool_free(pool);
+ return;
+ }
+ }
+
+ concr->pool = pool;
+
+ pgf_read_flags(rdr);
+ gu_return_on_exn(rdr->err, );
+
+ pgf_read_concrete_content(rdr, concr);
+ gu_return_on_exn(rdr->err, );
+
+ gu_pool_free(tmp_pool);
+}
+
+void
+pgf_concrete_unload(PgfConcr* concr)
+{
+ gu_concr_fini(&concr->fin);
+}
+
static PgfCIdMap*
-pgf_read_concretes(PgfReader* rdr, PgfAbstr* abstr)
+pgf_read_concretes(PgfReader* rdr, PgfAbstr* abstr, bool with_content)
{
GuMapType* map_type = (GuMapType*)
GU_TYPE_LIT(GuStringMap, _,
@@ -1205,19 +1301,8 @@ pgf_read_concretes(PgfReader* rdr, PgfAbstr* abstr)
size_t len = pgf_read_len(rdr);
gu_return_on_exn(rdr->err, NULL);
- PgfAbsFun* abs_lin_fun = gu_new(PgfAbsFun, rdr->opool);
- abs_lin_fun->name = "_";
- abs_lin_fun->type = gu_new(PgfType, rdr->opool);
- abs_lin_fun->type->hypos = NULL;
- abs_lin_fun->type->cid = "_";
- abs_lin_fun->type->n_exprs = 0;
- abs_lin_fun->arity = 0;
- abs_lin_fun->defns = NULL;
- abs_lin_fun->ep.prob = INFINITY;
- abs_lin_fun->ep.expr = gu_null_variant;
-
for (size_t i = 0; i < len; i++) {
- PgfConcr* concr = pgf_read_concrete(rdr, abstr, abs_lin_fun);
+ PgfConcr* concr = pgf_read_concrete(rdr, abstr, with_content);
gu_return_on_exn(rdr->err, NULL);
gu_map_put(concretes, concr->name, PgfConcr*, concr);
@@ -1242,7 +1327,9 @@ pgf_read_pgf(PgfReader* rdr) {
pgf_read_abstract(rdr, &pgf->abstract);
gu_return_on_exn(rdr->err, NULL);
- pgf->concretes = pgf_read_concretes(rdr, &pgf->abstract);
+ bool with_content =
+ gu_variant_is_null(gu_map_get(pgf->gflags, "split", PgfLiteral));
+ pgf->concretes = pgf_read_concretes(rdr, &pgf->abstract, with_content);
gu_return_on_exn(rdr->err, NULL);
return pgf;
diff --git a/src/runtime/c/pgf/reader.h b/src/runtime/c/pgf/reader.h
index 95dfc855f..7011eea17 100644
--- a/src/runtime/c/pgf/reader.h
+++ b/src/runtime/c/pgf/reader.h
@@ -14,6 +14,12 @@ PgfPGF*
pgf_read_pgf(PgfReader* rdr);
void
+pgf_concrete_load(PgfConcr* concr, GuIn* in, GuExn* err);
+
+void
+pgf_concrete_unload(PgfConcr* concr);
+
+void
pgf_reader_done(PgfReader* rdr, PgfPGF* pgf);
#endif // READER_H_