+static char *find_verb_by_number(int num);
+
+static void list_grammar_line_v1(int mark)
+{
+ int action, actsym;
+ int ix, len;
+ char *str;
+
+ /* There is no GV1 for Glulx. */
+ if (glulx_mode)
+ return;
+
+ action = (grammar_lines[mark] << 8) | (grammar_lines[mark+1]);
+ mark += 2;
+
+ printf(" *");
+ while (grammar_lines[mark] != 15) {
+ uchar tok = grammar_lines[mark];
+ mark += 3;
+
+ switch (tok) {
+ case 0:
+ printf(" noun");
+ break;
+ case 1:
+ printf(" held");
+ break;
+ case 2:
+ printf(" multi");
+ break;
+ case 3:
+ printf(" multiheld");
+ break;
+ case 4:
+ printf(" multiexcept");
+ break;
+ case 5:
+ printf(" multiinside");
+ break;
+ case 6:
+ printf(" creature");
+ break;
+ case 7:
+ printf(" special");
+ break;
+ case 8:
+ printf(" number");
+ break;
+ default:
+ if (tok >= 16 && tok < 48) {
+ printf(" noun=%d", tok-16);
+ }
+ else if (tok >= 48 && tok < 80) {
+ printf(" routine=%d", tok-48);
+ }
+ else if (tok >= 80 && tok < 128) {
+ printf(" scope=%d", tok-80);
+ }
+ else if (tok >= 128 && tok < 160) {
+ printf(" attr=%d", tok-128);
+ }
+ else if (tok >= 160) {
+ printf(" prep=%d", tok);
+ }
+ else {
+ printf(" ???");
+ }
+ }
+ }
+
+ printf(" -> ");
+ actsym = actions[action].symbol;
+ str = (symbols[actsym].name);
+ len = strlen(str) - 3; /* remove "__A" */
+ for (ix=0; ix<len; ix++) putchar(str[ix]);
+ printf("\n");
+}
+
+static void list_grammar_line_v2(int mark)
+{
+ int action, flags, actsym;
+ int ix, len;
+ char *str;
+
+ if (!glulx_mode) {
+ action = (grammar_lines[mark] << 8) | (grammar_lines[mark+1]);
+ flags = (action & 0x400);
+ action &= 0x3FF;
+ mark += 2;
+ }
+ else {
+ action = (grammar_lines[mark] << 8) | (grammar_lines[mark+1]);
+ mark += 2;
+ flags = grammar_lines[mark++];
+ }
+
+ printf(" *");
+ while (grammar_lines[mark] != 15) {
+ int toktype, tokdat, tokalt;
+ if (!glulx_mode) {
+ toktype = grammar_lines[mark] & 0x0F;
+ tokalt = (grammar_lines[mark] >> 4) & 0x03;
+ mark += 1;
+ tokdat = (grammar_lines[mark] << 8) | (grammar_lines[mark+1]);
+ mark += 2;
+ }
+ else {
+ toktype = grammar_lines[mark] & 0x0F;
+ tokalt = (grammar_lines[mark] >> 4) & 0x03;
+ mark += 1;
+ tokdat = (grammar_lines[mark] << 24) | (grammar_lines[mark+1] << 16) | (grammar_lines[mark+2] << 8) | (grammar_lines[mark+3]);
+ mark += 4;
+ }
+
+ if (tokalt == 3 || tokalt == 1)
+ printf(" /");
+
+ switch (toktype) {
+ case 1:
+ switch (tokdat) {
+ case 0: printf(" noun"); break;
+ case 1: printf(" held"); break;
+ case 2: printf(" multi"); break;
+ case 3: printf(" multiheld"); break;
+ case 4: printf(" multiexcept"); break;
+ case 5: printf(" multiinside"); break;
+ case 6: printf(" creature"); break;
+ case 7: printf(" special"); break;
+ case 8: printf(" number"); break;
+ case 9: printf(" topic"); break;
+ default: printf(" ???"); break;
+ }
+ break;
+ case 2:
+ printf(" '");
+ print_dict_word(tokdat);
+ printf("'");
+ break;
+ case 3:
+ printf(" noun=%d", tokdat);
+ break;
+ case 4:
+ printf(" attr=%d", tokdat);
+ break;
+ case 5:
+ printf(" scope=%d", tokdat);
+ break;
+ case 6:
+ printf(" routine=%d", tokdat);
+ break;
+ default:
+ printf(" ???%d:%d", toktype, tokdat);
+ break;
+ }
+ }
+ printf(" -> ");
+ actsym = actions[action].symbol;
+ str = (symbols[actsym].name);
+ len = strlen(str) - 3; /* remove "__A" */
+ for (ix=0; ix<len; ix++) putchar(str[ix]);
+ if (flags) printf(" (reversed)");
+ printf("\n");
+}
+