DIRECTORY TextLooks USING [Looks], RegularExpression USING [ParseTree, Code, CodeContent, PatternOpCodeArray, PatternDataArray, PatternNextArray, PatternLooksArray, IgnoreLooks, ParseTreeContent, OpCode, Index, MalformedPattern]; RegExpFindCompileImpl: CEDAR PROGRAM IMPORTS RegularExpression EXPORTS RegularExpression = { OPEN RegularExpression; Compile: PUBLIC PROC [p: ParseTree] RETURNS [code: Code] = { CompileIt: PROC [p: ParseTree, self, next: Index] = { WITH p SELECT FROM x: REF ParseTreeContent.concat => { FOR l: LIST OF ParseTree _ x.concats, l.rest UNTIL l = NIL DO IF l.rest = NIL THEN CompileIt[l.first, self, next] ELSE { middle: Index _ Alloc[]; CompileIt[l.first, self, middle]; self _ middle; }; ENDLOOP; }; x: REF ParseTreeContent.char => Set[self, IF x.looks = IgnoreLooks THEN matchChar ELSE matchCharLooks, x.looks, ORD[x.char], next]; x: REF ParseTreeContent.charIC => Set[self, IF x.looks = IgnoreLooks THEN matchCharIC ELSE matchCharLooksIC, x.looks, ORD[x.char], next]; x: REF ParseTreeContent.class => Set[self, IF x.looks = IgnoreLooks THEN matchClass ELSE matchClassLooks, x.looks, x.classNumber, next]; x: REF ParseTreeContent.anyChar => Set[self, IF x.looks = IgnoreLooks THEN matchAnyChar ELSE matchAnyCharLooks, x.looks, notUsed, next]; x: REF ParseTreeContent.nodeBreak => Set[self, matchNodeBreak, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.skipToNodeBreak => Set[self, IF x.looks = IgnoreLooks THEN skipToNodeBreak ELSE skipToNodeBreakLooks, x.looks, notUsed, next]; x: REF ParseTreeContent.beginNode => Set[self, matchBeginNode, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.fail => Set[self, fail, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.succeed => Set[self, succeed, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.noOp => Set[self, noOp, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.skipOverClass => Set[self, IF x.looks = IgnoreLooks THEN skipOverClass ELSE skipOverClassLooks, x.looks, x.classNumber, next]; x: REF ParseTreeContent.skipOverChar => Set[self, IF x.looks = IgnoreLooks THEN skipOverChar ELSE skipOverCharLooks, x.looks, ORD[x.char], next]; x: REF ParseTreeContent.skipOverCharIC => Set[self, IF x.looks = IgnoreLooks THEN skipOverCharIC ELSE skipOverCharLooksIC, x.looks, ORD[x.char], next]; x: REF ParseTreeContent.skipOver => -- ERROR RegularExpression.MalformedPattern[invalidNot,0]; ERROR RegularExpression.MalformedPattern[toobig]; x: REF ParseTreeContent.skipToChar => Set[self, IF x.looks = IgnoreLooks THEN skipToChar ELSE skipToCharLooks, x.looks, ORD[x.char], next]; x: REF ParseTreeContent.skipToCharIC => Set[self, IF x.looks = IgnoreLooks THEN skipToCharIC ELSE skipToCharLooksIC, x.looks, ORD[x.char], next]; x: REF ParseTreeContent.skipToString => { endOfStringInstructions: Index _ Alloc[]; stringInstructions: Index _ Alloc[]; Set[endOfStringInstructions, endOfSkipToString, IgnoreLooks, notUsed, next]; Set[self, skipToString, IgnoreLooks, notUsed, stringInstructions]; CompileIt[x.p, stringInstructions, endOfStringInstructions]; }; x: REF ParseTreeContent.skipTo => -- ERROR RegularExpression.MalformedPattern[invalidNot,0]; ERROR RegularExpression.MalformedPattern[toobig]; x: REF ParseTreeContent.skipToEnd => Set[self, skipToEnd, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.skipToBeginning => Set[self, skipToBeginning, IgnoreLooks, notUsed, next]; x: REF ParseTreeContent.closure => { body: Index _ Alloc[]; Set[self, closure, IgnoreLooks, body, next]; CompileIt[x.p, body, self]; }; x: REF ParseTreeContent.carefulClosure => { body: Index _ Alloc[]; bodyPlusOne: Index _ Alloc[]; check: Index _ Alloc[]; Set[self, carefulClosure, IgnoreLooks, body, next]; Set[check, carefulClosureEnd, IgnoreLooks, self, self]; CompileIt[x.p, body, check]; }; x: REF ParseTreeContent.greedyClosure => { body: Index _ Alloc[]; Set[self, greedyClosure, IgnoreLooks, next, body]; CompileIt[x.p, body, self]; }; x: REF ParseTreeContent.carefulGreedyClosure => { body: Index _ Alloc[]; bodyPlusOne: Index _ Alloc[]; check: Index _ Alloc[]; Set[self, carefulGreedyClosure, IgnoreLooks, next, body]; Set[check, carefulGreedyClosureEnd, IgnoreLooks, self, self]; CompileIt[x.p, body, check]; }; x: REF ParseTreeContent.alt => { FOR l: LIST OF ParseTree _ x.alts, l.rest UNTIL l = NIL DO IF l.rest = NIL THEN CompileIt[l.first, self, next] ELSE { instr: Index _ Alloc[]; nextAlt: Index _ Alloc[]; Set[self, alt, IgnoreLooks, nextAlt, instr]; CompileIt[l.first, instr, next]; self _ nextAlt; }; ENDLOOP; }; x: REF ParseTreeContent.field => { instr: Index _ Alloc[]; endInstr: Index _ Alloc[]; Set[self, fieldStart, IgnoreLooks, x.number, instr]; IF x.bound # -1 THEN { extraInstr: Index _ Alloc[]; Set[instr, boundNodeBreaks, IgnoreLooks, x.bound, extraInstr]; instr _ extraInstr; }; Set[endInstr, fieldEnd, IgnoreLooks, x.number, next]; CompileIt[x.p, instr, endInstr]; }; x: REF ParseTreeContent.fieldEquals => Set[self, fieldEquals, IgnoreLooks, x.number, next]; x: REF ParseTreeContent.fieldEqualsIC => Set[self, fieldEqualsIC, IgnoreLooks, x.number, next]; x: REF ParseTreeContent.beginALL => Set[self, fieldStart, IgnoreLooks, 0, next]; x: REF ParseTreeContent.endALL => Set[self, fieldEnd, IgnoreLooks, 0, next]; x: REF ParseTreeContent.beginAll => Set[self, beginAll, IgnoreLooks, 0, next]; x: REF ParseTreeContent.endAll => Set[self, endAll, IgnoreLooks, 0, next]; ENDCASE => ERROR; }; codePC: Index _ 0; codeSize: Index _ 0; StandardSizeIncrement: Index = 100; notUsed: NAT = 0; Alloc: PROC [] RETURNS [pc: Index] = { pc _ codePC; IF pc >= codeSize THEN { newCodeSize: INT _ codeSize*2 + StandardSizeIncrement; newCode: Code _ NEW[CodeContent _ [ NEW[PatternOpCodeArray[newCodeSize]], NEW[PatternLooksArray[newCodeSize]], NEW[PatternDataArray[newCodeSize]], NEW[PatternNextArray[newCodeSize]]]]; IF codeSize > 0 THEN FOR i: Index IN [0..pc) DO newCode.opCodes[i] _ code.opCodes[i]; newCode.looks[i] _ code.looks[i]; newCode.data[i] _ code.data[i]; newCode.next[i] _ code.next[i]; ENDLOOP; code _ newCode; codeSize _ newCodeSize; }; codePC _ codePC+1; }; Set: PROC [pc: Index, opCode: OpCode, looks: TextLooks.Looks, data: NAT, next: Index] = { code.opCodes[pc] _ opCode; code.looks[pc] _ looks; code.data[pc] _ data; code.next[pc] _ next; }; first: Index _ Alloc[]; CompileIt[p, first, 0]; }; }. °RegExpFindCompileImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Nix, December 21, 1983 6:02 pm Russ Atkinson (RRA) April 25, 1985 5:21:12 am PST Κ˜codešœ™Kšœ Οmœ1™˜>K˜K˜—Kšœ5˜5K˜ K˜—šœžœ ˜&Kšœ4˜4—šœžœ"˜(Kšœ6˜6—šœžœ˜#Kšœ,˜,—šœžœ˜!Kšœ*˜*—šœžœ˜#Kšœ*˜*—šœžœ˜!Kšœ(˜(—Kšžœžœ˜—K˜—K˜K˜Kšœ#˜#Kšœ žœ˜š œžœžœ˜&K˜ šžœžœ˜Kšœ žœ&˜6šœžœ˜#Kšžœ#˜&Kšžœ!˜$Kšžœ!˜$Kšžœ#˜&—šžœž˜šžœ žœ ž˜K˜%Kšœ!˜!Kšœ˜Kšœ˜Kšžœ˜——K˜Kšœ˜K˜—K˜K˜—š œžœ;žœ˜YK˜K˜K˜K˜K˜—K˜K˜K˜—K˜˜K˜——…—Ύˆ