This is an interpretation of Fischer's strict precedence parsing
algorithm, as described in his Cornell dissertation.

Overview:
The major problem (for an FP YACC) might well be breaking things up
according to precedences, so that a single simple phrase may be handled
on its own. We can then aa to that a true parser which
-- figures out the (Ordinary or Iterated) production to use, and
-- applies it to all simple phrases, ignoring all non-simple phrases.
There is a nasty suspicion that the above "major problem" would be
more complex for non-simple-precedence grammars.


Step 1
REL is set to the array of the syntactic relations between adjacent INPUT
	tokens (it is of size |INPUT| - 1)
REL_POS is set to the array of positions where REL is one of <, >, <> (the
	values in REL_POS are monotonically increasing)
BALANCED_REL is set to an array of size |REL_POS| - 1. The array elements
	contain True iff REL [REL_POS [index]] is one of < or <>, and at
	the same time    REL [REL_POS [index + 1]] is one of > or <>.
SP_RT_POS is assigned all those elements of REL_POS [2..MAX] for which
	BALANCED_REL is true, i.e., SP_RT_POS contains the end positions
	of all reducible phrases.
IF |SP_RT_POS| = 0, then if INPUT = $START$ then done, else error
SP_LEN is assigned the differences between each closing position from
	SP_RT_POS and the corresponding opening position (one formula is
	SP_RT_POS - (REL_POS [1..MAX-1] selected by BALANCED_REL)).

Summary: REL = adjacecy relations, REL_POS = positions where REL
is one of <, >, ><, BALANCED_REL is |REL_POS| - 1, 1 where a < >< is
followed immediately by a >,><, 0 otherwise (there are no equals, ' 's),
SP_RT_POS is |REL_POS| - 1, the positions at which BALANCED_RELS
close, and finally SP_LEN is the length of the balanced phrases preceding
the positions in SP_RT_POS.


Step 2
ORDINARY_RT_POS is set to all entries of SP_RT_POS for which
	SP_LEN < MAX_RHS_LENGTH
POS is set to ORDINARY_RT_POS
ORDINARY_LEN is set to all entries of SP_LEN for which SP_LEN < MAX_RHS_LENGTH
ENCODED_SP is of size |POS| and filled with the constant NULL_ENCODING
COUNT is set to 1
ACTIVE is initialized to IOTA (|POS|), the array 1..|POS|

Summary: POS and ORDINARY_RT_POS are set to the closing positions of
the normally-reducible phrases. ORDINARY_LEN is the lengths of these
phrases, i.e. ORDINARY_X is like SP_X except that only those phrases
with length < max are considered. Also, we initialize ENCODED_SP, COUNT,
ACTIVE.


Step 3
REPEAT		/* until ACTIVE is empty */
  For all indices in ACTIVE,
    ENCODED_SP [INDEX] :=
	Encode (ENCODED_SP [INDEX], INPUT [POS [INDEX]], COUNT);
	    this encodes one further input character into ENCODED_SP
    INPUT [POS [INDEX]] := blank;	to show the char has been read
that is, encode INPUT [ACTIVE] to ENCODED_SP [ACTIVE] and delete
INPUT [ACTIVE]
    ACTIVE := those elements of ACTIVE for which ORDINARY_LEN > COUNT
    COUNT := COUNT + 1;
    POS := POS - 1;  meaning decrement all the position indices, so
		     as to consider the preceding input tokens/chars
UNTIL (|ACTIVE| = 0);

Summary: encode all simple phrases. ENCODED_SP has the output (encoding).
The tokens encoded are deleted from (replaced by blanks in) INPUT


Step 4
ITER_RT_POS := those entries of SP_RT_POS not put inot ORDINARY_RT_POS
ITER_LEN := is set to all entries of SP_LEN for which SP_LEN >= MAX_RHS_LENGTH
COMPARE_FIELD := ITER_RT_POS [1], ITER_RT_POS [1] - 1, ..
		 ..  ITER_RT_POS [1] - (ITER_LEN [1] - 2),
		 ITER_RT_POS [2], ITER_RT_POS [2] - 1, ..
		 ..  ITER_RT_POS [2] - (ITER_LEN [2] - 2)
	COMPARE_FIELD is set to the indices of all but the first
		token of the the first phrase
IF (\/OR) (INPUT [COMPARE_FIELD [X]] != INPUT [COMPARE_FIELD [X] - 1]
  THEN ERROR	 all successive entries should be the same, otherwise no iter
FORALL X: INPUT [COMPARE_FIELD [X]] := blank;
	in other words, delete all the unnecessary tokens in iterative
	phrases

Summary: We check that all iterated productions each have all the same
element, otherwise error. Also, the positions of all iterated tokens
except for the first (token) are cleared (in INPUT) at this time.


Step 5
ORDINARY_PROD := Lookup_Prod (ENCODED_SP, ORDINARY_LEN);
				^ from (3)	^ from (2)
	ORDINARY_PROD is an array of size |ENCODED_SP| which contains
	the production numbers to be output.
ITER_PROD := ITER_PROD_TABLE [INPUT [ITER_RT_POS]]
	For each iterative production, we output the production
	corresponding to the symbol in the input at the start of
	the phrase. In other words, for each iterative production,
	the production number to be output.
IF FORSOME X (ORDINARY_PROD [X] = 0 OR ITER_PROD [X] = 0) THEN ERROR

Summary: We look up the production numbers for the ordinary and
iterated productions; these numbers will be output in (7).


Step 6
Forall X, X in ORDINARY_RT_POS
  INPUT [X] := LHS_TABLE [ORDINARY_PROD [X]];
Forall X, X in ITER_RT_POS
  INPUT [X] := LHS_TABLE [ITER_PROD [X]];

Summary?: replace the lone remaining token from the phrase in INPUT
with the left-hand side of the production (the non-terminal symbol).


Step 7
Output (ORDINARY_RT_POS - # of preceding blanks in INPUT)
Output (ORDINARY_PROD)		the positions and productions
Output (ITER_RT_POS - # of preceding blanks in INPUT)
Output (ITER_PROD)		the positions and productions and lengths
Output (ITER_LEN)
INPUT := INPUT - any element that is blank
GOTO (1)

Summary: output the computed ORDINARY and ITER RT_POS and PROD, the
RT_POS corrected for by the blanks that will be eliminated from INPUT.
