mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 03:32:51 -06:00
now the web service to the robust parser can to translations also
This commit is contained in:
@@ -59,7 +59,7 @@ static int
|
|||||||
generate_graphviz_expr(PgfExpr expr, int *pid,
|
generate_graphviz_expr(PgfExpr expr, int *pid,
|
||||||
GuWriter* wtr, GuExn* err, GuPool* pool)
|
GuWriter* wtr, GuExn* err, GuPool* pool)
|
||||||
{
|
{
|
||||||
int id;
|
int id = -1;
|
||||||
|
|
||||||
GuVariantInfo ei = gu_variant_open(expr);
|
GuVariantInfo ei = gu_variant_open(expr);
|
||||||
switch (ei.tag) {
|
switch (ei.tag) {
|
||||||
@@ -188,6 +188,55 @@ render(PgfExpr expr, GuPool* pool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_gu_string(GuString s) {
|
||||||
|
GuWord w = s.w_;
|
||||||
|
uint8_t buf[sizeof(GuWord)];
|
||||||
|
|
||||||
|
char* src;
|
||||||
|
size_t len;
|
||||||
|
if (w & 1) {
|
||||||
|
len = (w & 0xff) >> 1;
|
||||||
|
gu_assert(len <= sizeof(GuWord));
|
||||||
|
size_t i = len;
|
||||||
|
while (i > 0) {
|
||||||
|
w >>= 8;
|
||||||
|
buf[--i] = w & 0xff;
|
||||||
|
}
|
||||||
|
src = (char*) buf;
|
||||||
|
} else {
|
||||||
|
uint8_t* p = (void*) w;
|
||||||
|
len = (p[0] == 0) ? ((size_t*) p)[-1] : p[0];
|
||||||
|
src = (char*) &p[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
FCGI_putchar(src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
linearize(PgfConcr* concr, PgfExpr expr, GuPool* pool)
|
||||||
|
{
|
||||||
|
GuStringBuf* sbuf = gu_string_buf(pool);
|
||||||
|
GuWriter* wtr = gu_string_buf_writer(sbuf);
|
||||||
|
|
||||||
|
GuExn* err = gu_new_exn(NULL, gu_kind(type), pool);
|
||||||
|
|
||||||
|
pgf_linearize(concr, expr, wtr, err);
|
||||||
|
|
||||||
|
GuString s = gu_string_buf_freeze(sbuf, pool);
|
||||||
|
put_gu_string(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_lang(GuMapItor* fn, const void* key, void* value, GuExn* err)
|
||||||
|
{
|
||||||
|
PgfCId lang = *((PgfCId*) key);
|
||||||
|
put_gu_string(lang);
|
||||||
|
FCGI_putchar(' ');
|
||||||
|
}
|
||||||
|
|
||||||
int main ()
|
int main ()
|
||||||
{
|
{
|
||||||
// Create the pool that is used to allocate everything
|
// Create the pool that is used to allocate everything
|
||||||
@@ -220,7 +269,7 @@ int main ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the extra probs.
|
// Read the extra probs.
|
||||||
char* probs_name = "/ParseEngAbs2.probs";
|
char* probs_name = "/ParseEngAbs3.probs";
|
||||||
char* probs_file = malloc(strlen(grammar_path)+strlen(probs_name)+1);
|
char* probs_file = malloc(strlen(grammar_path)+strlen(probs_name)+1);
|
||||||
strcpy(probs_file,grammar_path);
|
strcpy(probs_file,grammar_path);
|
||||||
strcat(probs_file,probs_name);
|
strcat(probs_file,probs_name);
|
||||||
@@ -234,39 +283,51 @@ int main ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
GuString cat = gu_str_string("Phr", pool);
|
GuString cat = gu_str_string("Phr", pool);
|
||||||
GuString lang = gu_str_string("ParseEng", pool);
|
GuString from_lang = gu_str_string("ParseEng", pool);
|
||||||
PgfConcr* concr =
|
PgfConcr* from_concr =
|
||||||
pgf_get_language(pgf, lang);
|
pgf_get_language(pgf, from_lang);
|
||||||
if (!concr) {
|
if (!from_concr) {
|
||||||
status = EXIT_FAILURE;
|
status = EXIT_FAILURE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register a callback for the literal category Symbol
|
// Register a callback for the literal category Symbol
|
||||||
pgf_parser_add_literal(concr, gu_str_string("Symb", pool),
|
pgf_parser_add_literal(from_concr, gu_str_string("Symb", pool),
|
||||||
&pgf_nerc_literal_callback);
|
&pgf_nerc_literal_callback);
|
||||||
|
|
||||||
while (FCGI_Accept() >= 0) {
|
while (FCGI_Accept() >= 0) {
|
||||||
char* sentence = getenv("QUERY_STRING");
|
char* query = getenv("QUERY_STRING");
|
||||||
if (sentence == NULL ||
|
|
||||||
(sentence = strchr(sentence, '=')) == NULL) {
|
|
||||||
FCGI_printf("Content-type: text/html\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"<body>Please type a sentence to parse</body>\r\n");
|
|
||||||
} else {
|
|
||||||
sentence++;
|
|
||||||
|
|
||||||
|
char sentence[202];
|
||||||
|
char to_lang_buf[51] = "";
|
||||||
|
if (query == NULL ||
|
||||||
|
sscanf(query, "sentence=%200[^&]&to=%50[^&]", sentence, to_lang_buf) < 1) {
|
||||||
|
FCGI_printf("Status: 200 OK\r\n");
|
||||||
|
FCGI_printf("Content-type: text/plain; charset=utf-8\r\n\r\n");
|
||||||
|
|
||||||
|
GuMapItor clo = { print_lang };
|
||||||
|
pgf_iter_languages(pgf, &clo, NULL);
|
||||||
|
FCGI_putchar('\n');
|
||||||
|
} else {
|
||||||
// We create a temporary pool for translating a single
|
// We create a temporary pool for translating a single
|
||||||
// sentence, so our memory usage doesn't increase over time.
|
// sentence, so our memory usage doesn't increase over time.
|
||||||
GuPool* ppool = gu_new_pool();
|
GuPool* ppool = gu_new_pool();
|
||||||
|
|
||||||
char* tmp = gu_malloc(ppool, strlen(sentence)+2);
|
PgfConcr* to_concr = NULL;
|
||||||
strcpy(tmp, sentence);
|
if (strlen(to_lang_buf) > 0) {
|
||||||
url_escape(tmp);
|
GuString to_lang = gu_str_string(to_lang_buf, ppool);
|
||||||
int len = strlen(tmp);
|
to_concr =
|
||||||
tmp[len] = '\n';
|
pgf_get_language(pgf, to_lang);
|
||||||
tmp[len+1] = '\0';
|
if (!to_concr) {
|
||||||
sentence = tmp;
|
status = EXIT_FAILURE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url_escape(sentence);
|
||||||
|
int len = strlen(sentence);
|
||||||
|
sentence[len] = '\n';
|
||||||
|
sentence[len+1] = '\0';
|
||||||
|
|
||||||
GuReader *rdr =
|
GuReader *rdr =
|
||||||
gu_string_reader(gu_str_string(sentence, ppool), ppool);
|
gu_string_reader(gu_str_string(sentence, ppool), ppool);
|
||||||
@@ -274,26 +335,34 @@ int main ()
|
|||||||
pgf_new_simple_lexer(rdr, ppool);
|
pgf_new_simple_lexer(rdr, ppool);
|
||||||
|
|
||||||
GuEnum* result =
|
GuEnum* result =
|
||||||
pgf_parse(concr, cat, lexer, ppool);
|
pgf_parse(from_concr, cat, lexer, ppool);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
FCGI_printf("Content-type: text/html\r\n"
|
FCGI_printf("Status: 500 Internal Server Error\r\n");
|
||||||
|
FCGI_printf("Content-type: text/plain\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"<body>Parsing failed</body>");
|
"Parsing failed");
|
||||||
goto fail_request;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfExprProb* ep = gu_next(result, PgfExprProb*, ppool);
|
PgfExprProb* ep = gu_next(result, PgfExprProb*, ppool);
|
||||||
if (ep == NULL) {
|
if (ep == NULL) {
|
||||||
FCGI_printf("Content-type: text/html\r\n"
|
FCGI_printf("Status: 500 Internal Server Error\r\n");
|
||||||
|
FCGI_printf("Content-type: text/plain\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"<body>The sentence was parsed but there was no tree constructed</body>");
|
"The sentence was parsed but there was no tree constructed");
|
||||||
goto fail_request;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
FCGI_printf("Content-type: image/svg+xml\r\n\r\n");
|
FCGI_printf("Status: 200 OK\r\n");
|
||||||
render(ep->expr, ppool);
|
if (to_concr == NULL) {
|
||||||
|
FCGI_printf("Content-type: image/svg+xml\r\n\r\n");
|
||||||
|
render(ep->expr, ppool);
|
||||||
|
} else {
|
||||||
|
FCGI_printf("Content-type: text/plain; charset=utf-8\r\n\r\n");
|
||||||
|
linearize(to_concr, ep->expr, ppool);
|
||||||
|
}
|
||||||
|
|
||||||
fail_request:
|
done:
|
||||||
gu_pool_free(ppool);
|
gu_pool_free(ppool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user