3 This is a version of the famous CS 107 random sentence
4 generator. I wrote a program that reads a grammar definition
5 file and writes a C file containing that grammar as hard code
6 static C strings. Thus the majority of the code below in
7 machine generated and totally unreadable. The arrays created
8 are specially designed to make generating the sentences as
11 Originally by Greg Hutchins, March 1998.
12 Modified by Ben Pfaff for Pintos, Sept 2004. */
14 { "You", "1", "5", ".", "May", "13", ".", "With", "the", "19", "of", "18",
17 char startLoc[] = { 3, 0, 4, 7, 16 };
18 char *adj[] = { "3", "4", "2", ",", "1" };
19 char adjLoc[] = { 3, 0, 1, 2, 5 };
20 char *adj3[] = { "3", "4" };
21 char adj3Loc[] = { 2, 0, 1, 2 };
23 { "lame", "dried", "up", "par-broiled", "bloated", "half-baked", "spiteful",
24 "egotistical", "ungrateful", "stupid", "moronic", "fat", "ugly", "puny", "pitiful",
25 "insignificant", "blithering", "repulsive", "worthless", "blundering", "retarded",
26 "useless", "obnoxious", "low-budget", "assinine", "neurotic", "subhuman", "crochety",
27 "indescribable", "contemptible", "unspeakable", "sick", "lazy", "good-for-nothing",
28 "slutty", "mentally-deficient", "creepy", "sloppy", "dismal", "pompous", "pathetic",
29 "friendless", "revolting", "slovenly", "cantankerous", "uncultured", "insufferable",
30 "gross", "unkempt", "defective", "crumby"
33 { 50, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
34 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
35 43, 44, 45, 46, 47, 48, 49, 50, 51 };
37 { "putrefied", "festering", "funky", "moldy", "leprous", "curdled", "fetid",
38 "slimy", "crusty", "sweaty", "damp", "deranged", "smelly", "stenchy", "malignant",
39 "noxious", "grimy", "reeky", "nasty", "mutilated", "sloppy", "gruesome", "grisly",
40 "sloshy", "wormy", "mealy", "spoiled", "contaminated", "rancid", "musty",
41 "fly-covered", "moth-eaten", "decaying", "decomposed", "freeze-dried", "defective",
42 "petrified", "rotting", "scabrous", "hirsute"
45 { 40, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
46 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };
48 { "10", ",", "bad", "excuse", "for", "6", ",", "6", "for", "brains", ",",
49 "4", "11", "8", "for", "brains", "offspring", "of", "a", "motherless", "10", "7", "6",
52 char nameLoc[] = { 7, 0, 1, 6, 10, 16, 21, 23, 27 };
54 { "shit", "toe", "jam", "filth", "puss", "earwax", "leaf", "clippings",
55 "bat", "guano", "mucus", "fungus", "mung", "refuse", "earwax", "spittoon", "spittle",
58 char stuffLoc[] = { 14, 0, 1, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14, 15, 17, 18 };
59 char *noun_and_prep[] =
60 { "bit", "of", "piece", "of", "vat", "of", "lump", "of", "crock", "of",
61 "ball", "of", "tub", "of", "load", "of", "bucket", "of", "mound", "of", "glob", "of", "bag",
62 "of", "heap", "of", "mountain", "of", "load", "of", "barrel", "of", "sack", "of", "blob", "of",
63 "pile", "of", "truckload", "of", "vat", "of"
65 char noun_and_prepLoc[] =
66 { 21, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
69 { "droppings", "mung", "zits", "puckies", "tumors", "cysts", "tumors",
70 "livers", "froth", "parts", "scabs", "guts", "entrails", "blubber", "carcuses", "gizards",
74 { 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
76 { "kidneys", "genitals", "buttocks", "earlobes", "innards", "feet"
78 char body_partsLoc[] = { 6, 0, 1, 2, 3, 4, 5, 6 };
80 { "pop", "tart", "warthog", "twinkie", "barnacle", "fondue", "pot",
81 "cretin", "fuckwad", "moron", "ass", "neanderthal", "nincompoop", "simpleton", "11"
83 char nounLoc[] = { 13, 0, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
85 { "donkey", "llama", "dingo", "lizard", "gekko", "lemur", "moose", "camel",
88 char animalLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
90 { "love", "cuddle", "fondle", "adore", "smooch", "hug", "caress", "worship",
93 char good_verbLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11 };
95 { "14", "20", "23", "14", "17", "20", "23", "14", "find", "your", "9",
96 "suddenly", "delectable", "14", "and", "14", "seek", "a", "battleground", "23"
98 char curseLoc[] = { 4, 0, 3, 7, 13, 20 };
100 { "15", "21", "15", "21", "15", "21", "15", "21", "a", "22", "Rush",
101 "Limbaugh", "the", "hosts", "of", "Hades"
103 char afflictorsLoc[] = { 6, 0, 2, 4, 6, 8, 12, 16 };
105 { "a", "4", "hoard", "of", "a", "4", "pack", "of", "a", "truckload", "of",
106 "a", "swarm", "of", "many", "an", "army", "of", "a", "4", "heard", "of", "a", "4",
107 "platoon", "of", "a", "4", "and", "4", "group", "of", "16"
109 char quantityLoc[] = { 10, 0, 4, 8, 11, 14, 15, 18, 22, 26, 32, 33 };
111 { "a", "thousand", "three", "million", "ninty-nine", "nine-hundred,",
112 "ninty-nine", "forty-two", "a", "gazillion", "sixty-eight", "times", "thirty-three"
114 char numbersLoc[] = { 7, 0, 2, 4, 5, 7, 8, 10, 13 };
116 { "viciously", "manicly", "merrily", "happily", ",", "with", "the", "19",
117 "of", "18", ",", "gleefully", ",", "with", "much", "ritualistic", "celebration", ",",
120 char advLoc[] = { 8, 0, 1, 2, 3, 4, 11, 12, 18, 19 };
122 { "an", "irate", "manticore", "Thor's", "belch", "Alah's", "fist", "16",
123 "titans", "a", "particularly", "vicious", "she-bear", "in", "the", "midst", "of", "her",
124 "menstrual", "cycle", "a", "pissed-off", "Jabberwock"
126 char metaphorLoc[] = { 6, 0, 3, 5, 7, 9, 20, 23 };
127 char *force[] = { "force", "fury", "power", "rage" };
128 char forceLoc[] = { 4, 0, 1, 2, 3, 4 };
130 { "spit", "shimmy", "slobber", "find", "refuge", "find", "shelter", "dance",
131 "retch", "vomit", "defecate", "erect", "a", "strip", "mall", "build", "a", "26", "have", "a",
132 "religious", "experience", "discharge", "bodily", "waste", "fart", "dance", "drool",
133 "lambada", "spill", "16", "rusty", "tacks", "bite", "you", "sneeze", "sing", "16",
134 "campfire", "songs", "smite", "you", "16", "times", "construct", "a", "new", "home", "throw",
135 "a", "party", "procreate"
137 char bad_actionLoc[] =
138 { 25, 0, 1, 2, 3, 5, 7, 8, 9, 10, 11, 15, 18, 22, 25, 26, 27, 28, 29, 33,
139 35, 36, 40, 44, 48, 51, 52 };
141 { "yaks", "22", "maggots", "22", "cockroaches", "stinging", "scorpions",
142 "fleas", "22", "weasels", "22", "gnats", "South", "American", "killer", "bees", "spiders",
143 "4", "monkeys", "22", "wiener-dogs", "22", "rats", "22", "wolverines", "4", ",", "22",
147 { 14, 0, 1, 3, 5, 7, 8, 10, 12, 16, 17, 19, 21, 23, 25, 29 };
149 { "frothing", "manic", "crazed", "plague-ridden", "disease-carrying",
150 "biting", "rabid", "blood-thirsty", "ravaging", "slavering"
152 char conditionLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
154 { "in", "24", "25", "upon", "your", "mother's", "grave", "on", "24", "best",
155 "rug", "in", "the", "26", "you", "call", "home", "upon", "your", "heinie"
157 char placeLoc[] = { 5, 0, 3, 7, 11, 17, 20 };
159 { "your", "your", "your", "your", "father's", "your", "mother's", "your",
162 char relationLoc[] = { 6, 0, 1, 2, 3, 5, 7, 9 };
163 char *in_something[] =
164 { "entrails", "anal", "cavity", "shoes", "house", "pantry", "general",
165 "direction", "pants", "bed"
167 char in_somethingLoc[] = { 8, 0, 1, 3, 4, 5, 6, 8, 9, 10 };
169 { "rat", "hole", "sewer", "toxic", "dump", "oil", "refinery", "landfill",
172 char bad_placeLoc[] = { 6, 0, 2, 3, 5, 7, 8, 9 };
173 char **daGrammar[27];
179 daGrammar[0] = start;
180 daGLoc[0] = startLoc;
191 daGrammar[6] = stuff;
192 daGLoc[6] = stuffLoc;
193 daGrammar[7] = noun_and_prep;
194 daGLoc[7] = noun_and_prepLoc;
195 daGrammar[8] = organics;
196 daGLoc[8] = organicsLoc;
197 daGrammar[9] = body_parts;
198 daGLoc[9] = body_partsLoc;
199 daGrammar[10] = noun;
200 daGLoc[10] = nounLoc;
201 daGrammar[11] = animal;
202 daGLoc[11] = animalLoc;
203 daGrammar[12] = good_verb;
204 daGLoc[12] = good_verbLoc;
205 daGrammar[13] = curse;
206 daGLoc[13] = curseLoc;
207 daGrammar[14] = afflictors;
208 daGLoc[14] = afflictorsLoc;
209 daGrammar[15] = quantity;
210 daGLoc[15] = quantityLoc;
211 daGrammar[16] = numbers;
212 daGLoc[16] = numbersLoc;
215 daGrammar[18] = metaphor;
216 daGLoc[18] = metaphorLoc;
217 daGrammar[19] = force;
218 daGLoc[19] = forceLoc;
219 daGrammar[20] = bad_action;
220 daGLoc[20] = bad_actionLoc;
221 daGrammar[21] = beasties;
222 daGLoc[21] = beastiesLoc;
223 daGrammar[22] = condition;
224 daGLoc[22] = conditionLoc;
225 daGrammar[23] = place;
226 daGLoc[23] = placeLoc;
227 daGrammar[24] = relation;
228 daGLoc[24] = relationLoc;
229 daGrammar[25] = in_something;
230 daGLoc[25] = in_somethingLoc;
231 daGrammar[26] = bad_place;
232 daGLoc[26] = bad_placeLoc;
243 void expand (int num, char **grammar[], char *location[], int handle);
246 usage (int ret_code, const char *message, ...) PRINTF_FORMAT (2, 3);
249 usage (int ret_code, const char *message, ...)
255 va_start (args, message);
256 vprintf (message, args);
261 "Usage: insult [OPTION]...\n"
262 "Prints random insults to screen.\n\n"
263 " -h: this help message\n"
264 " -s <integer>: set the random seed (default 4951)\n"
265 " -n <integer>: choose number of insults (default 4)\n"
266 " -f <file>: redirect output to <file>\n");
272 main (int argc, char *argv[])
274 int sentence_cnt, new_seed, i, file_flag, sent_flag, seed_flag;
282 handle = STDOUT_FILENO;
284 for (i = 1; i < argc; i++)
286 if (strcmp (argv[1], "-h") == 0)
288 else if (strcmp (argv[i], "-s") == 0)
291 usage (-1, "Can't have more than one seed");
293 usage (-1, "Missing value for -s");
294 new_seed = atoi (argv[i]);
296 else if (strcmp (argv[i], "-n") == 0)
299 usage (-1, "Can't have more than one sentence option");
301 usage (-1, "Missing value for -n");
302 sentence_cnt = atoi (argv[i]);
303 if (sentence_cnt < 1)
304 usage (-1, "Must have at least one sentence");
306 else if (strcmp (argv[i], "-f") == 0)
309 usage (-1, "Can't have more than one output file");
311 usage (-1, "Missing value for -f");
313 /* Because files have fixed length in the basic Pintos
314 file system, the 0 argument means that this option
315 will not be useful until project 4 is
318 handle = open (argv[i]);
321 printf ("%s: open failed\n", argv[i]);
326 usage (-1, "Unrecognized flag");
331 random_init (new_seed);
332 hprintf (handle, "\n");
334 for (i = 0; i < sentence_cnt; i++)
336 hprintf (handle, "\n");
337 expand (0, daGrammar, daGLoc, handle);
338 hprintf (handle, "\n\n");
348 expand (int num, char **grammar[], char *location[], int handle)
351 int i, which, listStart, listEnd;
353 which = random_ulong () % location[num][0] + 1;
354 listStart = location[num][which];
355 listEnd = location[num][which + 1];
356 for (i = listStart; i < listEnd; i++)
358 word = grammar[num][i];
359 if (!isdigit (*word))
361 if (!ispunct (*word))
362 hprintf (handle, " ");
363 hprintf (handle, "%s", word);
366 expand (atoi (word), grammar, location, handle);