DIRECTORY
   KipperSupport USING[UnKipperer, UnKipperRef, UnKipperRope, RecordUnKipperedRef, Kipperer, KipperRope, KipperRef],
   Basics USING[RawBytes],
   IO USING[STREAM, UnsafeGetBlock, UnsafePutBlock],
   Rope USING[ROPE],
   NewParserData USING[],
   NewParserPrivate USING[TokenTable, TokenCellBody, ParserTable, ParserTableBody, TokenTableBody, ActionTable, ActionTableBody, SymbolTable, SymbolTableBody, ActionCell, SymbolCell, TokenCell, ActionCellBody, SymbolCellBody];

NewParserDataImpl: CEDAR PROGRAM IMPORTS KipperSupport, IO  EXPORTS NewParserData  =
BEGIN
OPEN KipperSupport, Basics, IO, Rope, NewParserPrivate;




KipperActionCellBodyRef: PUBLIC PROC[kipperer: Kipperer,
ActionCellBodyRef: REF ActionCellBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, ActionCellBodyRef] THEN 
      BEGIN
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.state), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.terminal), LONG POINTER TO RawBytes], 0, 2]];
      word ← ORD[(ActionCellBodyRef.action)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.nextState), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.ruleNumber), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.leftSide), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.ruleSize), LONG POINTER TO RawBytes], 0, 2]];
      KipperActionCell[kipperer, (ActionCellBodyRef.next)];
      END;
   END;


UnKipperActionCellBodyRef: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[ActionCellBodyRef: REF ActionCellBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      refAny ← NEW[ActionCellBody];
      RecordUnKipperedRef[unKipperer, refAny];
      ActionCellBodyRef ← NARROW[refAny];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.state), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.terminal), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ActionCellBodyRef.action) ← VAL[word];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.nextState), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.ruleNumber), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.leftSide), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellBodyRef.ruleSize), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ActionCellBodyRef.next) ← UnKipperActionCell[unKipperer];
      END
     ELSE
      ActionCellBodyRef ← NARROW[refAny];
   END;


KipperActionTableBodyRef: PUBLIC PROC[kipperer: Kipperer,
ActionTableBodyRef: REF ActionTableBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, ActionTableBodyRef] THEN 
      BEGIN
      count: CARDINAL ← ActionTableBodyRef.nSlots;
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]];
      FOR I: CARDINAL IN[0..(ActionTableBodyRef.nSlots)) DO
         KipperActionCell[kipperer, (ActionTableBodyRef.actions[I])];
         ENDLOOP;
      END;
   END;


UnKipperActionTableBodyRef: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[ActionTableBodyRef: REF ActionTableBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      count: CARDINAL;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      refAny ← NEW[ActionTableBody[count]];
      RecordUnKipperedRef[unKipperer, refAny];
      ActionTableBodyRef ← NARROW[refAny];
      FOR I: CARDINAL IN[0..(ActionTableBodyRef.nSlots)) DO
         (ActionTableBodyRef.actions[I]) ← UnKipperActionCell[unKipperer];
         ENDLOOP;
      END
     ELSE
      ActionTableBodyRef ← NARROW[refAny];
   END;


KipperTokenCellBodyRef: PUBLIC PROC[kipperer: Kipperer,
TokenCellBodyRef: REF TokenCellBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, TokenCellBodyRef] THEN 
      BEGIN
      KipperRope[kipperer, (TokenCellBodyRef.name)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(TokenCellBodyRef.symbolCode), LONG POINTER TO RawBytes], 0, 2]];
      word ← ORD[(TokenCellBodyRef.kind)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]];
      KipperRope[kipperer, (TokenCellBodyRef.spelling)];
      word ← ORD[(TokenCellBodyRef.case)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]];
      KipperTokenCell[kipperer, (TokenCellBodyRef.next)];
      END;
   END;


