Handling serial comma in player input

I’ve seen occasional complaints about the parser’s long-standing inability to handle a serial comma (Oxford comma) in player input specifying a list of objects. It seems that the best-known method of handling it is an I6 inclusion by zarf that excises the word 'and' from command input when it follows a comma, then re-parses.

Since I didn’t know about that, while looking into this I wrote something to handle it on the parsing side. It requires only a small change to the code in Parse Token Letter E:

Include (-

! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! Parser.i6t: Parse Token Letter E (MODIFIED)
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====

	! Object(s) specified now: is that the end of the list, or have we reached
	! "and", "but" and so on?  If so, create a multiple-object list if we
	! haven't already (and are allowed to).

  .NextInList;

	o = NextWord();

	if (o == AND1__WD or AND2__WD or AND3__WD or BUT1__WD or BUT2__WD or BUT3__WD or comma_word) {

	    #Ifdef DEBUG;
	    if (parser_trace >= 3) print "  [Read connective '", (address) o, "']^";
	    #Endif; ! DEBUG

	    if (~~token_allows_multiple) {
	        if (multiflag) jump PassToken; ! give UPTO_PE error
	        etype=MULTI_PE;
	        jump FailToken;
	    }

		! BEGIN ADDITION (to accept serial comma in player input if that use option is specified)
		#Ifdef SERIAL_COMMA;	! REMOVABLE
		if (o == comma_word) {
			if (NextWord() ~= 'and') wn--;
		}
		#Endif;					! REMOVABLE
		! END ADDITION

	    if (o == BUT1__WD or BUT2__WD or BUT3__WD) and_parity = 1-and_parity;

	    if (~~many_flag) {
	        multiple_object-->0 = 1;
	        multiple_object-->1 = single_object;
	        many_flag = true;
	        #Ifdef DEBUG;
	        if (parser_trace >= 3) print "  [Making new list from ", (the) single_object, "]^";
	        #Endif; ! DEBUG
	    }
	    dont_infer = true; inferfrom=0;           ! Don't print (inferences)
	    jump ObjectList;                          ! And back around
	}

	wn--;   ! Word marker back to first not-understood word

-) instead of "Parse Token Letter E" in "Parser.i6t".

The version shown above is for 6M62 – a 10.1.2 inclusion would be much longer because routines (in this case ParseToken__) must be replaced in full, but the essentials are the same.

The added code just causes the parser to ignore any 'and' found immediately following comma_word when constructing a multiple object list. Note that the parser will understand a serial comma in player input only if Use serial comma. is specified. If you want the parser to accept a serial comma even when not using it for output, then deleting or commenting out the two lines marked REMOVABLE will do that.

2 Likes

The “Use serial comma” option says whether the author prefers the serial comma. It shouldn’t be taken as indicating whether the player does.

Sure, that’s why I included a note about how to unlink it from the use option. As I was getting ready to submit the original post it occurred to me that the kind of person who takes an interest in this functionality might be the kind of person who prefers that their game behave consistently for both input and output. (It’s kind of a do-it-yourself kit, anyway.)

I see that I described what your version does incorrectly, though. Sorry about that – fixed above.

Now, if I wanted to require the serial comma in input, in revenge for the past three decades of Inform rejecting it…

3 Likes

My view is that it shouldn’t really be the place of the author to dictate whether the player is ‘allowed’ to use a serial comma. The canonical behaviour (i.e. Infocom’s interpreters) is to allow it, so it is strange that it has never been ‘officially’ implemented in Inform.

1 Like

Clearly it’s a sign of the creator’s anti-Oxford sentiments!

Clearly enjoyed his undergrad days (Cambridge) far more than his post-grad life & career (Oxford) :thinking: