DIRECTORY PGSConDefs: TYPE USING [ cpw, defaultMarker, maxCharCode, outbufLim, pssLim, rhsLim, tokenSize, aliases, eofMark, flags, nextAlias, numProd, numRules, ntEntries, prodInfo, sLim, sourceName, symInfo, symTab, tEntries, totalTokens, closewordstream, MakeArray, FreeArray, inword, openwordstream, outblock, outchar, outeol, outnum, outstring, outtime, OutToken, outword], PGSTypes: TYPE USING [ Column, ColumnRec, HashTab, HashTabRec, ItemRec, NTab, NTDefaultRec, NTDefaults, Renumber, StateData, StateDataRec, TabRec, TTab, VocabIndex], Rope: TYPE USING [ROPE]; PGSTab: PROGRAM IMPORTS PGSConDefs EXPORTS PGSConDefs = { OPEN PGSConDefs; linewidth, hashval, lastntstate, vocabspace, nlim, tlim: CARDINAL; offset: CARDINAL; hashtab: PGSTypes.HashTab; ttab: PGSTypes.TTab; ntab: PGSTypes.NTab; packedProdInfo: BOOL; statedata: PGSTypes.StateData; ntdefaults: PGSTypes.NTDefaults; column: PGSTypes.Column; renumber: PGSTypes.Renumber; vocabindex: PGSTypes.VocabIndex; scantab: ARRAY [40b..177b] OF CARDINAL; TabGen: PUBLIC PROC [prefix, suffix: PROC] RETURNS [success: BOOL_TRUE] = { Error: PROC [sel: CARDINAL] = { outstring["\nFAIL - "]; outstring[SELECT sel FROM 1 => "more than 255 terminal symbols", 2 => "more than 254 nonterminal symbols", 3 => "more than 2047 states or productions", 4 => "more than 15 symbols in a production right part", ENDCASE => "PGS error"]; outeol[1]; success _ FALSE}; IF eofMark > 255 THEN Error[1]; IF totalTokens-eofMark+1 > 255 THEN Error[2]; IF pssLim > 2047 THEN Error[3]; IF rhsLim > 15 THEN Error[4]; IF ~success THEN RETURN [success]; ntab _ LOOPHOLE[MakeArray[ntEntries, PGSTypes.TabRec.SIZE]]; ttab _ LOOPHOLE[MakeArray[tEntries, PGSTypes.TabRec.SIZE]]; packedProdInfo _ (numRules <= 255); statedata _ LOOPHOLE[MakeArray[sLim, PGSTypes.StateDataRec.SIZE]]; ntdefaults _ LOOPHOLE[MakeArray[totalTokens-eofMark+2, PGSTypes.NTDefaultRec.SIZE]]; column _ LOOPHOLE[MakeArray[ntEntries+1, PGSTypes.ColumnRec.SIZE]]; TableSetup[]; closewordstream[]; SquashNTab[]; outstring["\nParse Table Data\n"]; IF flags[printLALR] THEN {PrintNDef[]; TableOverlays[]}; vocabindex _ LOOPHOLE[MakeArray[eofMark+1, CARDINAL.SIZE]]; hashval _ 3*eofMark/2; hashval _ MIN[251, IF hashval MOD 2 = 0 THEN hashval+1 ELSE hashval]; hashtab _ LOOPHOLE[MakeArray[hashval+1, PGSTypes.HashTabRec.SIZE]]; HashTabSetup[]; openwordstream[scratch:FALSE]; IF prefix # NIL THEN prefix[]; offset _ 14; -- number of tables outword[offset]; offset _ offset + 96; outword[offset]; offset _ offset + (hashval+1); outword[offset]; offset _ offset + (eofMark+1); outword[offset]; offset _ offset + (2 + (vocabspace+cpw-1)/cpw); StatePartition[]; -- compute lastntstate outword[offset]; offset _ offset + (numProd+1)*(IF packedProdInfo THEN 1 ELSE 2); outword[offset]; offset _ offset + (lastntstate+1); outword[offset]; offset _ offset + (lastntstate+1); outword[offset]; offset _ offset + nlim; outword[offset]; offset _ offset + nlim; outword[offset]; offset _ offset + (totalTokens-eofMark+2); outword[offset]; offset _ offset + sLim; outword[offset]; offset _ offset + sLim; outword[offset]; offset _ offset + tlim; outword[offset]; outblock[scantab.BASE, 96]; outblock[hashtab.BASE, hashval+1]; outblock[vocabindex.BASE, eofMark+1]; outword[vocabspace]; outword[vocabspace]; outblock[symTab.BASE, (vocabspace+cpw-1)/cpw]; FreeArray[hashtab]; FreeArray[vocabindex]; FreeArray[symInfo]; renumber _ LOOPHOLE[MakeArray[sLim, CARDINAL.SIZE]]; StateRenumber[]; --now output parser tables OutArray[1,numProd, IF packedProdInfo THEN ProdDataItem1 ELSE ProdDataItem2]; OutArray[1,lastntstate, NStateItem]; OutArray[1,lastntstate, NLenItem]; OutArray[0,nlim-1, NSymItem]; OutArray[0,nlim-1, NActionItem]; OutArray[2,totalTokens-eofMark+1, NTDefaultItem]; OutArray[1,sLim-1, TStateItem]; OutArray[1,sLim-1, TLenItem]; OutArray[0,tlim-1, TSymItem]; OutArray[0,tlim-1, TActionItem]; FreeArray[prodInfo]; FreeArray[ntab]; FreeArray[ntdefaults]; FreeArray[renumber]; FreeArray[statedata]; FreeArray[ttab]; IF suffix # NIL THEN suffix[]}; TableSetup: PROC = { defaultitem, item: PGSTypes.ItemRec; defaultprod, i, j, k, symbol, ttix, ntix, six, index, ptr: CARDINAL; ColumnEntry: PROC = { j: INTEGER; lastptr: CARDINAL; lastptr _ 0; ptr _ ntdefaults[symbol].count; DO IF ptr=0 THEN GOTO insert; j _ item.jf-column[ptr].item.jf; IF j=0 THEN j _ item.pss-column[ptr].item.pss; IF j=0 THEN GOTO countup; IF j<0 THEN GOTO insert; lastptr _ ptr; ptr _ column[ptr].link; REPEAT countup => column[ptr].count _ column[ptr].count+1; insert => { column[index].item _ item; IF lastptr=0 THEN { --head of list for column "symbol" column[index].link _ ntdefaults[symbol].count; ntdefaults[symbol].count _ index} ELSE { column[index].link _ column[lastptr].link; column[lastptr].link _ index}; index _ index+1}; ENDLOOP}; ntix _ ttix _ 0; index _ 1; statedata[1] _ [0,0,0,0]; FOR six IN [1..sLim) DO defaultprod _ inword[]; statedata[six] _ [ttix,ntix,0,0]; THROUGH [1..inword[]] DO --set up entries for state six in ttab and ntab symbol _ inword[]; k _ inword[]; item _ [k MOD 4, k/4, inword[]]; IF item.tag=2 AND item.pss=defaultprod THEN defaultitem _ item ELSE IF symbol<=eofMark THEN {ttab[ttix] _ [symbol, item]; ttix _ ttix+1} ELSE { symbol _ symbol-eofMark+1; ntab[ntix] _ [symbol, item]; ntix _ ntix+1; ColumnEntry[]}; ENDLOOP; IF defaultprod # 0 THEN { ttab[ttix] _ [defaultMarker, defaultitem]; ttix _ ttix+1}; statedata[six].tLink _ ttix-statedata[six].tIndex; --length statedata[six].ntLink _ ntix-statedata[six].ntIndex; --length FOR i IN [1..six) DO k _ statedata[six].tIndex-statedata[i].tIndex; IF statedata[six].tLink=statedata[i].tLink THEN -- same length FOR j IN [statedata[i].tIndex..statedata[i].tIndex+statedata[i].tLink) DO IF ttab[j]#ttab[j+k] THEN EXIT; REPEAT FINISHED => { --there is a matching set of entries statedata[six].tLink _ -i; -- point state six at state i ttix _ statedata[six].tIndex; -- back up index EXIT}; ENDLOOP; ENDLOOP; ENDLOOP; tlim _ ttix; FOR symbol IN [0..totalTokens-eofMark+1] DO IF (ptr _ ntdefaults[symbol].count)=0 THEN LOOP; k _ 0; ntdefaults[symbol].item _ column[ptr].item; WHILE ptr#0 DO IF column[ptr].count>k THEN { k _ column[ptr].count; ntdefaults[symbol].item _ column[ptr].item}; ptr _ column[ptr].link; ENDLOOP; ntdefaults[symbol].count _ k; ENDLOOP}; SquashNTab: PROC = { i, j, k, six, ntix: CARDINAL; nlim _ 0; FOR six IN [1..sLim) DO k _ nlim; FOR ntix IN [statedata[six].ntIndex..statedata[six].ntIndex+statedata[six].ntLink) DO IF ntab[ntix].item # ntdefaults[ntab[ntix].symbol].item THEN { ntab[nlim] _ ntab[ntix]; nlim _ nlim+1}; ENDLOOP; statedata[six].ntIndex _ k; k _ nlim-k; statedata[six].ntLink _ k; IF k#0 THEN FOR i IN [1..six) DO --do these entries match those of an existing state k _ statedata[six].ntIndex-statedata[i].ntIndex; IF statedata[six].ntLink=statedata[i].ntLink THEN -- same length FOR j IN [statedata[i].ntIndex..statedata[i].ntIndex+statedata[i].ntLink) DO IF ntab[j]#ntab[j+k] THEN EXIT; REPEAT FINISHED => { --there is a matching set of entries statedata[six].ntLink _ -i; -- point state six at state i nlim _ statedata[six].ntIndex; -- back up index EXIT}; ENDLOOP; ENDLOOP; ENDLOOP}; PrintNDef: PROC = { j: CARDINAL; item: PGSTypes.ItemRec; outstring["\nNonterminal Default Actions\n"]; linewidth _ 0; j _ 0; FOR i: CARDINAL IN [2..totalTokens-eofMark+1] DO IF (linewidth _ linewidth+tokenSize+8)>outbufLim THEN { outeol[1]; linewidth _ tokenSize+8}; item _ ntdefaults[i].item; j _ j+ntdefaults[i].count; outnum[IF item.tag=0 THEN item.pss ELSE -item.pss, 5]; outchar[' ,1]; outchar[' , tokenSize+2-OutToken[i+eofMark-1]]; ENDLOOP; outstring["\nEntries removed = "]; outnum[j,5]; outeol[1]}; TableOverlays: PROC = { j, k: INTEGER; outstring["\nTable Overlays\n row ttab ntab\n"]; FOR i: CARDINAL IN [1..sLim) DO j _ statedata[i].tLink; k _ statedata[i].ntLink; IF j<0 OR k<0 THEN { outnum[i,4]; IF j<0 THEN outnum[-j, 5] ELSE outchar[' ,5]; IF k<0 THEN outnum[-k, 5]; outeol[1]}; ENDLOOP}; HashTabSetup: PROC = { i, j, k, h, p, count, freeptr, code: CARDINAL; null: CHAR = '\000; outstring["\nScanner hashtable probe counts (terminal symbol, probecount, hashcode)\n"]; vocabspace _ vocabindex[0] _ 0; freeptr _ hashval; linewidth _ 0; scantab _ ALL[0]; FOR i IN [1..eofMark] DO -- strip quotes, Repack, build vocabindex, scantab and hashtab p _ i*tokenSize; k _ symInfo[i].length; IF k=2 AND symTab[p]='' THEN {p _ p+1; k _ 1} ELSE IF k>2 AND symTab[p]='" AND symTab[p+k-1]='" THEN {p_p+1; k_k-2}; IF k=1 AND ~(symTab[p] IN ['a..'z] OR symTab[p] IN ['A..'Z]) THEN { scantab[CARDINAL[symTab[p]-null]] _ i; symTab[vocabspace] _ symTab[p]; vocabspace _ vocabspace+1; vocabindex[i] _ vocabspace} ELSE { FOR j IN [0..k) DO symTab[vocabspace] _ symTab[p+j]; vocabspace _ vocabspace+1; ENDLOOP; vocabindex[i] _ vocabspace; IF i=eofMark THEN LOOP; count _ 1; code _ h _ (((symTab[p]-null)*127+(symTab[p+k-1]-null)) MOD hashval) + 1; IF hashtab[h].symPtr#0 THEN { WHILE h#0 DO j _ h; h _ hashtab[h].link; count _ count+1 ENDLOOP; WHILE hashtab[freeptr].symPtr#0 DO freeptr _ freeptr-1 ENDLOOP; hashtab[j].link _ h _ freeptr}; hashtab[h].symPtr _ i; IF (linewidth _ linewidth+tokenSize+8)>outbufLim THEN { outeol[1]; linewidth _ tokenSize+8}; FOR j IN [vocabindex[i-1]..vocabindex[i]) DO outchar[symTab[j],1] ENDLOOP; outchar[' ,tokenSize-k]; outnum[count,2]; outnum[code,4]; outchar[' ,2]}; ENDLOOP; IF (j _ vocabspace MOD cpw)#0 THEN -- pad to word boundary THROUGH [j..cpw) DO symTab[vocabspace] _ null ENDLOOP; outeol[1]}; StatePartition: PROC = { i, j: CARDINAL; i_2; j_sLim-1; DO WHILE statedata[j].ntLink=0 AND i<=j DO j_j-1 ENDLOOP; -- j indexes an ntstate WHILE statedata[i].ntLink#0 AND i=j IF i>=j THEN EXIT ELSE {i_i+1; j_j-1}; -- simulate renumbering ENDLOOP; lastntstate_j}; StateRenumber: PROC = { i, j: CARDINAL; k: INTEGER; swaprec: PGSTypes.StateDataRec; i_2; j_sLim-1; DO WHILE statedata[j].ntLink=0 AND i<=j DO j_j-1 ENDLOOP; -- j indexes an ntstate WHILE statedata[i].ntLink#0 AND i=j IF i>=j THEN EXIT ELSE {renumber[i]_j; renumber[j]_i; i_i+1; j_j-1}; ENDLOOP; IF lastntstate # j THEN ERROR; FOR i IN [0..tlim) DO IF ttab[i].item.tag=0 AND (j_renumber[ttab[i].item.pss])#0 THEN ttab[i].item.pss_j; ENDLOOP; FOR i IN [0..nlim) DO IF ntab[i].item.tag=0 AND (j_renumber[ntab[i].item.pss])#0 THEN ntab[i].item.pss_j; ENDLOOP; FOR i IN [2..totalTokens-eofMark+1] DO IF ntdefaults[i].item.tag=0 AND (j_renumber[ntdefaults[i].item.pss])#0 THEN ntdefaults[i].item.pss_j; ENDLOOP; FOR i IN [1..sLim) DO k _ statedata[i].tLink; IF k<0 THEN { statedata[i].tLink _ statedata[-k].tLink; statedata[i].tIndex _ statedata[-k].tIndex}; k _ statedata[i].ntLink; IF k<0 THEN { statedata[i].ntLink _ statedata[-k].ntLink; statedata[i].ntIndex _ statedata[-k].ntIndex}; ENDLOOP; FOR i IN [2..lastntstate] DO IF (j_renumber[i])#0 THEN { swaprec _ statedata[i]; statedata[i] _ statedata[j]; statedata[j] _ swaprec}; ENDLOOP; IF flags[printLALR] THEN { outstring["\nRenumbered States\n"]; FOR i IN [2..lastntstate] DO IF renumber[i]#0 THEN { outnum[i,4]; outstring[" swapped with"]; outnum[renumber[i],4]; outeol[1]}; ENDLOOP}}; OutModule: PUBLIC PROC [typename, modfname: Rope.ROPE, long: BOOL] = { i,j,k: CARDINAL; OutRange: PROC [id, cover: Rope.ROPE, ulim: CARDINAL] = { outchar[' ,2]; outstring[id]; outstring[": TYPE = "]; outstring[cover]; outstring["[0.."]; outnum[ulim,3]; outstring["];\n"]}; OutArray: PROC [id, index, range: Rope.ROPE] = { outchar[' ,2]; outstring[id]; outstring[": TYPE = ARRAY "]; outstring[index]; outstring[" OF "]; outstring[range]; outchar[';,1]; outeol[1]}; OutRefType: PROC [referent: Rope.ROPE, base: BOOL _ FALSE] = { outchar[' ,2]; outstring[referent]; outstring["Ref: TYPE = "]; IF long THEN outstring["LONG "]; IF base THEN outstring["BASE "]; outstring["POINTER TO "]; outstring[referent]; outchar[';,1]; outeol[1]}; outstring["-- file "]; outstring[modfname]; outstring["\n-- created by PGS from "]; outstring[sourceName]; outstring[", "]; outtime[]; outeol[2]; outstring[typename]; outstring[": DEFINITIONS = {\n\n"]; OutRange["Symbol","",maxCharCode]; OutRange["TSymbol","Symbol",eofMark]; OutRange["NTSymbol","Symbol",totalTokens-eofMark+1]; outstring["\n-- token indices for the scanner and parser\n"]; FOR i IN [0..nextAlias) DO outchar[' ,2]; k _ aliases[i].alias*tokenSize; FOR j IN [k..k+tokenSize) WHILE symTab[j]#0c DO outchar[symTab[j],1] ENDLOOP; outstring[": TSymbol ="]; outnum[aliases[i].terminal,3]; outchar[';,1]; outeol[1]; ENDLOOP; FreeArray[LOOPHOLE[symTab]]; FreeArray[aliases]; outstring["\n default"]; outstring["Marker: TSymbol = TSymbol"]; outstring[".FIRST;\n"]; outstring[" end"]; outstring["Marker: TSymbol = TSymbol"]; outstring[".LAST;\n\n"]; OutRange["HashIndex","",hashval]; OutRange["VIndex","",vocabspace-1]; outstring[" VocabHashEntry: TYPE = MACHINE DEPENDENT RECORD [ symbol(0: 0..7): TSymbol, -- symbol index link(0: 8..15): HashIndex]; -- link to next entry\n\n"]; OutRange["State","",sLim-1]; OutRange["NTState","State",lastntstate]; OutRange["TIndex","",tlim-1]; OutRange["NTIndex","",nlim-1]; OutRange["Production","",numProd]; outstring[" ActionTag: TYPE = MACHINE DEPENDENT RECORD [ reduce(0: 0..0): BOOL, -- TRUE iff reduce entry pLength(0: 1..4): [0..15]]; -- number of symbols in production rhs ActionEntry: TYPE = MACHINE DEPENDENT RECORD [ tag(0: 0..4): ActionTag, -- [FALSE,0] if a shift entry transition(0: 5..15): [0..2047]]; -- production number / next state"]; IF packedProdInfo THEN outstring[" ProductionInfo: TYPE = MACHINE DEPENDENT RECORD [ rule(0: 0..7): [0..256), -- reduction rule lhs(0: 8..15): NTSymbol]; -- production lhs symbol\n\n"] ELSE outstring[" ProductionInfo: TYPE = MACHINE DEPENDENT RECORD [ rule(0): CARDINAL, -- reduction rule lhs(1): Symbol]; -- production lhs symbol (NTSymbol)\n\n"]; OutArray["ScanTable","CHAR['\\040..'\\177]","TSymbol"]; OutArray["HashTable","HashIndex","VocabHashEntry"]; OutArray["IndexTable","TSymbol","CARDINAL"]; outstring[" Vocabulary: TYPE = MACHINE DEPENDENT RECORD [\n"]; outstring[" length(0), maxlength(1): CARDINAL,\n"]; outstring[" text(2): PACKED ARRAY VIndex OF CHAR];\n"]; OutArray["ProdData","Production","ProductionInfo"]; OutArray["NStarts","NTState","NTIndex"]; OutArray["NLengths","NTState","CARDINAL"]; OutArray["NSymbols","NTIndex","NTSymbol"]; OutArray["NActions","NTIndex","ActionEntry"]; OutArray["NTDefaults","NTSymbol","ActionEntry"]; OutArray["TStarts","State","TIndex"]; OutArray["TLengths","State","CARDINAL"]; OutArray["TSymbols","TIndex","TSymbol"]; OutArray["TActions","TIndex","ActionEntry"]; outeol[1]; outstring[" initial"]; outstring["State: State = "]; outnum[1,1]; outchar[';,1]; outeol[1]; outstring[" final"]; outstring["State: State = "]; outnum[0,1]; outchar[';,1]; outeol[1]; outstring[" Table: TYPE = MACHINE DEPENDENT RECORD [ scanTable: RECORD [ scanTab: TableRef RELATIVE POINTER TO ScanTable, hashTab: TableRef RELATIVE POINTER TO HashTable, vocabIndex: TableRef RELATIVE POINTER TO IndexTable, vocabBody: TableRef RELATIVE POINTER TO Vocabulary], parseTable: RECORD [ prodData: TableRef RELATIVE POINTER TO ProdData, nStart: TableRef RELATIVE POINTER TO NStarts, nLength: TableRef RELATIVE POINTER TO NLengths, nSymbol: TableRef RELATIVE POINTER TO NSymbols, nAction: TableRef RELATIVE POINTER TO NActions, ntDefaults: TableRef RELATIVE POINTER TO NTDefaults, tStart: TableRef RELATIVE POINTER TO TStarts, tLength: TableRef RELATIVE POINTER TO TLengths, tSymbol: TableRef RELATIVE POINTER TO TSymbols, tAction: TableRef RELATIVE POINTER TO TActions]];\n\n"]; OutRefType["Table", TRUE]; OutRefType["ScanTable"]; OutRefType["HashTable"]; OutRefType["IndexTable"]; OutRefType["Vocabulary"]; OutRefType["ProdData"]; OutRefType["NStarts"]; OutRefType["NLengths"]; OutRefType["NSymbols"]; OutRefType["NActions"]; OutRefType["NTDefaults"]; OutRefType["TStarts"]; OutRefType["TLengths"]; OutRefType["TSymbols"]; OutRefType["TActions"]; outstring["\n }.\n"]}; IProc: TYPE = PROC [index: CARDINAL]; OutArray: PROC [llim, ulim: CARDINAL, p: IProc] = { THROUGH [0..llim) DO outword[0] ENDLOOP; FOR i: CARDINAL IN [llim..ulim] DO p[i] ENDLOOP}; ProdDataItem1: IProc = { outword[prodInfo[index].rule*256+(prodInfo[index].lhs-eofMark+1)]}; ProdDataItem2: IProc = { outword[prodInfo[index].rule]; outword[prodInfo[index].lhs-eofMark+1]}; NStateItem: IProc = {outword[statedata[index].ntIndex]}; NLenItem: IProc = {outword[statedata[index].ntLink]}; NSymItem: IProc = {outword[ntab[index].symbol]}; NActionItem: IProc = {Repack[ntab[index].item]}; NTDefaultItem: IProc = {Repack[ntdefaults[index].item]}; TStateItem: IProc = {outword[statedata[index].tIndex]}; TLenItem: IProc = {outword[statedata[index].tLink]}; TSymItem: IProc = {outword[ttab[index].symbol]}; TActionItem: IProc = {Repack[ttab[index].item]}; Repack: PROC [item: PGSTypes.ItemRec] = { SELECT item.tag FROM 0 => outword[item.pss]; 1 => outword[item.jf*2048+item.pss]; 2 => outword[(16+item.jf)*2048+item.pss]; ENDCASE}; }. Xfile PGSTab.mesa last modified by Satterthwaite, January 7, 1983 12:27 pm Last Edited by: Maxwell, August 10, 1983 10:39 am start output file output scanner table relative offsets (see table output below) output parser table relative offsets (see table output below) output scanner tables now see if these terminal entries match those of an existing state ttab contains terminal entries; statedata[i].tindex indexes state i entries if statedata[i].link>0, otherwise statedata[-statedata[i].link].tindex indexes them. the following code leaves the most frequently occurring item in column "symbol" of the lalr tables in the appropriate entry of ntdefaults the next two statements are redundant, they keep the new tables identical to the old if jJ˜J—šœ œœ˜J˜PJ˜=—Jšœœœœ˜J˜—šœ˜Jšœ ˜Jšœ˜—Jšœ ˜J˜Jšœ9œ˜BJšœœ˜J˜J˜J˜Jšœœ˜J˜J˜ J˜J˜J˜ Jšœ œ œœ˜'J˜JšÏnœœœœœ œœ˜K˜šžœœœ˜J˜šœ œ˜J˜&J˜)J˜,J˜7Jšœ˜—Jšœœ˜J˜—Jšœœ ˜Jšœœ ˜-Jšœœ ˜Jšœ œ ˜Jšœ œœ ˜"J˜Jšœœ&œ˜™>Jšœ Ïc˜ J˜&J˜/J˜/J˜@J˜—šœ=™=JšœŸ˜)Jšœ0œœœ˜QJ˜3J˜3J˜(J˜(J˜;J˜(J˜(J˜(J˜J˜—šœ™Jšœœ˜Jšœœ ˜"Jšœœ ˜%J˜)Jšœœ˜.J˜J˜*J˜J˜Jšœ œœœ˜4JšœŸ˜+Jšœœœœ˜MJ˜$J˜"J˜J˜ J˜1J˜J˜J˜J˜ J˜J˜%J˜+J˜&J˜Jšœ œœ ˜J˜J˜—šž œœ˜J˜$Jšœ;œ˜DJ˜šž œœ˜Jšœœ œ˜J˜-š˜Jšœœœ˜Jšœ!œœ#˜OJšœœœ ˜Jšœœœ˜J˜&Jš˜J˜3˜ J˜šœ œŸ"˜6J˜.J˜!—šœ˜J˜*J˜—J˜—Jšœ˜ J˜——J˜5šœœ ˜J˜9šœœŸ/˜IJ˜ Jšœ œ˜ šœ œœ˜CJšœœ-˜Dšœ˜J˜FJ˜——Jšœ˜—šœœ˜J˜:—Jšœ3Ÿ˜;Jšœ5Ÿ˜=JšœB™Bšœœ ˜J˜.šœ)œŸ˜?šœœ?˜IJšœœœ˜šœœŸ$˜9JšœŸ˜8JšœŸ˜.Jšœ˜—Jšœ˜——Jšœ˜—Jšœ˜—J˜ JšœN™NJšœQ™QJ˜JšœO™OJšœ9™9šœœ˜+Jšœ$œœ˜0J˜2šœ˜šœœ˜J˜C—J˜Jšœ˜—J˜Jšœ˜ J˜——šž œœ˜Jšœœ˜J˜ šœœ ˜J˜ šœœH˜Ušœ6œ˜>J˜(—Jšœ˜—J˜Bš œœœœ œŸ3˜TJ˜0šœ+œŸ˜AšœœB˜LJšœœœ˜šœœŸ$˜9JšœŸ˜9JšœŸ˜/Jšœ˜—Jšœ˜——Jšœ˜—Jšœ˜ J˜J˜——šž œœ˜Jšœœ˜$J˜Cšœœœ˜0šœ/œ˜7J˜$—J˜5Jšœœ œ œ˜EJ˜/Jšœ˜—J˜;J˜—šž œœ˜Jšœœ˜J˜0šœœœ ˜J˜0šœœœ˜J˜ Jšœœœ˜-Jšœœ˜J˜ —Jšœ˜ J˜——šž œœ˜Jšœ%œ˜.Jšœœ ˜J˜XJ˜AJšœ œ˜šœœœŸ>˜WJ˜'Jšœœœ˜-Jš œœœœœ˜Fš œœ œ œ œ œ˜CJšœœ˜&———šœT™TJ˜:J˜šœ˜šœœ˜J˜J˜>Jšœœ˜ Jšœœ˜ J˜.J˜J˜—J˜,J˜>J˜(J˜J˜8J˜J˜"J˜%J˜4J˜J˜=šœœ˜J˜.Jš œœœœœ˜NJ˜RJšœ˜—Jšœ œ˜0J˜˜J˜?—˜J˜@J˜—J˜EJ˜ š œœœ œœ˜1JšœŸ˜)JšœŸœŸ˜8J˜—J˜J˜(J˜J˜J˜"J˜J˜ š œ œœ œœ˜,JšœœŸ˜2JšœŸ&˜B—š œ œœ œœ˜.JšœŸ˜7Jšœ"Ÿ!œŸ˜FJ˜—Jšœœ ˜"J˜š œœœ œœ˜1JšœŸ˜+JšœŸœ˜8J˜—Jšœ ˜J˜š œœœ œœ˜1Jšœ œŸ˜$JšœŸ'œŸ˜