1 /* @(#)parse.c 8.2 (Berkeley) 4/28/95 */
2 /* $NetBSD: parse.c,v 1.17 2020/02/06 22:09:43 fox Exp $ */
5 * Copyright (c) 1983, 1993
6 * The Regents of the University of California. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #define HASHMASK (HASHSIZE - 1)
39 static int hash(const char *);
40 static void install(struct wlist
*);
41 static struct wlist
*lookup(const char *);
43 static struct wlist
*hashtab
[HASHSIZE
];
50 for (w
= wlist
; w
->string
; w
++)
72 for (wp
= hashtab
[hash(s
)]; wp
!= NULL
; wp
= wp
->next
)
73 if (*s
== *wp
->string
&& strcmp(s
, wp
->string
) == 0)
79 install(struct wlist
*wp
)
83 if (lookup(wp
->string
) == NULL
) {
84 hashval
= hash(wp
->string
);
85 wp
->next
= hashtab
[hashval
];
86 hashtab
[hashval
] = wp
;
88 printf("Multiply defined %s.\n", wp
->string
);
98 wordnumber
= 0; /* for cypher */
99 for (n
= 0; n
<= wordcount
; n
++) {
100 if ((wp
= lookup(words
[n
])) == NULL
) {
104 wordvalue
[n
] = wp
->value
;
105 wordtype
[n
] = wp
->article
;
108 /* We never use adjectives for anything, so yank them all. */
109 for (n
= 1; n
< wordcount
; n
++)
110 if (wordtype
[n
] == ADJS
) {
112 for (i
= n
+ 1; i
< wordcount
; i
++) {
113 wordtype
[i
- 1] = wordtype
[i
];
114 wordvalue
[i
- 1] = wordvalue
[i
];
115 strlcpy(words
[i
- 1], words
[i
], WORDLEN
);
119 /* Don't let a comma mean AND if followed by a verb. */
120 for (n
= 0; n
< wordcount
; n
++)
121 if (wordvalue
[n
] == AND
&& words
[n
][0] == ','
122 && wordtype
[n
+ 1] == VERB
) {
126 /* Trim "AND AND" which can happen naturally at the end of a
127 * comma-delimited list.
129 for (n
= 1; n
< wordcount
; n
++)
130 if (wordvalue
[n
- 1] == AND
&& wordvalue
[n
] == AND
) {
132 for (i
= n
+ 1; i
< wordcount
; i
++) {
133 wordtype
[i
- 1] = wordtype
[i
];
134 wordvalue
[i
- 1] = wordvalue
[i
];
135 strlcpy(words
[i
- 1], words
[i
], WORDLEN
);
140 /* If there is a sequence (NOUN | OBJECT) AND EVERYTHING
141 * then move all the EVERYTHINGs to the beginning, since that's where
142 * they're expected. We can't get rid of the NOUNs and OBJECTs in
143 * case they aren't in EVERYTHING (i.e. not here or nonexistent).
148 for (n
= 1; n
< wordcount
; n
++)
149 if ((wordtype
[n
- 1] == NOUNS
||
150 wordtype
[n
- 1] == OBJECT
) &&
151 wordvalue
[n
] == AND
&&
152 wordvalue
[n
+ 1] == EVERYTHING
) {
153 char tmpword
[WORDLEN
];
154 wordvalue
[n
+ 1] = wordvalue
[n
- 1];
155 wordvalue
[n
- 1] = EVERYTHING
;
156 wordtype
[n
+ 1] = wordtype
[n
- 1];
157 wordtype
[n
- 1] = OBJECT
;
158 strcpy(tmpword
, words
[n
- 1]);
159 strlcpy(words
[n
- 1], words
[n
+ 1], WORDLEN
);
160 strcpy(words
[n
+ 1], tmpword
);
163 /* And trim EVERYTHING AND EVERYTHING. */
164 for (n
= 1; n
< wordcount
; n
++)
165 if (wordvalue
[n
- 1] == EVERYTHING
&&
166 wordvalue
[n
] == AND
&&
167 wordvalue
[n
+ 1] == EVERYTHING
) {
169 for (i
= n
+ 1; i
< wordcount
; i
++) {
170 wordtype
[i
- 1] = wordtype
[i
+ 1];
171 wordvalue
[i
- 1] = wordvalue
[i
+ 1];
172 strlcpy(words
[i
- 1], words
[i
+ 1], WORDLEN
);