home *** CD-ROM | disk | FTP | other *** search
- #include "demo7.h"
-
- /*
-
- First we make some simple DCG-like rules and a small lexicon and store
- this information in two arrays, rules[] and lexicon[], using function
- init().
- */
-
- ITEM_ *init(int number, ITEM_ start, ...)
- {
- ITEM_
- *tmp;
-
- if (!(tmp = (ITEM_ *) malloc(number * sizeof(ITEM_))))
- {
- puts("Error: out of memory data");
- exit(0);
- }
- memcpy(tmp, &start, number * sizeof(ITEM_));
- return(tmp);
- }
-
- RULE_
- rules[] = {
- {2, S, init(2, NP, VP)},
- {1, NP, init(1, SNP)},
- {2, NP, init(2, DET, N)},
- {1, VP, init(1, IV)},
- {2, VP, init(2, TV, NP)},
- {3, VP, init(3, SV, CN, S)},
- {VOID, VOID, NULL}
- };
-
- LEX_
- lexicon[] = {
- {TV, "kills"},
- {SV, "thinks"},
- {IV, "sleeps"},
- {SNP, "john"},
- {N, "man"},
- {DET, "the"},
- {CN, "that"},
- {VOID, NULL}
- };
-
- char /* to print syntactic categories */
- *table[] = {"void" , "s", "vp", "iv", "tv", "sv", "np", "snp",
- "n", "det", "cn"};
-
-
-
- PARSE_::PARSE_(char **s, ELEMENT_ *start)
- : AODEPTH_TREE_(start, 0)
- {
- string = s;
- index = 0;
- }
-
-
- ELEMENT_::ELEMENT_(ITEM_ it)
- {
- item = it;
- }
-
-
- void ELEMENT_::display() const
- {
- printf("%s\n", table[item]);
- }
-
-
- /* EQUAL
-
- We don't really need this function in this class because we are
- performing a tree search, so we can be sure none of the nodes will
- be generated twice; also, nodes won't be compared against a goal
- node. Still, we must define this function because it's pure
- virtual in NODE_.
-
- */
-
- int ELEMENT_::equal(const VOBJECT_ &) const
- {
- return(0);
- }
-
-
- ITEM_ ELEMENT_::get_item() const
- {
- return(item);
- }
-
-
- /* EXPAND
-
- Expanding a node means in this problem that we must find the syntactic
- category that the node represents in the database of rules. Since a rule
- may rewrite the syntactic category to more than one new category we may
- have to, and most of the time will, produce an AND-node.
-
- */
-
- NODE_ *ELEMENT_::expand(int ) const
- {
- AONODE_
- *tmp = NULL,
- *start = NULL;
- int
- i,
- d;
-
- for (i = 0; rules[i].num != VOID; i++) // find item in rules database
- {
- if (rules[i].head == item)
- {
- if (rules[i].num == 1) // create OR node
- tmp = new ELEMENT_(rules[i].tail[0]);
- else
- {
- tmp = new ANDNODE_(); // create AND node
- /* remember that our terminology of AND and OR nodes differs
- from normal usage */
- for (d = 0; d < rules[i].num; d++)
- ((ANDNODE_ *)tmp)->addsucc(new ELEMENT_(rules[i].tail[d]));
- }
-
- tmp->setnext(start);
- start = tmp;
- }
- }
- return(start);
- }
-
-
- /* IS_TERMINAL
-
- To determine if a node may be considered terminal we check if the
- syntactic item to be parsed, which must of course be terminal itself,
- matches the word (pointed to by index) in the input string. Therefore,
- we first locate the syntactic category in the lexicon (if we can't find it
- there this means the syntactic category isn't terminal) and compare the
- word that accompanies it with the word in the input string.
-
- */
-
- int PARSE_::is_terminal(const AONODE_ &node)
- {
- int
- i;
-
- if (!string[index])
- return(0);
-
- for (i = 0; lexicon[i].head != VOID; i++)
- if (lexicon[i].head == ((ELEMENT_ &)node).get_item()
- && !strcmp(lexicon[i].tail, string[index]))
- {
- index++;
- return(1);
- }
-
- return(0);
- }
-
-
- int main(int argc, char *argv[])
- {
- if (argc == 1)
- {
- printf("Usage: %s <string>\n", argv[0]);
- exit(0);
- }
- PARSE_
- sentence(++argv, new ELEMENT_(S));
-
- sentence.generate();
- return(1);
- }
-