48ecd83421
- Fix wrong ELP import paths in soul.el, elp-input.el, studio.el (../foundation/elp/src → ../foundation/el/elp/src) - Add missing import "morphology.el" to all 29 language morphology modules - Recompile all affected dist/*.c with correct cross-module declarations - Add dist/elp-c-decls.h: C-level master forward declarations for ELP package (enables elb --force-include to resolve undeclared cross-module calls)
659 lines
20 KiB
C
659 lines
20 KiB
C
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include "el_runtime.h"
|
|
|
|
el_val_t slots_get(el_val_t slots, el_val_t key);
|
|
el_val_t slots_set(el_val_t slots, el_val_t key, el_val_t val);
|
|
el_val_t make_slots(el_val_t k0, el_val_t v0);
|
|
el_val_t make_slots2(el_val_t k0, el_val_t v0, el_val_t k1, el_val_t v1);
|
|
el_val_t make_slots3(el_val_t k0, el_val_t v0, el_val_t k1, el_val_t v1, el_val_t k2, el_val_t v2);
|
|
el_val_t make_slots4(el_val_t k0, el_val_t v0, el_val_t k1, el_val_t v1, el_val_t k2, el_val_t v2, el_val_t k3, el_val_t v3);
|
|
el_val_t make_slots5(el_val_t k0, el_val_t v0, el_val_t k1, el_val_t v1, el_val_t k2, el_val_t v2, el_val_t k3, el_val_t v3, el_val_t k4, el_val_t v4);
|
|
el_val_t rule_id(el_val_t rule);
|
|
el_val_t rule_lhs(el_val_t rule);
|
|
el_val_t rule_rhs_len(el_val_t rule);
|
|
el_val_t rule_rhs(el_val_t rule, el_val_t idx);
|
|
el_val_t make_rule(el_val_t id, el_val_t lhs, el_val_t r0);
|
|
el_val_t make_rule2(el_val_t id, el_val_t lhs, el_val_t r0, el_val_t r1);
|
|
el_val_t make_rule3(el_val_t id, el_val_t lhs, el_val_t r0, el_val_t r1, el_val_t r2);
|
|
el_val_t make_rule4(el_val_t id, el_val_t lhs, el_val_t r0, el_val_t r1, el_val_t r2, el_val_t r3);
|
|
el_val_t build_rules(void);
|
|
el_val_t get_rules(void);
|
|
el_val_t find_rule(el_val_t rule_id_str);
|
|
el_val_t make_leaf(el_val_t label, el_val_t word);
|
|
el_val_t make_node1(el_val_t label, el_val_t child0);
|
|
el_val_t make_node2(el_val_t label, el_val_t child0, el_val_t child1);
|
|
el_val_t make_node3(el_val_t label, el_val_t child0, el_val_t child1, el_val_t child2);
|
|
el_val_t make_node4(el_val_t label, el_val_t child0, el_val_t child1, el_val_t child2, el_val_t child3);
|
|
el_val_t nlg_is_ws(el_val_t c);
|
|
el_val_t skip_ws(el_val_t s, el_val_t pos);
|
|
el_val_t scan_token(el_val_t s, el_val_t start);
|
|
el_val_t render_tree(el_val_t tree);
|
|
el_val_t gram_word_order(el_val_t profile);
|
|
el_val_t gram_order_constituents(el_val_t subj, el_val_t verb, el_val_t obj, el_val_t profile);
|
|
el_val_t gram_build_vp(el_val_t verb, el_val_t aux, el_val_t profile);
|
|
el_val_t gram_question_strategy(el_val_t profile);
|
|
el_val_t is_pronoun(el_val_t word);
|
|
el_val_t build_np(el_val_t referent, el_val_t slots);
|
|
el_val_t build_pp(el_val_t loc);
|
|
el_val_t build_vp_body(el_val_t slots);
|
|
el_val_t build_vp_from_slots(el_val_t slots);
|
|
el_val_t generate_tree(el_val_t rule_id_str, el_val_t slots);
|
|
|
|
el_val_t slots_get(el_val_t slots, el_val_t key) {
|
|
el_val_t n = native_list_len(slots);
|
|
el_val_t i = 0;
|
|
while (i < (n - 1)) {
|
|
el_val_t k = native_list_get(slots, i);
|
|
if (str_eq(k, key)) {
|
|
return native_list_get(slots, (i + 1));
|
|
}
|
|
i = (i + 2);
|
|
}
|
|
return EL_STR("");
|
|
return 0;
|
|
}
|
|
|
|
el_val_t slots_set(el_val_t slots, el_val_t key, el_val_t val) {
|
|
el_val_t n = native_list_len(slots);
|
|
el_val_t result = native_list_empty();
|
|
el_val_t found = 0;
|
|
el_val_t i = 0;
|
|
while (i < (n - 1)) {
|
|
el_val_t k = native_list_get(slots, i);
|
|
el_val_t v = native_list_get(slots, (i + 1));
|
|
if (str_eq(k, key)) {
|
|
result = native_list_append(result, k);
|
|
result = native_list_append(result, val);
|
|
found = 1;
|
|
} else {
|
|
result = native_list_append(result, k);
|
|
result = native_list_append(result, v);
|
|
}
|
|
i = (i + 2);
|
|
}
|
|
if (!found) {
|
|
result = native_list_append(result, key);
|
|
result = native_list_append(result, val);
|
|
}
|
|
return result;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_slots(el_val_t k0, el_val_t v0) {
|
|
el_val_t r = native_list_empty();
|
|
r = native_list_append(r, k0);
|
|
r = native_list_append(r, v0);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_slots2(el_val_t k0, el_val_t v0, el_val_t k1, el_val_t v1) {
|
|
el_val_t r = make_slots(k0, v0);
|
|
r = native_list_append(r, k1);
|
|
r = native_list_append(r, v1);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_slots3(el_val_t k0, el_val_t v0, el_val_t k1, el_val_t v1, el_val_t k2, el_val_t v2) {
|
|
el_val_t r = make_slots2(k0, v0, k1, v1);
|
|
r = native_list_append(r, k2);
|
|
r = native_list_append(r, v2);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_slots4(el_val_t k0, el_val_t v0, el_val_t k1, el_val_t v1, el_val_t k2, el_val_t v2, el_val_t k3, el_val_t v3) {
|
|
el_val_t r = make_slots3(k0, v0, k1, v1, k2, v2);
|
|
r = native_list_append(r, k3);
|
|
r = native_list_append(r, v3);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_slots5(el_val_t k0, el_val_t v0, el_val_t k1, el_val_t v1, el_val_t k2, el_val_t v2, el_val_t k3, el_val_t v3, el_val_t k4, el_val_t v4) {
|
|
el_val_t r = make_slots4(k0, v0, k1, v1, k2, v2, k3, v3);
|
|
r = native_list_append(r, k4);
|
|
r = native_list_append(r, v4);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t rule_id(el_val_t rule) {
|
|
return native_list_get(rule, 0);
|
|
return 0;
|
|
}
|
|
|
|
el_val_t rule_lhs(el_val_t rule) {
|
|
return native_list_get(rule, 1);
|
|
return 0;
|
|
}
|
|
|
|
el_val_t rule_rhs_len(el_val_t rule) {
|
|
el_val_t n = native_list_len(rule);
|
|
return (n - 2);
|
|
return 0;
|
|
}
|
|
|
|
el_val_t rule_rhs(el_val_t rule, el_val_t idx) {
|
|
return native_list_get(rule, (idx + 2));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_rule(el_val_t id, el_val_t lhs, el_val_t r0) {
|
|
el_val_t r = native_list_empty();
|
|
r = native_list_append(r, id);
|
|
r = native_list_append(r, lhs);
|
|
r = native_list_append(r, r0);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_rule2(el_val_t id, el_val_t lhs, el_val_t r0, el_val_t r1) {
|
|
el_val_t r = make_rule(id, lhs, r0);
|
|
r = native_list_append(r, r1);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_rule3(el_val_t id, el_val_t lhs, el_val_t r0, el_val_t r1, el_val_t r2) {
|
|
el_val_t r = make_rule2(id, lhs, r0, r1);
|
|
r = native_list_append(r, r2);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_rule4(el_val_t id, el_val_t lhs, el_val_t r0, el_val_t r1, el_val_t r2, el_val_t r3) {
|
|
el_val_t r = make_rule3(id, lhs, r0, r1, r2);
|
|
r = native_list_append(r, r3);
|
|
return r;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t build_rules(void) {
|
|
el_val_t rules = native_list_empty();
|
|
rules = native_list_append(rules, make_rule2(EL_STR("S-DECL"), EL_STR("S"), EL_STR("NP"), EL_STR("VP")));
|
|
rules = native_list_append(rules, make_rule3(EL_STR("S-QUEST"), EL_STR("S"), EL_STR("Aux"), EL_STR("NP"), EL_STR("VP")));
|
|
rules = native_list_append(rules, make_rule(EL_STR("S-IMP"), EL_STR("S"), EL_STR("VP")));
|
|
rules = native_list_append(rules, make_rule2(EL_STR("NP-DET-N"), EL_STR("NP"), EL_STR("Det"), EL_STR("N")));
|
|
rules = native_list_append(rules, make_rule3(EL_STR("NP-DET-ADJ-N"), EL_STR("NP"), EL_STR("Det"), EL_STR("Adj"), EL_STR("N")));
|
|
rules = native_list_append(rules, make_rule(EL_STR("NP-PRON"), EL_STR("NP"), EL_STR("Pron")));
|
|
rules = native_list_append(rules, make_rule(EL_STR("NP-N"), EL_STR("NP"), EL_STR("N")));
|
|
rules = native_list_append(rules, make_rule(EL_STR("VP-V"), EL_STR("VP"), EL_STR("V")));
|
|
rules = native_list_append(rules, make_rule2(EL_STR("VP-V-NP"), EL_STR("VP"), EL_STR("V"), EL_STR("NP")));
|
|
rules = native_list_append(rules, make_rule2(EL_STR("VP-V-PP"), EL_STR("VP"), EL_STR("V"), EL_STR("PP")));
|
|
rules = native_list_append(rules, make_rule3(EL_STR("VP-V-NP-PP"), EL_STR("VP"), EL_STR("V"), EL_STR("NP"), EL_STR("PP")));
|
|
rules = native_list_append(rules, make_rule2(EL_STR("VP-AUX-V"), EL_STR("VP"), EL_STR("Aux"), EL_STR("V")));
|
|
rules = native_list_append(rules, make_rule3(EL_STR("VP-AUX-V-NP"), EL_STR("VP"), EL_STR("Aux"), EL_STR("V"), EL_STR("NP")));
|
|
rules = native_list_append(rules, make_rule2(EL_STR("PP-P-NP"), EL_STR("PP"), EL_STR("P"), EL_STR("NP")));
|
|
return rules;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t get_rules(void) {
|
|
return build_rules();
|
|
return 0;
|
|
}
|
|
|
|
el_val_t find_rule(el_val_t rule_id_str) {
|
|
el_val_t rules = get_rules();
|
|
el_val_t n = native_list_len(rules);
|
|
el_val_t i = 0;
|
|
while (i < n) {
|
|
el_val_t rule = native_list_get(rules, i);
|
|
el_val_t id = native_list_get(rule, 0);
|
|
if (str_eq(id, rule_id_str)) {
|
|
return rule;
|
|
}
|
|
i = (i + 1);
|
|
}
|
|
el_val_t empty = native_list_empty();
|
|
return empty;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_leaf(el_val_t label, el_val_t word) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), label), EL_STR(" ")), word), EL_STR(")"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_node1(el_val_t label, el_val_t child0) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), label), EL_STR(" _ ")), child0), EL_STR(")"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_node2(el_val_t label, el_val_t child0, el_val_t child1) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), label), EL_STR(" _ ")), child0), EL_STR(" ")), child1), EL_STR(")"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_node3(el_val_t label, el_val_t child0, el_val_t child1, el_val_t child2) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), label), EL_STR(" _ ")), child0), EL_STR(" ")), child1), EL_STR(" ")), child2), EL_STR(")"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t make_node4(el_val_t label, el_val_t child0, el_val_t child1, el_val_t child2, el_val_t child3) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), label), EL_STR(" _ ")), child0), EL_STR(" ")), child1), EL_STR(" ")), child2), EL_STR(" ")), child3), EL_STR(")"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t nlg_is_ws(el_val_t c) {
|
|
if (str_eq(c, EL_STR(" "))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(c, EL_STR("\t"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(c, EL_STR("\n"))) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t skip_ws(el_val_t s, el_val_t pos) {
|
|
el_val_t n = str_len(s);
|
|
el_val_t i = pos;
|
|
el_val_t running = 1;
|
|
while (running) {
|
|
if (i >= n) {
|
|
running = 0;
|
|
} else {
|
|
el_val_t c = str_slice(s, i, (i + 1));
|
|
if (nlg_is_ws(c)) {
|
|
i = (i + 1);
|
|
} else {
|
|
running = 0;
|
|
}
|
|
}
|
|
}
|
|
return i;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t scan_token(el_val_t s, el_val_t start) {
|
|
el_val_t n = str_len(s);
|
|
el_val_t i = start;
|
|
el_val_t running = 1;
|
|
while (running) {
|
|
if (i >= n) {
|
|
running = 0;
|
|
} else {
|
|
el_val_t c = str_slice(s, i, (i + 1));
|
|
if (nlg_is_ws(c)) {
|
|
running = 0;
|
|
} else {
|
|
if (str_eq(c, EL_STR("("))) {
|
|
running = 0;
|
|
} else {
|
|
if (str_eq(c, EL_STR(")"))) {
|
|
running = 0;
|
|
} else {
|
|
i = (i + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
el_val_t tok = str_slice(s, start, i);
|
|
el_val_t result = native_list_empty();
|
|
result = native_list_append(result, tok);
|
|
result = native_list_append(result, int_to_str(i));
|
|
return result;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t render_tree(el_val_t tree) {
|
|
el_val_t words = native_list_empty();
|
|
el_val_t n = str_len(tree);
|
|
el_val_t i = 0;
|
|
el_val_t prev_was_open = 0;
|
|
while (i < n) {
|
|
el_val_t c = str_slice(tree, i, (i + 1));
|
|
if (str_eq(c, EL_STR("("))) {
|
|
prev_was_open = 1;
|
|
i = (i + 1);
|
|
} else {
|
|
if (str_eq(c, EL_STR(")"))) {
|
|
prev_was_open = 0;
|
|
i = (i + 1);
|
|
} else {
|
|
if (nlg_is_ws(c)) {
|
|
i = (i + 1);
|
|
} else {
|
|
el_val_t tok_info = scan_token(tree, i);
|
|
el_val_t tok = native_list_get(tok_info, 0);
|
|
el_val_t new_i = str_to_int(native_list_get(tok_info, 1));
|
|
i = new_i;
|
|
if (prev_was_open) {
|
|
prev_was_open = 0;
|
|
} else {
|
|
if (!str_eq(tok, EL_STR("_"))) {
|
|
words = native_list_append(words, tok);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return str_join(words, EL_STR(" "));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t gram_word_order(el_val_t profile) {
|
|
return lang_word_order(profile);
|
|
return 0;
|
|
}
|
|
|
|
el_val_t gram_order_constituents(el_val_t subj, el_val_t verb, el_val_t obj, el_val_t profile) {
|
|
el_val_t order = gram_word_order(profile);
|
|
el_val_t parts = native_list_empty();
|
|
if (str_eq(order, EL_STR("SVO"))) {
|
|
if (!str_eq(subj, EL_STR(""))) {
|
|
parts = native_list_append(parts, subj);
|
|
}
|
|
if (!str_eq(verb, EL_STR(""))) {
|
|
parts = native_list_append(parts, verb);
|
|
}
|
|
if (!str_eq(obj, EL_STR(""))) {
|
|
parts = native_list_append(parts, obj);
|
|
}
|
|
return str_join(parts, EL_STR(" "));
|
|
}
|
|
if (str_eq(order, EL_STR("SOV"))) {
|
|
if (!str_eq(subj, EL_STR(""))) {
|
|
parts = native_list_append(parts, subj);
|
|
}
|
|
if (!str_eq(obj, EL_STR(""))) {
|
|
parts = native_list_append(parts, obj);
|
|
}
|
|
if (!str_eq(verb, EL_STR(""))) {
|
|
parts = native_list_append(parts, verb);
|
|
}
|
|
return str_join(parts, EL_STR(" "));
|
|
}
|
|
if (str_eq(order, EL_STR("VSO"))) {
|
|
if (!str_eq(verb, EL_STR(""))) {
|
|
parts = native_list_append(parts, verb);
|
|
}
|
|
if (!str_eq(subj, EL_STR(""))) {
|
|
parts = native_list_append(parts, subj);
|
|
}
|
|
if (!str_eq(obj, EL_STR(""))) {
|
|
parts = native_list_append(parts, obj);
|
|
}
|
|
return str_join(parts, EL_STR(" "));
|
|
}
|
|
if (str_eq(order, EL_STR("VOS"))) {
|
|
if (!str_eq(verb, EL_STR(""))) {
|
|
parts = native_list_append(parts, verb);
|
|
}
|
|
if (!str_eq(obj, EL_STR(""))) {
|
|
parts = native_list_append(parts, obj);
|
|
}
|
|
if (!str_eq(subj, EL_STR(""))) {
|
|
parts = native_list_append(parts, subj);
|
|
}
|
|
return str_join(parts, EL_STR(" "));
|
|
}
|
|
if (str_eq(order, EL_STR("OVS"))) {
|
|
if (!str_eq(obj, EL_STR(""))) {
|
|
parts = native_list_append(parts, obj);
|
|
}
|
|
if (!str_eq(verb, EL_STR(""))) {
|
|
parts = native_list_append(parts, verb);
|
|
}
|
|
if (!str_eq(subj, EL_STR(""))) {
|
|
parts = native_list_append(parts, subj);
|
|
}
|
|
return str_join(parts, EL_STR(" "));
|
|
}
|
|
if (str_eq(order, EL_STR("OSV"))) {
|
|
if (!str_eq(obj, EL_STR(""))) {
|
|
parts = native_list_append(parts, obj);
|
|
}
|
|
if (!str_eq(subj, EL_STR(""))) {
|
|
parts = native_list_append(parts, subj);
|
|
}
|
|
if (!str_eq(verb, EL_STR(""))) {
|
|
parts = native_list_append(parts, verb);
|
|
}
|
|
return str_join(parts, EL_STR(" "));
|
|
}
|
|
if (!str_eq(subj, EL_STR(""))) {
|
|
parts = native_list_append(parts, subj);
|
|
}
|
|
if (!str_eq(verb, EL_STR(""))) {
|
|
parts = native_list_append(parts, verb);
|
|
}
|
|
if (!str_eq(obj, EL_STR(""))) {
|
|
parts = native_list_append(parts, obj);
|
|
}
|
|
return str_join(parts, EL_STR(" "));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t gram_build_vp(el_val_t verb, el_val_t aux, el_val_t profile) {
|
|
if (str_eq(aux, EL_STR(""))) {
|
|
return verb;
|
|
}
|
|
return el_str_concat(el_str_concat(aux, EL_STR(" ")), verb);
|
|
return 0;
|
|
}
|
|
|
|
el_val_t gram_question_strategy(el_val_t profile) {
|
|
el_val_t code = lang_get(profile, EL_STR("code"));
|
|
if (str_eq(code, EL_STR("en"))) {
|
|
return EL_STR("do-support");
|
|
}
|
|
if (str_eq(code, EL_STR("ja"))) {
|
|
return EL_STR("particle");
|
|
}
|
|
if (str_eq(code, EL_STR("zh"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("es"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("fr"))) {
|
|
return EL_STR("inversion");
|
|
}
|
|
if (str_eq(code, EL_STR("de"))) {
|
|
return EL_STR("inversion");
|
|
}
|
|
if (str_eq(code, EL_STR("ar"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("hi"))) {
|
|
return EL_STR("particle");
|
|
}
|
|
if (str_eq(code, EL_STR("ru"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("fi"))) {
|
|
return EL_STR("particle");
|
|
}
|
|
if (str_eq(code, EL_STR("sw"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("la"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("he"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("grc"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("ang"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("sa"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("got"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("non"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
if (str_eq(code, EL_STR("enm"))) {
|
|
return EL_STR("do-support");
|
|
}
|
|
if (str_eq(code, EL_STR("pi"))) {
|
|
return EL_STR("intonation");
|
|
}
|
|
return EL_STR("intonation");
|
|
return 0;
|
|
}
|
|
|
|
el_val_t is_pronoun(el_val_t word) {
|
|
if (str_eq(word, EL_STR("I"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("you"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("he"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("she"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("it"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("we"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("they"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("me"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("him"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("her"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("us"))) {
|
|
return 1;
|
|
}
|
|
if (str_eq(word, EL_STR("them"))) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
|
|
el_val_t build_np(el_val_t referent, el_val_t slots) {
|
|
if (is_pronoun(referent)) {
|
|
return make_node1(EL_STR("NP"), make_leaf(EL_STR("Pron"), referent));
|
|
}
|
|
el_val_t parts = str_split(referent, EL_STR(" "));
|
|
el_val_t np = native_list_len(parts);
|
|
if (np == 1) {
|
|
return make_node1(EL_STR("NP"), make_leaf(EL_STR("N"), referent));
|
|
}
|
|
if (np == 2) {
|
|
el_val_t det = native_list_get(parts, 0);
|
|
el_val_t noun = native_list_get(parts, 1);
|
|
return make_node2(EL_STR("NP"), make_leaf(EL_STR("Det"), det), make_leaf(EL_STR("N"), noun));
|
|
}
|
|
if (np == 3) {
|
|
el_val_t det = native_list_get(parts, 0);
|
|
el_val_t adj = native_list_get(parts, 1);
|
|
el_val_t noun = native_list_get(parts, 2);
|
|
return make_node3(EL_STR("NP"), make_leaf(EL_STR("Det"), det), make_leaf(EL_STR("Adj"), adj), make_leaf(EL_STR("N"), noun));
|
|
}
|
|
return make_node1(EL_STR("NP"), make_leaf(EL_STR("N"), referent));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t build_pp(el_val_t loc) {
|
|
el_val_t parts = str_split(loc, EL_STR(" "));
|
|
el_val_t n = native_list_len(parts);
|
|
if (n < 2) {
|
|
return make_leaf(EL_STR("PP"), loc);
|
|
}
|
|
el_val_t prep = native_list_get(parts, 0);
|
|
el_val_t np_parts = native_list_empty();
|
|
el_val_t i = 1;
|
|
while (i < n) {
|
|
np_parts = native_list_append(np_parts, native_list_get(parts, i));
|
|
i = (i + 1);
|
|
}
|
|
el_val_t np_str = str_join(np_parts, EL_STR(" "));
|
|
el_val_t np_tree = build_np(np_str, native_list_empty());
|
|
return make_node2(EL_STR("PP"), make_leaf(EL_STR("P"), prep), np_tree);
|
|
return 0;
|
|
}
|
|
|
|
el_val_t build_vp_body(el_val_t slots) {
|
|
el_val_t verb_surf = slots_get(slots, EL_STR("verb_surf"));
|
|
el_val_t patient = slots_get(slots, EL_STR("patient"));
|
|
el_val_t loc = slots_get(slots, EL_STR("location"));
|
|
if (!str_eq(patient, EL_STR(""))) {
|
|
el_val_t obj_np = build_np(patient, slots);
|
|
if (!str_eq(loc, EL_STR(""))) {
|
|
el_val_t pp = build_pp(loc);
|
|
return make_node3(EL_STR("VP"), make_leaf(EL_STR("V"), verb_surf), obj_np, pp);
|
|
}
|
|
return make_node2(EL_STR("VP"), make_leaf(EL_STR("V"), verb_surf), obj_np);
|
|
}
|
|
if (!str_eq(loc, EL_STR(""))) {
|
|
el_val_t pp = build_pp(loc);
|
|
return make_node2(EL_STR("VP"), make_leaf(EL_STR("V"), verb_surf), pp);
|
|
}
|
|
return make_node1(EL_STR("VP"), make_leaf(EL_STR("V"), verb_surf));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t build_vp_from_slots(el_val_t slots) {
|
|
el_val_t aux_surf = slots_get(slots, EL_STR("aux_surf"));
|
|
if (!str_eq(aux_surf, EL_STR(""))) {
|
|
el_val_t verb_surf = slots_get(slots, EL_STR("verb_surf"));
|
|
el_val_t patient = slots_get(slots, EL_STR("patient"));
|
|
el_val_t loc = slots_get(slots, EL_STR("location"));
|
|
if (!str_eq(patient, EL_STR(""))) {
|
|
el_val_t obj_np = build_np(patient, slots);
|
|
return make_node3(EL_STR("VP"), make_leaf(EL_STR("Aux"), aux_surf), make_leaf(EL_STR("V"), verb_surf), obj_np);
|
|
}
|
|
return make_node2(EL_STR("VP"), make_leaf(EL_STR("Aux"), aux_surf), make_leaf(EL_STR("V"), verb_surf));
|
|
}
|
|
return build_vp_body(slots);
|
|
return 0;
|
|
}
|
|
|
|
el_val_t generate_tree(el_val_t rule_id_str, el_val_t slots) {
|
|
el_val_t rule = find_rule(rule_id_str);
|
|
el_val_t n = native_list_len(rule);
|
|
if (n == 0) {
|
|
return make_leaf(EL_STR("ERR"), EL_STR("unknown-rule"));
|
|
}
|
|
el_val_t lhs = native_list_get(rule, 1);
|
|
if (str_eq(rule_id_str, EL_STR("S-DECL"))) {
|
|
el_val_t agent = slots_get(slots, EL_STR("agent"));
|
|
el_val_t np_tree = build_np(agent, slots);
|
|
el_val_t vp_tree = build_vp_from_slots(slots);
|
|
return make_node2(EL_STR("S"), np_tree, vp_tree);
|
|
}
|
|
if (str_eq(rule_id_str, EL_STR("S-QUEST"))) {
|
|
el_val_t agent = slots_get(slots, EL_STR("agent"));
|
|
el_val_t np_tree = build_np(agent, slots);
|
|
el_val_t vp_tree = build_vp_body(slots);
|
|
el_val_t aux_surf = slots_get(slots, EL_STR("aux_surf"));
|
|
return make_node3(EL_STR("S"), make_leaf(EL_STR("Aux"), aux_surf), np_tree, vp_tree);
|
|
}
|
|
if (str_eq(rule_id_str, EL_STR("S-IMP"))) {
|
|
el_val_t vp_tree = build_vp_from_slots(slots);
|
|
return make_node1(EL_STR("S"), vp_tree);
|
|
}
|
|
return make_leaf(lhs, EL_STR("?"));
|
|
return 0;
|
|
}
|
|
|