mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
311 lines
12 KiB
OpenEdge ABL
311 lines
12 KiB
OpenEdge ABL
[Diagrams::] Diagrams.
|
|
|
|
To specify standard verb-phrase nodes in the parse tree.
|
|
|
|
@ This section lays out a sort of specification for what we ultimately want
|
|
to turn sentences into: i.e., little sentence diagrams made up of parse nodes.
|
|
We do that with the aid of the //syntax// module. So we must first set up
|
|
some new node types:
|
|
|
|
@e L3_NCAT
|
|
@e VERB_NT /* "is" */
|
|
@e UNPARSED_NOUN_NT /* "arfle barfle gloop" */
|
|
@e PRONOUN_NT /* "them" */
|
|
@e DEFECTIVE_NOUN_NT /* "there" */
|
|
@e COMMON_NOUN_NT /* "a container" */
|
|
@e PROPER_NOUN_NT /* "the red handkerchief" */
|
|
@e RELATIONSHIP_NT /* "on" */
|
|
@e CALLED_NT /* "On the table is a container called the box" */
|
|
@e WITH_NT /* "The footstool is a supporter with capacity 2" */
|
|
@e AND_NT /* "whisky and soda" */
|
|
@e KIND_NT /* "A woman is a kind of person" */
|
|
@e PROPERTY_LIST_NT /* "capacity 2" */
|
|
@e X_OF_Y_NT /* "description of the painting" */
|
|
|
|
@ These nodes are annotated with the following:
|
|
|
|
@e verbal_certainty_ANNOT /* |int|: certainty level if known */
|
|
@e sentence_is_existential_ANNOT /* |int|: such as "there is a man" */
|
|
@e linguistic_error_here_ANNOT /* |int|: one of the errors occurred here */
|
|
@e verb_ANNOT /* |verb_usage|: what's being done here */
|
|
@e noun_ANNOT /* |noun_usage|: what's being done here */
|
|
@e article_ANNOT /* |article_usage|: what's being done here */
|
|
@e pronoun_ANNOT /* |pronoun_usage|: what's being done here */
|
|
@e preposition_ANNOT /* |preposition|: which preposition, if any, qualifies it */
|
|
@e second_preposition_ANNOT /* |preposition|: which further preposition, if any, qualifies it */
|
|
@e special_meaning_ANNOT /* |special_meaning_holder|: to give a verb a non-standard meaning */
|
|
@e occurrence_ANNOT /* |time_period|: any stipulation on occurrence */
|
|
@e relationship_ANNOT /* |binary_predicate|: for RELATIONSHIP nodes */
|
|
|
|
=
|
|
DECLARE_ANNOTATION_FUNCTIONS(verb, verb_usage)
|
|
DECLARE_ANNOTATION_FUNCTIONS(noun, noun_usage)
|
|
DECLARE_ANNOTATION_FUNCTIONS(pronoun, pronoun_usage)
|
|
DECLARE_ANNOTATION_FUNCTIONS(article, article_usage)
|
|
DECLARE_ANNOTATION_FUNCTIONS(preposition, preposition)
|
|
DECLARE_ANNOTATION_FUNCTIONS(second_preposition, preposition)
|
|
DECLARE_ANNOTATION_FUNCTIONS(special_meaning, special_meaning_holder)
|
|
DECLARE_ANNOTATION_FUNCTIONS(occurrence, time_period)
|
|
|
|
MAKE_ANNOTATION_FUNCTIONS(verb, verb_usage)
|
|
MAKE_ANNOTATION_FUNCTIONS(noun, noun_usage)
|
|
MAKE_ANNOTATION_FUNCTIONS(pronoun, pronoun_usage)
|
|
MAKE_ANNOTATION_FUNCTIONS(article, article_usage)
|
|
MAKE_ANNOTATION_FUNCTIONS(preposition, preposition)
|
|
MAKE_ANNOTATION_FUNCTIONS(second_preposition, preposition)
|
|
MAKE_ANNOTATION_FUNCTIONS(special_meaning, special_meaning_holder)
|
|
MAKE_ANNOTATION_FUNCTIONS(occurrence, time_period)
|
|
|
|
@ =
|
|
void Diagrams::declare_annotations(void) {
|
|
Annotations::declare_type(verbal_certainty_ANNOT,
|
|
Diagrams::write_verbal_certainty_ANNOT);
|
|
Annotations::declare_type(sentence_is_existential_ANNOT,
|
|
Diagrams::write_sentence_is_existential_ANNOT);
|
|
Annotations::declare_type(linguistic_error_here_ANNOT,
|
|
Diagrams::write_linguistic_error_here_ANNOT);
|
|
Annotations::declare_type(verb_ANNOT,
|
|
Diagrams::write_verb_ANNOT);
|
|
Annotations::declare_type(noun_ANNOT,
|
|
Diagrams::write_noun_ANNOT);
|
|
Annotations::declare_type(article_ANNOT,
|
|
Diagrams::write_article_ANNOT);
|
|
Annotations::declare_type(pronoun_ANNOT,
|
|
Diagrams::write_pronoun_ANNOT);
|
|
Annotations::declare_type(preposition_ANNOT,
|
|
Diagrams::write_preposition_ANNOT);
|
|
Annotations::declare_type(second_preposition_ANNOT,
|
|
Diagrams::write_second_preposition_ANNOT);
|
|
Annotations::declare_type(special_meaning_ANNOT,
|
|
Diagrams::write_special_meaning_ANNOT);
|
|
Annotations::declare_type(occurrence_ANNOT,
|
|
Diagrams::write_occurrence_ANNOT);
|
|
Annotations::declare_type(relationship_ANNOT,
|
|
Diagrams::write_relationship_ANNOT);
|
|
}
|
|
void Diagrams::write_verbal_certainty_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Annotations::read_int(p, verbal_certainty_ANNOT) != UNKNOWN_CE) {
|
|
WRITE(" {certainty:");
|
|
Certainty::write(OUT, Annotations::read_int(p, verbal_certainty_ANNOT));
|
|
WRITE("}");
|
|
}
|
|
}
|
|
void Diagrams::write_sentence_is_existential_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Annotations::read_int(p, sentence_is_existential_ANNOT))
|
|
WRITE(" {existential}");
|
|
}
|
|
void Diagrams::write_linguistic_error_here_ANNOT(text_stream *OUT, parse_node *p) {
|
|
WRITE(" {error: ");
|
|
switch (Annotations::read_int(p, linguistic_error_here_ANNOT)) {
|
|
case TwoLikelihoods_LINERROR: WRITE(" two likelihoods"); break;
|
|
default: WRITE("unknown"); break;
|
|
}
|
|
WRITE("}");
|
|
}
|
|
void Diagrams::write_verb_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_verb(p))
|
|
VerbUsages::write_usage(OUT, Node::get_verb(p));
|
|
}
|
|
void Diagrams::write_noun_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_noun(p))
|
|
Nouns::write_usage(OUT, Node::get_noun(p));
|
|
}
|
|
void Diagrams::write_article_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_article(p))
|
|
Articles::write_usage(OUT, Node::get_article(p));
|
|
}
|
|
void Diagrams::write_pronoun_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_pronoun(p))
|
|
Pronouns::write_usage(OUT, Node::get_pronoun(p));
|
|
}
|
|
void Diagrams::write_preposition_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_preposition(p)) {
|
|
WRITE(" {prep1: ");
|
|
Prepositions::log(OUT, Node::get_preposition(p));
|
|
WRITE("}");
|
|
}
|
|
}
|
|
void Diagrams::write_second_preposition_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_second_preposition(p)) {
|
|
WRITE(" {prep2: ");
|
|
Prepositions::log(OUT, Node::get_second_preposition(p));
|
|
WRITE("}");
|
|
}
|
|
}
|
|
void Diagrams::write_special_meaning_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_special_meaning(p))
|
|
WRITE(" {special meaning: %S}",
|
|
SpecialMeanings::get_name(Node::get_special_meaning(p)));
|
|
}
|
|
void Diagrams::write_occurrence_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_occurrence(p)) {
|
|
WRITE(" {occurrence: ");
|
|
Occurrence::log(OUT, Node::get_occurrence(p));
|
|
WRITE("}");
|
|
}
|
|
}
|
|
void Diagrams::write_relationship_ANNOT(text_stream *OUT, parse_node *p) {
|
|
if (Node::get_relationship(p))
|
|
WRITE(" {meaning: %S}", Node::get_relationship(p)->debugging_log_name);
|
|
}
|
|
|
|
@ The |linguistic_error_here_ANNOT| annotation is for any errors we find:
|
|
|
|
@e TwoLikelihoods_LINERROR from 1
|
|
|
|
@ Two callbacks are needed so that the //syntax// module will create the above
|
|
nodes and annotations correctly:
|
|
|
|
@d EVEN_MORE_NODE_METADATA_SETUP_SYNTAX_CALLBACK Diagrams::setup
|
|
@d EVEN_MORE_PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK Diagrams::parentage_permission
|
|
@d EVEN_MORE_ANNOTATION_PERMISSIONS_SYNTAX_CALLBACK Diagrams::permissions
|
|
|
|
=
|
|
void Diagrams::setup(void) {
|
|
NodeType::new(VERB_NT, I"VERB_NT", 0, 0, L3_NCAT, 0);
|
|
NodeType::new(RELATIONSHIP_NT, I"RELATIONSHIP_NT", 0, 2, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(CALLED_NT, I"CALLED_NT", 2, 2, L3_NCAT, 0);
|
|
NodeType::new(WITH_NT, I"WITH_NT", 2, 2, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(AND_NT, I"AND_NT", 2, 2, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(KIND_NT, I"KIND_NT", 0, 1, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(UNPARSED_NOUN_NT, I"UNPARSED_NOUN_NT", 0, 0, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(PRONOUN_NT, I"PRONOUN_NT", 0, 0, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(DEFECTIVE_NOUN_NT, I"DEFECTIVE_NOUN_NT", 0, 0, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(PROPER_NOUN_NT, I"PROPER_NOUN_NT", 0, 0, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(COMMON_NOUN_NT, I"COMMON_NOUN_NT", 0, INFTY, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(PROPERTY_LIST_NT, I"PROPERTY_LIST_NT", 0, INFTY, L3_NCAT, ASSERT_NFLAG);
|
|
NodeType::new(X_OF_Y_NT, I"X_OF_Y_NT", 2, 2, L3_NCAT, ASSERT_NFLAG);
|
|
}
|
|
|
|
void Diagrams::parentage_permission(void) {
|
|
NodeType::allow_parentage_for_categories(L2_NCAT, L3_NCAT);
|
|
NodeType::allow_parentage_for_categories(L3_NCAT, L3_NCAT);
|
|
}
|
|
|
|
void Diagrams::permissions(void) {
|
|
Annotations::allow(VERB_NT, verbal_certainty_ANNOT);
|
|
Annotations::allow(VERB_NT, sentence_is_existential_ANNOT);
|
|
Annotations::allow(VERB_NT, verb_ANNOT);
|
|
Annotations::allow(VERB_NT, preposition_ANNOT);
|
|
Annotations::allow(VERB_NT, second_preposition_ANNOT);
|
|
Annotations::allow(VERB_NT, special_meaning_ANNOT);
|
|
Annotations::allow(VERB_NT, occurrence_ANNOT);
|
|
Annotations::allow(UNPARSED_NOUN_NT, noun_ANNOT);
|
|
Annotations::allow(PRONOUN_NT, pronoun_ANNOT);
|
|
Annotations::allow(PROPER_NOUN_NT, noun_ANNOT);
|
|
Annotations::allow(COMMON_NOUN_NT, noun_ANNOT);
|
|
Annotations::allow(RELATIONSHIP_NT, preposition_ANNOT);
|
|
Annotations::allow(RELATIONSHIP_NT, relationship_ANNOT);
|
|
Annotations::allow_for_category(L3_NCAT, linguistic_error_here_ANNOT);
|
|
Annotations::allow_for_category(L3_NCAT, article_ANNOT);
|
|
}
|
|
|
|
@h Creation.
|
|
The following functions create leaves, or very minor twigs, used in sentence
|
|
diagrams.
|
|
|
|
=
|
|
parse_node *Diagrams::new_arity0(node_type_t t, wording W) {
|
|
parse_node *P = Node::new(t);
|
|
Node::set_text(P, W);
|
|
return P;
|
|
}
|
|
|
|
parse_node *Diagrams::new_arity1(node_type_t t, wording W, parse_node *A) {
|
|
parse_node *P = Node::new(t);
|
|
Node::set_text(P, W);
|
|
if (A == NULL) internal_error("no child of arity-1 node");
|
|
P->down = A;
|
|
return P;
|
|
}
|
|
|
|
parse_node *Diagrams::new_arity2(node_type_t t, wording W, parse_node *A, parse_node *B) {
|
|
parse_node *P = Node::new(t);
|
|
Node::set_text(P, W);
|
|
if (A == NULL) internal_error("no first child of arity-2 node");
|
|
if (B == NULL) internal_error("no second child of arity-2 node");
|
|
P->down = A; P->down->next = B;
|
|
return P;
|
|
}
|
|
|
|
@ And those are then used to make the following.
|
|
|
|
Note that if the variable |preform_lookahead_mode| is set, then all these
|
|
functions return |NULL|: this optimisation prevents us from creating millions
|
|
of useless nodes when all that's happening is that the sentence parser is
|
|
looking ahead speculatively.[1]
|
|
|
|
[1] At one time Inform used garbage collection to reclaim discarded nodes
|
|
instead, but it turned out to be more efficient not to make garbage in the
|
|
first place: a lesson there for all of us.
|
|
|
|
=
|
|
parse_node *Diagrams::new_UNPARSED_NOUN(wording W) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
return Diagrams::new_arity0(UNPARSED_NOUN_NT, W);
|
|
}
|
|
|
|
parse_node *Diagrams::new_DEFECTIVE(wording W) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
return Diagrams::new_arity0(DEFECTIVE_NOUN_NT, W);
|
|
}
|
|
|
|
parse_node *Diagrams::new_PROPER_NOUN(wording W) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
return Diagrams::new_arity0(PROPER_NOUN_NT, W);
|
|
}
|
|
|
|
parse_node *Diagrams::new_PROPERTY_LIST(wording W) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
return Diagrams::new_arity0(PROPERTY_LIST_NT, W);
|
|
}
|
|
|
|
parse_node *Diagrams::new_PRONOUN(wording W, pronoun_usage *pro) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
parse_node *PN = Diagrams::new_arity0(PRONOUN_NT, W);
|
|
Node::set_pronoun(PN, pro);
|
|
return PN;
|
|
}
|
|
|
|
parse_node *Diagrams::new_KIND(wording W, parse_node *O) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
if (O == NULL) return Diagrams::new_arity0(KIND_NT, W);
|
|
return Diagrams::new_arity1(KIND_NT, W, O);
|
|
}
|
|
|
|
parse_node *Diagrams::new_RELATIONSHIP(wording W, VERB_MEANING_LINGUISTICS_TYPE *R,
|
|
parse_node *O) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
parse_node *P = Diagrams::new_arity1(RELATIONSHIP_NT, W, O);
|
|
Node::set_relationship(P, R);
|
|
return P;
|
|
}
|
|
|
|
int Diagrams::is_possessive_RELATIONSHIP(parse_node *py) {
|
|
if ((py) && (Node::get_type(py) == RELATIONSHIP_NT) &&
|
|
(Node::get_relationship(py)) &&
|
|
(VerbMeanings::reverse_VMT(Node::get_relationship(py)) == VERB_MEANING_POSSESSION))
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
parse_node *Diagrams::new_implied_RELATIONSHIP(wording W, VERB_MEANING_LINGUISTICS_TYPE *R) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
return Diagrams::new_RELATIONSHIP(W, R, Diagrams::new_PRONOUN(W, Pronouns::get_implied()));
|
|
}
|
|
|
|
parse_node *Diagrams::new_AND(int wn, parse_node *X, parse_node *Y) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
return Diagrams::new_arity2(AND_NT, Wordings::one_word(wn), X, Y);
|
|
}
|
|
|
|
parse_node *Diagrams::new_WITH(int wn, parse_node *X, parse_node *Y) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
return Diagrams::new_arity2(WITH_NT, Wordings::one_word(wn), X, Y);
|
|
}
|
|
|
|
parse_node *Diagrams::new_CALLED(wording W, parse_node *X, parse_node *Y) {
|
|
if (preform_lookahead_mode) return NULL;
|
|
return Diagrams::new_arity2(CALLED_NT, W, X, Y);
|
|
}
|