ParseOneStream: PUBLIC PROC[from: IO.STREAM, table: OneCasabaParser.ParserTable
, setUpLinks:
PROC[SeeProdLinkArray, TokenLinkArray], nProductions: INT, debugFlags:
CARDINAL, debuggingTextTo:
IO.STREAM] RETURNS[REF ANY] =
BEGIN
prodLinkArray: SeeProdLinkArray ← NEW[SeeProdLinkArrayBody[nProductions]];
genericTokenLinkArray: TokenLinkArray ← NEW[TokenLinkArrayBody];
stack: LIST OF REF ANY ← NIL;
charPosition: INT ← 0;
last100Index: CARDINAL ← 1;
Last100: ARRAY [1..100] OF REF Stuff;
Stuff: TYPE = RECORD[doing: StuffCase, code: CARDINAL, text: Rope.ROPE];
StuffCase: TYPE = {shift, reduction, trying};
Record:
PROC[case: StuffCase, code:
CARDINAL, text:
Rope.ROPE] =
BEGIN
IF Last100[last100Index] =
NIL
THEN
Last100[last100Index] ← NEW[Stuff];
Last100[last100Index]^ ← [case, code, text];
last100Index ← last100Index+1;
IF last100Index > 100 THEN last100Index ← 1;
END;
GetSourceToken:
PROC
RETURNS[tokenKind: IO.TokenKind, tokenText: Rope
.ROPE, position:
INT] =
BEGIN
charsSkipped: CARDINAL;
thisTokenPosition: INT;
DO
[tokenKind, tokenText, charsSkipped] ← IO.GetCedarTokenRope[from,
FALSE
! IO.EndOfStream =>
BEGIN
tokenKind ← tokenEOF;
tokenText ← "tokenEOF";
charsSkipped ← 0; -- this last is a lie
CONTINUE;
END];
charPosition ← thisTokenPosition ← charPosition+charsSkipped;
charPosition ← charPosition+Rope.Length[tokenText];
IF tokenKind # tokenCOMMENT
THEN
RETURN[tokenKind, tokenText, thisTokenPosition];
ENDLOOP;
END;
SeeGenericShift:
PROC[code:
CARDINAL, kind: IO.TokenKind, text:
Rope.ROPE, firstCharPosition:
INT] =
BEGIN
IF Basics.
BITAND[debugFlags, ShowParseSteps] # 0
THEN IO.PutF[debuggingTextTo, " shift %g:%g\N", IO.card[code], IO.rope[text]]
ELSE Record[shift, code, text];
IF kind # tokenROPE THEN
stack ← CONS[genericTokenLinkArray[kind][text, firstCharPosition], stack]
ELSE
BEGIN
withoutQuotes: Rope.ROPE ← Rope.Substr[base: text, start: 1, len: Rope.Length[text]-2];
stack ← CONS[genericTokenLinkArray[kind][withoutQuotes, firstCharPosition+1], stack]
END;
END;
SeeReduction:
PROC[rule:
CARDINAL, firstCharPosition:
INT, length:
INT] =
BEGIN
IF Basics.
BITAND[debugFlags, ShowParseSteps] # 0
THEN IO.PutF[debuggingTextTo, " reduce by %g\N", IO.card[rule]]
ELSE Record[reduction, rule, ""];
stack ← prodLinkArray.links[rule][stack, firstCharPosition, length];
END;
setUpLinks[prodLinkArray, genericTokenLinkArray];
[] ← OneCasabaParser.Parse[table, GetSourceToken, SeeReduction, SeeGenericShift];
IO.Close[from];
RETURN[stack.first];
END;
GetSourceInfo: PUBLIC SIGNAL RETURNS[sourcePosition, sourceLength: INT] = CODE;