UnKipperTokenCellBodyRef: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[TokenCellBodyRef: REF TokenCellBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      refAny ← NEW[TokenCellBody];
      RecordUnKipperedRef[unKipperer, refAny];
      TokenCellBodyRef ← NARROW[refAny];
      (TokenCellBodyRef.name)← UnKipperRope[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(TokenCellBodyRef.symbolCode), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (TokenCellBodyRef.kind) ← VAL[word];
      (TokenCellBodyRef.spelling)← UnKipperRope[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (TokenCellBodyRef.case) ← VAL[word];
      (TokenCellBodyRef.next) ← UnKipperTokenCell[unKipperer];
      END
     ELSE
      TokenCellBodyRef ← NARROW[refAny];
   END;


KipperTokenTableBodyRef: PUBLIC PROC[kipperer: Kipperer,
TokenTableBodyRef: REF TokenTableBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, TokenTableBodyRef] THEN 
      BEGIN
      count: CARDINAL ← TokenTableBodyRef.nSlots;
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]];
      KipperTokenCell[kipperer, (TokenTableBodyRef.idToken)];
      FOR I: CARDINAL IN[0..(TokenTableBodyRef.nSlots)) DO
         KipperTokenCell[kipperer, (TokenTableBodyRef.tokens[I])];
         ENDLOOP;
      END;
   END;


UnKipperTokenTableBodyRef: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[TokenTableBodyRef: REF TokenTableBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      count: CARDINAL;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      refAny ← NEW[TokenTableBody[count]];
      RecordUnKipperedRef[unKipperer, refAny];
      TokenTableBodyRef ← NARROW[refAny];
      (TokenTableBodyRef.idToken) ← UnKipperTokenCell[unKipperer];
      FOR I: CARDINAL IN[0..(TokenTableBodyRef.nSlots)) DO
         (TokenTableBodyRef.tokens[I]) ← UnKipperTokenCell[unKipperer];
         ENDLOOP;
      END
     ELSE
      TokenTableBodyRef ← NARROW[refAny];
   END;


KipperSymbolCellBodyRef: PUBLIC PROC[kipperer: Kipperer,
SymbolCellBodyRef: REF SymbolCellBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, SymbolCellBodyRef] THEN 
      BEGIN
      KipperRope[kipperer, (SymbolCellBodyRef.name)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(SymbolCellBodyRef.code), LONG POINTER TO RawBytes], 0, 2]];
      KipperSymbolCell[kipperer, (SymbolCellBodyRef.next)];
      END;
   END;


UnKipperSymbolCellBodyRef: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[SymbolCellBodyRef: REF SymbolCellBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      refAny ← NEW[SymbolCellBody];
      RecordUnKipperedRef[unKipperer, refAny];
      SymbolCellBodyRef ← NARROW[refAny];
      (SymbolCellBodyRef.name)← UnKipperRope[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(SymbolCellBodyRef.code), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (SymbolCellBodyRef.next) ← UnKipperSymbolCell[unKipperer];
      END
     ELSE
      SymbolCellBodyRef ← NARROW[refAny];
   END;


KipperSymbolTableBodyRef: PUBLIC PROC[kipperer: Kipperer,
SymbolTableBodyRef: REF SymbolTableBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, SymbolTableBodyRef] THEN 
      BEGIN
      count: CARDINAL ← SymbolTableBodyRef.nSlots;
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]];
      FOR I: CARDINAL IN[0..(SymbolTableBodyRef.nSlots)) DO
         KipperSymbolCell[kipperer, (SymbolTableBodyRef.symbols[I])];
         ENDLOOP;
      END;
   END;


