BEGIN
e: LIST OF REF ANY;
savepos: INT;
lex: Lexeme;
rp: REF Props;
qm: BOOL ← TRUE;
IsMatchfixOrSubfixOp:
PROC [x: Lexeme]
RETURNS [
BOOL] =
INLINE
{WITH x SELECT FROM
atom: ATOM =>
{rpx: REF Props = GetAtomProps[atom].rp;
RETURN [rpx.matchfix OR rpx.subfix]};
ENDCASE => RETURN[FALSE]};
Beats:
PROC [x: Lexeme, rp:
REF Props]
RETURNS [
BOOL] =
INLINE
{WITH x SELECT FROM
atom: ATOM =>
{rpx: REF Props = GetAtomProps[atom].rpx;
RETURN [rpx.bindingPower > rp.bindingPower]};
ENDCASE => RETURN[FALSE]};
Retract:
PROC =
INLINE
{t: LIST OF REF ANY ← e.rest; e.rest ← NIL; e ← t};
e ← s3;
openCount ← 0;
e.first ← NIL;
WHILE NOT Exhausted [stream, table] DO
savepos ← stream.pos;
[lex, error, rp] ← Lex[stream, table];
IF error # NIL THEN EXIT;
SELECT TRUE FROM
qm AND rp = NIL
=> {e.first ← lex; qm ← FALSE};
qm AND rp # NIL AND (rp.prefix OR rp.matchfix)
=> {e.first ← CONS[lex, CONS[NIL, e]]; e ← NARROW[Cdar[e]]};
~ qm AND rp # NIL AND (rp.infix OR rp.subfix)
=> {WHILE Beats[Caadr[e], rp] AND ~ IsMatchfixOrSubfixOp[Caadr[e]]
DO Retract[] ENDLOOP;
e.first ← CONS[lex, CONS[e.first, CONS[NIL, e]]]; e ← NARROW[Cddar[e]];
qm ← TRUE};
~qm AND rp # NIL AND rp.postfix
=> {WHILE Beats[Caadr[e], rp] DO Retract[] ENDLOOP;
e.first ← CONS[lex, CONS[e.first, NIL]]};
~qm AND rp # NIL AND rp.closefix
=> {WHILE ~ IsMatchfixOrSubfixOp[Caadr[e]] DO Retract[] ENDLOOP;
IF Matches[Caadr[e], rp]
THEN Retract[]
ELSE {error ← "Parse Error"; EXIT}}
ENDCASE => EXIT
ENDLOOP;
Unthread right branch of tree:
WHILE Caadr[e] # weakOp DO
IF IsMatchfixOrSubfixOp[Caadr[e]] THEN openCount ← openCount + 1;
Retract[];
ENDLOOP;
IF error = NIL AND (qm OR openCount # 0) THEN {error ← "Parse error "};
expr ← s3.first