DIRECTORY OperatorPrecedenceParse; OperatorPrecedenceParseImpl: CEDAR PROGRAM EXPORTS OperatorPrecedenceParse = BEGIN OPEN OperatorPrecedenceParse; CantReduce: PUBLIC SIGNAL [ops: TokenList, args: ArgList] RETURNS [use: REF ANY] = CODE; CantFix: PUBLIC SIGNAL [token: Token] RETURNS [fix: Token] = CODE; DoesntFix: PUBLIC ERROR [token: Token, expectingArg, willGetArg: BOOLEAN] = CODE; TerminateErr: PUBLIC ERROR [argStack: ArgList, opStack: TokenList] = CODE; LastReduceErr: PUBLIC ERROR [args: ArgList, ops: TokenList] = CODE; InvalidToken: PUBLIC ERROR [token: Token] = CODE; endClass: TokenClass _ NEW [TokenClassRep _ [leftPrec: 1, rightPrec: 0]]; beginClass: TokenClass _ NEW [TokenClassRep _ [leftPrec: 0, rightPrec: 1, Reduce: ReduceEnd]]; argClass: PUBLIC TokenClass _ NEW [TokenClassRep _ [leftPrec: 0, rightPrec: 0]]; end: PUBLIC Token _ [class: endClass]; begin: Token _ [class: beginClass]; Parse: PUBLIC PROC [context: REF ANY, GetToken: TokenProc] RETURNS [ans: Arg] = BEGIN Reduce: PROC = BEGIN GrabArg: PROC = { sr _ Union[sr, argStack.first.sr]; args _ CONS[argStack.first, args]; argStack _ argStack.rest}; GrabOp: PROC = { sr _ Union[sr, opStack.first.sr]; ops _ CONS[opStack.first, ops]; opStack _ opStack.rest}; args: ArgList _ NIL; ops: TokenList _ NIL; new: REF ANY; sr: SourceRange _ nullSR; WHILE TRUE DO IF opStack.first.class.rightPrec > 0 THEN GrabArg[]; GrabOp[]; IF opStack = NIL THEN EXIT; IF opStack.first.class.rightPrec # ops.first.class.leftPrec THEN EXIT; ENDLOOP; IF ops.first.class.leftPrec > 0 THEN GrabArg[]; IF ops.first.class.Reduce # NIL THEN new _ ops.first.class.Reduce[sr, context, ops, args] ELSE new _ SIGNAL CantReduce[ops, args]; argStack _ CONS[[sr, new], argStack]; END; argStack: ArgList _ NIL; opStack: TokenList _ LIST[begin]; expectingArg: BOOLEAN _ TRUE; useOld: BOOLEAN _ FALSE; old: Token; WHILE opStack # NIL DO next: Token; IF useOld THEN {next _ old; useOld _ FALSE} ELSE next _ GetToken[context, expectingArg]; IF next.class = NIL THEN ERROR InvalidToken[next]; IF next.class.rightPrec = 1 THEN ERROR InvalidToken[next]; IF next.class.leftPrec = 1 AND next # end THEN ERROR InvalidToken[next]; IF expectingArg # (next.class.leftPrec = 0) THEN BEGIN old _ next; IF next.class.leftFix.class = NIL THEN next _ SIGNAL CantFix[next] ELSE next _ next.class.leftFix; IF expectingArg # (next.class.leftPrec = 0) THEN ERROR DoesntFix[next, expectingArg, old.class.leftPrec = 0]; IF (next.class.rightPrec > 0) # (old.class.leftPrec = 0) THEN ERROR DoesntFix[next, expectingArg, old.class.leftPrec = 0]; useOld _ TRUE; END; IF next.class.leftPrec > 0 THEN BEGIN WHILE opStack.first.class.rightPrec > next.class.leftPrec DO Reduce[] ENDLOOP; END; IF next.class.leftPrec = 0 AND next.class.rightPrec = 0 THEN argStack _ CONS[[next.sr, next.asArg], argStack] ELSE opStack _ CONS[next, opStack]; expectingArg _ next.class.rightPrec > 0; IF (next.class.leftPrec > 0) AND NOT expectingArg THEN Reduce[]; ENDLOOP; IF argStack = NIL THEN ERROR TerminateErr[argStack, opStack]; IF argStack.rest # NIL THEN ERROR TerminateErr[argStack, opStack]; ans _ argStack.first; END; Union: PROC [a, b: SourceRange] RETURNS [c: SourceRange] = BEGIN IF a = nullSR THEN RETURN [b]; IF b = nullSR THEN RETURN [a]; c.first _ MIN[a.first, b.first]; c.last _ MAX[a.last, b.last]; END; ReduceEnd: Reducer = BEGIN IF args = NIL THEN ERROR LastReduceErr[args, ops]; IF args.rest # NIL THEN ERROR LastReduceErr[args, ops]; IF ops = NIL THEN ERROR; IF ops.rest = NIL THEN ERROR LastReduceErr[args, ops]; IF ops.rest.rest # NIL THEN ERROR LastReduceErr[args, ops]; reduced _ args.first.arg; END; END. ^OperatorPrecedenceParseImpl.Mesa Last Edited by: Spreitzer, July 8, 1985 8:28:48 pm PDT Κ,˜Icode™ K™6K˜KšΟk œ˜"K˜šΠbxœœ˜*Kšœ˜!—K˜Kšœœ˜#K˜Kš œ œœ!œœœœ˜XK˜Kš œ œœœœ˜BK˜Kš œ œœ*œœ˜QK˜Kšœœœ+œ˜JK˜Kšœœœ#œ˜CK˜Kšœœœœ˜1K˜K˜Kšœœ/˜IKšœœB˜^Kšœ œœ/˜PK˜Kšœœ˜&Kšœ#˜#K˜K˜š Οnœœœ œœœ ˜OKš˜K˜šŸœœ˜Kš˜K˜šŸœœ˜Kšœ"˜"Kšœœ˜"Kšœ˜—K˜šŸœœ˜Kšœ!˜!Kšœœ˜Kšœ˜—K˜Kšœœ˜Kšœœ˜Kšœœœ˜ K˜šœœ˜ Kšœ#œ ˜4K˜ Kšœ œœœ˜Kšœ:œœ˜FKšœ˜—Kšœœ ˜/Kš œœœ6œœ˜‚Kšœ œ˜%Kšœ˜—K˜Kšœœ˜Kšœœ˜!Kšœœœ˜Kšœœœ˜K˜ K˜šœ œ˜Kšœ ˜ Kšœœœœ(˜XK˜Kšœœœœ˜2Kšœœœ˜:Kšœœ œœ˜HK˜šœ*˜0Kš˜K˜ Kš œœœœœ˜bKšœ*œœ7˜mKšœ7œœ7˜zKšœ œ˜Kšœ˜—šœ˜Kš˜Kšœ5œ œ˜NKšœ˜—Kš œœœ œ"œ œ˜‘Kšœ(˜(Kšœœœœ ˜@Kšœ˜—K˜Kšœ œœœ!˜=Kšœœœœ!˜BK˜Kšœ˜—K˜šŸœœœ˜:Kš˜Kšœ œœ˜Kšœ œœ˜Kšœ œ˜ Kšœ œ˜Kšœ˜—K˜šœ˜Kš˜Kšœœœœ˜2Kšœ œœœ˜7Kšœœœœ˜Kšœ œœœ˜6Kšœœœœ˜;K˜Kšœ˜—K˜Kšœ˜—…—@Κ