UnKipperSymbolTableBodyRef: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[SymbolTableBodyRef: REF SymbolTableBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      count: CARDINAL;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      refAny ← NEW[SymbolTableBody[count]];
      RecordUnKipperedRef[unKipperer, refAny];
      SymbolTableBodyRef ← NARROW[refAny];
      FOR I: CARDINAL IN[0..(SymbolTableBodyRef.nSlots)) DO
         (SymbolTableBodyRef.symbols[I]) ← UnKipperSymbolCell[unKipperer];
         ENDLOOP;
      END
     ELSE
      SymbolTableBodyRef ← NARROW[refAny];
   END;


KipperParserTableBodyRef: PUBLIC PROC[kipperer: Kipperer,
ParserTableBodyRef: REF ParserTableBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, ParserTableBodyRef] THEN 
      BEGIN
      KipperSymbolCell[kipperer, (ParserTableBodyRef.unAnalyzedSymbols)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ParserTableBodyRef.nSymbols), LONG POINTER TO RawBytes], 0, 2]];
      KipperTokenCell[kipperer, (ParserTableBodyRef.unAnalyzedTokens)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ParserTableBodyRef.nTokens), LONG POINTER TO RawBytes], 0, 2]];
      KipperActionCell[kipperer, (ParserTableBodyRef.unAnalyzedActions)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ParserTableBodyRef.nActions), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ParserTableBodyRef.startState), LONG POINTER TO RawBytes], 0, 2]];
      KipperSymbolTable[kipperer, (ParserTableBodyRef.symbolTable)];
      KipperTokenTable[kipperer, (ParserTableBodyRef.tokenTable)];
      KipperActionTable[kipperer, (ParserTableBodyRef.actionTable)];
      END;
   END;


UnKipperParserTableBodyRef: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[ParserTableBodyRef: REF ParserTableBody] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      refAny ← NEW[ParserTableBody];
      RecordUnKipperedRef[unKipperer, refAny];
      ParserTableBodyRef ← NARROW[refAny];
      (ParserTableBodyRef.unAnalyzedSymbols) ← UnKipperSymbolCell[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ParserTableBodyRef.nSymbols), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ParserTableBodyRef.unAnalyzedTokens) ← UnKipperTokenCell[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ParserTableBodyRef.nTokens), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ParserTableBodyRef.unAnalyzedActions) ← UnKipperActionCell[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ParserTableBodyRef.nActions), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ParserTableBodyRef.startState), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ParserTableBodyRef.symbolTable) ← UnKipperSymbolTable[unKipperer];
      (ParserTableBodyRef.tokenTable) ← UnKipperTokenTable[unKipperer];
      (ParserTableBodyRef.actionTable) ← UnKipperActionTable[unKipperer];
      END
     ELSE
      ParserTableBodyRef ← NARROW[refAny];
   END;


KipperActionCell: PUBLIC PROC[kipperer: Kipperer,
ActionCellVal: ActionCell] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, ActionCellVal] THEN 
      BEGIN
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellVal.state), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellVal.terminal), LONG POINTER TO RawBytes], 0, 2]];
      word ← ORD[(ActionCellVal.action)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellVal.nextState), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellVal.ruleNumber), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellVal.leftSide), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ActionCellVal.ruleSize), LONG POINTER TO RawBytes], 0, 2]];
      KipperActionCell[kipperer, (ActionCellVal.next)];
      END;
   END;


UnKipperActionCell: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[ActionCellVal: ActionCell] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      refAny ← NEW[ActionCellBody];
      RecordUnKipperedRef[unKipperer, refAny];
      ActionCellVal ← NARROW[refAny];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellVal.state), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellVal.terminal), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ActionCellVal.action) ← VAL[word];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellVal.nextState), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellVal.ruleNumber), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellVal.leftSide), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ActionCellVal.ruleSize), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ActionCellVal.next) ← UnKipperActionCell[unKipperer];
      END
     ELSE
      ActionCellVal ← NARROW[refAny];
   END;


KipperActionTable: PUBLIC PROC[kipperer: Kipperer,
ActionTableVal: ActionTable] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, ActionTableVal] THEN 
      BEGIN
      count: CARDINAL ← ActionTableVal.nSlots;
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]];
      FOR I: CARDINAL IN[0..(ActionTableVal.nSlots)) DO
         KipperActionCell[kipperer, (ActionTableVal.actions[I])];
         ENDLOOP;
      END;
   END;


