summaryrefslogtreecommitdiffstats
path: root/battlestar/parse.c
diff options
context:
space:
mode:
authorjsm <jsm@NetBSD.org>2000-09-21 17:44:34 +0000
committerjsm <jsm@NetBSD.org>2000-09-21 17:44:34 +0000
commit0ba05dd5a679e7723ea4b9f1426175b1651926cf (patch)
tree8beede32304395cb7418af5573f1e3b042030ca8 /battlestar/parse.c
parent66bc28438e19fafc7abecfa76bce72d10174c9be (diff)
downloadbsdgames-darwin-0ba05dd5a679e7723ea4b9f1426175b1651926cf.tar.gz
bsdgames-darwin-0ba05dd5a679e7723ea4b9f1426175b1651926cf.tar.zst
bsdgames-darwin-0ba05dd5a679e7723ea4b9f1426175b1651926cf.zip
Various improvements to parsing in battlestar, mostly from OpenBSD.
Define a constant WORDLEN. Always use this constant and NWORD where appropriate. Use NWORD - 1 in battlestar.c to avoid off-by-one error. Increment wordnumber after the INVEN verb to allow it to be followed by a comma and other actions. Avoid overflowing elements of the words array if input words are too long. Parse "," as AND except when followed by a verb, to allow such constructions as "take foo, bar, and baz". Trim AND AND which may occur from the ", and" in such a list. Avoid crashes from EVERYTHING in the wrong place by moving it to the start of OBJECT AND EVERYTHING and NOUNS AND EVERYTHING sequences, and trimming EVERYTHING AND EVERYTHING.
Diffstat (limited to 'battlestar/parse.c')
-rw-r--r--battlestar/parse.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/battlestar/parse.c b/battlestar/parse.c
index 8d85e6c5..e79722ba 100644
--- a/battlestar/parse.c
+++ b/battlestar/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.7 1999/02/10 01:36:50 hubertf Exp $ */
+/* $NetBSD: parse.c,v 1.8 2000/09/21 17:44:34 jsm Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)parse.c 8.2 (Berkeley) 4/28/95";
#else
-__RCSID("$NetBSD: parse.c,v 1.7 1999/02/10 01:36:50 hubertf Exp $");
+__RCSID("$NetBSD: parse.c,v 1.8 2000/09/21 17:44:34 jsm Exp $");
#endif
#endif /* not lint */
@@ -98,6 +98,7 @@ parse()
{
struct wlist *wp;
int n;
+ int flag;
wordnumber = 0; /* for cypher */
for (n = 0; n <= wordcount; n++) {
@@ -109,4 +110,61 @@ parse()
wordtype[n] = wp->article;
}
}
+ /* Don't let a comma mean AND if followed by a verb. */
+ for (n = 0; n < wordcount; n++)
+ if (wordvalue[n] == AND && words[n][0] == ','
+ && wordtype[n + 1] == VERB) {
+ wordvalue[n] = -1;
+ wordtype[n] = -1;
+ }
+ /* Trim "AND AND" which can happen naturally at the end of a
+ * comma-delimited list.
+ */
+ for (n = 1; n < wordcount; n++)
+ if (wordvalue[n - 1] == AND && wordvalue[n] == AND) {
+ int i;
+ for (i = n + 1; i < wordcount; i++) {
+ wordtype[i - 1] = wordtype[i];
+ wordvalue[i - 1] = wordvalue[i];
+ strcpy(words[i - 1], words[i]);
+ }
+ wordcount--;
+ }
+
+ /* If there is a sequence (NOUN | OBJECT) AND EVERYTHING
+ * then move all the EVERYTHINGs to the beginning, since that's where
+ * they're expected. We can't get rid of the NOUNs and OBJECTs in
+ * case they aren't in EVERYTHING (i.e. not here or nonexistant).
+ */
+ flag = 1;
+ while (flag) {
+ flag = 0;
+ for (n = 1; n < wordcount; n++)
+ if ((wordtype[n - 1] == NOUNS || wordtype[n - 1] == OBJECT) &&
+ wordvalue[n] == AND && wordvalue[n + 1] == EVERYTHING) {
+ char tmpword[WORDLEN];
+ wordvalue[n + 1] = wordvalue[n - 1];
+ wordvalue[n - 1] = EVERYTHING;
+ wordtype[n + 1] = wordtype[n - 1];
+ wordtype[n - 1] = OBJECT;
+ strcpy(tmpword, words[n - 1]);
+ strcpy(words[n - 1], words[n + 1]);
+ strcpy(words[n + 1], tmpword);
+ flag = 1;
+ }
+ /* And trim EVERYTHING AND EVERYTHING. */
+ for (n = 1; n < wordcount; n++)
+ if (wordvalue[n - 1] == EVERYTHING &&
+ wordvalue[n] == AND && wordvalue[n + 1] == EVERYTHING) {
+ int i;
+ for (i = n + 1; i < wordcount; i++) {
+ wordtype[i - 1] = wordtype[i + 1];
+ wordvalue[i - 1] = wordvalue[i + 1];
+ strcpy(words[i - 1], words[i + 1]);
+ }
+ wordcount--;
+ wordcount--;
+ flag = 1;
+ }
+ }
}