diff options
author | jsm <jsm@NetBSD.org> | 2000-09-21 17:44:34 +0000 |
---|---|---|
committer | jsm <jsm@NetBSD.org> | 2000-09-21 17:44:34 +0000 |
commit | 0ba05dd5a679e7723ea4b9f1426175b1651926cf (patch) | |
tree | 8beede32304395cb7418af5573f1e3b042030ca8 /battlestar/parse.c | |
parent | 66bc28438e19fafc7abecfa76bce72d10174c9be (diff) | |
download | bsdgames-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.c | 62 |
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; + } + } } |