UnKipperActionTable: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[ActionTableVal: ActionTable] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      count: CARDINAL;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      refAny ← NEW[ActionTableBody[count]];
      RecordUnKipperedRef[unKipperer, refAny];
      ActionTableVal ← NARROW[refAny];
      FOR I: CARDINAL IN[0..(ActionTableVal.nSlots)) DO
         (ActionTableVal.actions[I]) ← UnKipperActionCell[unKipperer];
         ENDLOOP;
      END
     ELSE
      ActionTableVal ← NARROW[refAny];
   END;


KipperTokenCell: PUBLIC PROC[kipperer: Kipperer,
TokenCellVal: TokenCell] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, TokenCellVal] THEN 
      BEGIN
      KipperRope[kipperer, (TokenCellVal.name)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(TokenCellVal.symbolCode), LONG POINTER TO RawBytes], 0, 2]];
      word ← ORD[(TokenCellVal.kind)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]];
      KipperRope[kipperer, (TokenCellVal.spelling)];
      word ← ORD[(TokenCellVal.case)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]];
      KipperTokenCell[kipperer, (TokenCellVal.next)];
      END;
   END;


UnKipperTokenCell: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[TokenCellVal: TokenCell] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      refAny ← NEW[TokenCellBody];
      RecordUnKipperedRef[unKipperer, refAny];
      TokenCellVal ← NARROW[refAny];
      (TokenCellVal.name)← UnKipperRope[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(TokenCellVal.symbolCode), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (TokenCellVal.kind) ← VAL[word];
      (TokenCellVal.spelling)← UnKipperRope[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@word], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (TokenCellVal.case) ← VAL[word];
      (TokenCellVal.next) ← UnKipperTokenCell[unKipperer];
      END
     ELSE
      TokenCellVal ← NARROW[refAny];
   END;


KipperTokenTable: PUBLIC PROC[kipperer: Kipperer,
TokenTableVal: TokenTable] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, TokenTableVal] THEN 
      BEGIN
      count: CARDINAL ← TokenTableVal.nSlots;
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]];
      KipperTokenCell[kipperer, (TokenTableVal.idToken)];
      FOR I: CARDINAL IN[0..(TokenTableVal.nSlots)) DO
         KipperTokenCell[kipperer, (TokenTableVal.tokens[I])];
         ENDLOOP;
      END;
   END;


UnKipperTokenTable: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[TokenTableVal: TokenTable] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      count: CARDINAL;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      refAny ← NEW[TokenTableBody[count]];
      RecordUnKipperedRef[unKipperer, refAny];
      TokenTableVal ← NARROW[refAny];
      (TokenTableVal.idToken) ← UnKipperTokenCell[unKipperer];
      FOR I: CARDINAL IN[0..(TokenTableVal.nSlots)) DO
         (TokenTableVal.tokens[I]) ← UnKipperTokenCell[unKipperer];
         ENDLOOP;
      END
     ELSE
      TokenTableVal ← NARROW[refAny];
   END;


KipperSymbolCell: PUBLIC PROC[kipperer: Kipperer,
SymbolCellVal: SymbolCell] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, SymbolCellVal] THEN 
      BEGIN
      KipperRope[kipperer, (SymbolCellVal.name)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(SymbolCellVal.code), LONG POINTER TO RawBytes], 0, 2]];
      KipperSymbolCell[kipperer, (SymbolCellVal.next)];
      END;
   END;


