anchor.diff:  readStatement :
   	READ fileName
   	NEXT? RECORD?
  -	(INTO identifier)?
  -	(
  -		WITH?
  -		(
  -			(KEPT | NO) LOCK
  -			| WAIT
  -		)
  -	)?
  -	(KEY IS? qualifiedDataName)?
  -	(INVALID KEY? statements)?
  -	(NOT INVALID KEY? statements)?
  -	(AT? END statements)?
  -	(NOT AT? END statements)?
  +	readInto?
  +	readWith?
  +	readKey?
  +	invalidKeyPhrase?
  +	notInvalidKeyPhrase?
  +	atEndPhrase?
  +	notAtEndPhrase?
   	END_READ?
   ;
   
  +readInto :
  +	INTO identifier
  +;
  +
  +readWith :
  +	WITH? ((KEPT | NO) LOCK | WAIT)
  +;
  +
  +readKey :
  +	KEY IS? qualifiedDataName
  +;
  +
   // receive statement
   
   receiveStatement :
  -	RECEIVE
  -	(
  -		dataName FROM (THREAD dataName | LAST THREAD | ANY THREAD)
  -		(
  -			BEFORE TIME? (numericLiteral | identifier)
  -			| WITH? NO WAIT
  -			| THREAD IN? dataName
  -			| SIZE IN? (numericLiteral | identifier)
  -			| STATUS IN? (identifier)
  -			| onExceptionClause
  -			| notOnExceptionClause
  -		)
  -		| cdName (MESSAGE | SEGMENT) INTO? identifier (NO DATA statements)? (WITH DATA statements)?
  -	)
  +	RECEIVE	(receiveFromStatement | receiveIntoStatement)
  +	onExceptionClause?
  +	notOnExceptionClause?
   	END_RECEIVE?
  +;
  +
  +receiveFromStatement :
  +	dataName FROM receiveFrom (receiveBefore | receiveWith | receiveThread | receiveSize | receiveStatus)*
  +;
  +
  +receiveFrom :
  +	THREAD dataName | LAST THREAD | ANY THREAD
  +;
  +
  +receiveIntoStatement :
  +	cdName (MESSAGE | SEGMENT) INTO? identifier receiveNoData? receiveWithData?
  +;
  +
  +receiveNoData :
  +	NO DATA statements
  +;
  +
  +receiveWithData :
  +	WITH DATA statements
  +;
  +
  +receiveBefore :
  +	BEFORE TIME? (numericLiteral | identifier)
  +;
  +
  +receiveWith :
  +	WITH? NO WAIT
  +;
  +
  +receiveThread :
  +	THREAD IN? dataName
  +;
  +
  +receiveSize :
  +	SIZE IN? (numericLiteral | identifier)
  +;
  +
  +receiveStatus :
  +	STATUS IN? (identifier)
   ;
   
   // release statement
  
positive.code: 	(
  		USING (callByReferenceStatement | callByValueStatement | callByContentStatement)+
  	)?
  	(GIVING identifier)?
  	(ON? OVERFLOW statements)?
  	onExceptionClause?
  	notOnExceptionClause?
  	END_CALL?
  ;
  
  callByReferenceStatement :
  	(BY? REFERENCE)? (identifier | ADDRESS OF identifier | fileName | INTEGER identifier | STRING identifier)+
  ;
  
  callByValueStatement :
  	BY? VALUE (identifier | literal)+
  ;
  
  callByContentStatement :
  	BY? CONTENT ((LENGTH OF)? identifier | ADDRESS OF identifier | literal)+
  ;
  
  // cancel statement
  
  cancelStatement :
  	CANCEL (identifier | literal | libraryName (BYTITLE | BYFUNCTION))+
  ;
  
  // close statement
  
  closeStatement :
  	CLOSE
  	(
  		fileName (closeReelUnitStatement | closeRelativeStatement | closePortFileIOStatement)?
  	)+
  ;
  
  closeReelUnitStatement :
  	(REEL | UNIT)
  	(FOR? REMOVAL)?
  	(WITH? (NO REWIND | LOCK))?
  ;
  
  closeRelativeStatement :
  
negative.code: 		| divideIntoGivingStatement
  		| divideIntoByGivingStatement
  	)
  	divideRemainder?
  	onSizeErrorPhrase?
  	notOnSizeErrorPhrase?
  	END_DIVIDE?
  ;
  
  divideIntoStatement :
  	INTO (identifier | literal) divideGivingPhrase?
  ;
  
  divideIntoGivingStatement :
  	INTO divideGiving+
  ;
  
  divideIntoByGivingStatement :
  	BY (identifier | literal) divideGivingPhrase?
  ;
  
  divideGivingPhrase :
  	GIVING divideGiving+
  ;
  
  divideGiving :
  	identifier ROUNDED?
  ;
  
  divideRemainder :
  	REMAINDER identifier
  ;
  
  // enable statement
  
  enableStatement :
  	ENABLE (INPUT TERMINAL? | I_O TERMINAL | OUTPUT) cdName WITH? KEY (literal | identifier)
  ;
  
  // entry statement
  