UnKipperSymbolCell: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[SymbolCellVal: SymbolCell] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      refAny ← NEW[SymbolCellBody];
      RecordUnKipperedRef[unKipperer, refAny];
      SymbolCellVal ← NARROW[refAny];
      (SymbolCellVal.name)← UnKipperRope[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(SymbolCellVal.code), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (SymbolCellVal.next) ← UnKipperSymbolCell[unKipperer];
      END
     ELSE
      SymbolCellVal ← NARROW[refAny];
   END;


KipperSymbolTable: PUBLIC PROC[kipperer: Kipperer,
SymbolTableVal: SymbolTable] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, SymbolTableVal] THEN 
      BEGIN
      count: CARDINAL ← SymbolTableVal.nSlots;
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]];
      FOR I: CARDINAL IN[0..(SymbolTableVal.nSlots)) DO
         KipperSymbolCell[kipperer, (SymbolTableVal.symbols[I])];
         ENDLOOP;
      END;
   END;


UnKipperSymbolTable: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[SymbolTableVal: SymbolTable] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      count: CARDINAL;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[LONG[@count], LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      refAny ← NEW[SymbolTableBody[count]];
      RecordUnKipperedRef[unKipperer, refAny];
      SymbolTableVal ← NARROW[refAny];
      FOR I: CARDINAL IN[0..(SymbolTableVal.nSlots)) DO
         (SymbolTableVal.symbols[I]) ← UnKipperSymbolCell[unKipperer];
         ENDLOOP;
      END
     ELSE
      SymbolTableVal ← NARROW[refAny];
   END;


KipperParserTable: PUBLIC PROC[kipperer: Kipperer,
ParserTableVal: ParserTable] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   IF KipperRef[kipperer, ParserTableVal] THEN 
      BEGIN
      KipperSymbolCell[kipperer, (ParserTableVal.unAnalyzedSymbols)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ParserTableVal.nSymbols), LONG POINTER TO RawBytes], 0, 2]];
      KipperTokenCell[kipperer, (ParserTableVal.unAnalyzedTokens)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ParserTableVal.nTokens), LONG POINTER TO RawBytes], 0, 2]];
      KipperActionCell[kipperer, (ParserTableVal.unAnalyzedActions)];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ParserTableVal.nActions), LONG POINTER TO RawBytes], 0, 2]];
      UnsafePutBlock[kipperer.stream, [LOOPHOLE[@(ParserTableVal.startState), LONG POINTER TO RawBytes], 0, 2]];
      KipperSymbolTable[kipperer, (ParserTableVal.symbolTable)];
      KipperTokenTable[kipperer, (ParserTableVal.tokenTable)];
      KipperActionTable[kipperer, (ParserTableVal.actionTable)];
      END;
   END;


UnKipperParserTable: PUBLIC PROC[unKipperer: UnKipperer] RETURNS[ParserTableVal: ParserTable] = TRUSTED
   BEGIN
   
   word: CARDINAL ← 0;
   doubleWord: LONG CARDINAL ← 0;
   refAny: REF ANY ← NIL;
   flag: BOOLEAN ← FALSE;
   
   [flag, refAny] ← UnKipperRef[unKipperer];
   IF flag THEN
      BEGIN
      refAny ← NEW[ParserTableBody];
      RecordUnKipperedRef[unKipperer, refAny];
      ParserTableVal ← NARROW[refAny];
      (ParserTableVal.unAnalyzedSymbols) ← UnKipperSymbolCell[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ParserTableVal.nSymbols), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ParserTableVal.unAnalyzedTokens) ← UnKipperTokenCell[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ParserTableVal.nTokens), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ParserTableVal.unAnalyzedActions) ← UnKipperActionCell[unKipperer];
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ParserTableVal.nActions), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      IF UnsafeGetBlock[unKipperer.stream, [LOOPHOLE[@(ParserTableVal.startState), LONG POINTER TO RawBytes], 0, 2]] # 2 THEN ERROR;
      (ParserTableVal.symbolTable) ← UnKipperSymbolTable[unKipperer];
      (ParserTableVal.tokenTable) ← UnKipperTokenTable[unKipperer];
      (ParserTableVal.actionTable) ← UnKipperActionTable[unKipperer];
      END
     ELSE
      ParserTableVal ← NARROW[refAny];
   END;

END..