-- SyntaxDescReadersImpl.mesa -- last edit March 28, 1985 9:09:56 am PST DIRECTORY Basics USING[LowHalf], Convert USING[CardFromRope], IO USING[STREAM, CharClass, Close, EndOf, EndOfStream, GetCedarTokenRope, GetLineRope, GetTokenRope, RIS, SP], Rope USING[ROPE, Equal, Length], SyntaxDescReaders USING[]; SyntaxDescReadersImpl: CEDAR PROGRAM IMPORTS Basics, Convert, IO, Rope EXPORTS SyntaxDescReaders = BEGIN OPEN Basics, Convert, IO, Rope; GenSimpleTermsFromStream: PUBLIC PROC[stream: STREAM, showTerm: PROC[name: ROPE, spelling: ROPE]] = BEGIN token: ROPE; skipped: INT; BlankSepr: PROC[char: CHAR] RETURNS[CharClass] = {RETURN[IF char = SP THEN sepr ELSE other]}; WHILE NOT EndOf[stream] DO [token, skipped] _ GetTokenRope[stream, BlankSepr]; showTerm[token, token]; ENDLOOP; END; GenSpelledTermsFromStream: PUBLIC PROC[stream: STREAM, showTerm: PROC[name: ROPE, spelling: ROPE]] = BEGIN token: ROPE; skipped1: INT; spelling: ROPE; skipped2: INT; BlankSepr: PROC[char: CHAR] RETURNS[CharClass] = {RETURN[IF char = SP THEN sepr ELSE other]}; WHILE NOT EndOf[stream] DO [token, skipped1] _ GetTokenRope[stream, BlankSepr]; [spelling, skipped2] _ GetTokenRope[stream, BlankSepr]; showTerm[token, spelling]; ENDLOOP; END; GenGenericTermsFromStream: PUBLIC PROC[stream: STREAM, showTerm: PROC[name: ROPE, class: ROPE]] = BEGIN token: ROPE; skipped1: INT; class: ROPE; skipped2: INT; BlankSepr: PROC[char: CHAR] RETURNS[CharClass] = {RETURN[IF char = SP THEN sepr ELSE other]}; WHILE NOT EndOf[stream] DO [token, skipped1] _ GetTokenRope[stream, BlankSepr]; [class, skipped2] _ GetTokenRope[stream, BlankSepr]; showTerm[token, class]; ENDLOOP; END; GenNonTermsFromStream: PUBLIC PROC[stream: STREAM, showNonTerm: PROC[ROPE]] = BEGIN token: ROPE; skipped: INT; BlankSepr: PROC[char: CHAR] RETURNS[CharClass] = {RETURN[IF char = SP THEN sepr ELSE other]}; WHILE NOT EndOf[stream] DO [token, skipped] _ GetTokenRope[stream, BlankSepr]; showNonTerm[token]; ENDLOOP; END; OneProductionFromStream: PUBLIC PROC[productionIndex: CARDINAL, stream: STREAM, leftSymbol: PROC[CARDINAL, ROPE], rightSymbol: PROC[ROPE]] = BEGIN token: ROPE; skipped: INT; BlankSepr: PROC[char: CHAR] RETURNS[CharClass] = {RETURN[IF char = SP THEN sepr ELSE other]}; [token, skipped] _ GetTokenRope[stream, BlankSepr]; leftSymbol[productionIndex, token]; [token, skipped] _ GetTokenRope[stream, BlankSepr]; IF NOT Equal[token, "_"] THEN ERROR; WHILE NOT EndOf[stream] DO [token, skipped] _ GetTokenRope[stream, BlankSepr]; rightSymbol[token]; ENDLOOP; END; GenSimpleTermsFromRope: PUBLIC PROC[rope: ROPE, showTerm: PROC[name: ROPE, spelling: ROPE]] = BEGIN -- uses default IO.TokenProc s: STREAM _ RIS[rope]; GenSimpleTermsFromStream[s, showTerm]; Close[s]; END; GenSpelledTermsFromRope: PUBLIC PROC[rope: ROPE, showTerm: PROC[name: ROPE, spelling: ROPE]] = BEGIN -- uses default IO.TokenProc s: STREAM _ RIS[rope]; GenSpelledTermsFromStream[s, showTerm]; Close[s]; END; GenGenericTermsFromRope: PUBLIC PROC[rope: ROPE, showTerm: PROC[name: ROPE, class: ROPE]] = BEGIN -- uses default IO.TokenProc s: STREAM _ RIS[rope]; GenGenericTermsFromStream[s, showTerm]; Close[s]; END; GenNonTermsFromRope: PUBLIC PROC[rope: ROPE, showNonTerm: PROC[name: ROPE]] = BEGIN -- uses default IO.TokenProc s: STREAM _ RIS[rope]; GenNonTermsFromStream[s, showNonTerm]; Close[s]; END; OneProductionFromRope: PUBLIC PROC[productionIndex: CARDINAL, rope: ROPE, leftSymbol: PROC[CARDINAL, ROPE], rightSymbol: PROC[ROPE]] = BEGIN -- uses default IO.TokenProc s: STREAM _ RIS[rope]; OneProductionFromStream[productionIndex, s, leftSymbol, rightSymbol]; Close[s]; END; PGSFormat: PUBLIC PROC[stream: STREAM, ut: PROC[ROPE, ROPE], gt: PROC[ROPE, ROPE], n: PROC[ROPE], l: PROC[CARDINAL, ROPE], r: PROC[ROPE]] = BEGIN BlankSepr: PROC[char: CHAR] RETURNS[CharClass] = {RETURN[IF char = SP THEN sepr ELSE other]}; -- scan for table 1 WHILE TRUE DO line: ROPE _ GetLineRope[stream]; lineStream: STREAM; key: ROPE; IF Length[line] = 0 THEN LOOP; lineStream _ RIS[line]; key _ GetTokenRope[lineStream, BlankSepr].token; Close[lineStream]; IF Equal[key, "||TABLE1"] THEN EXIT; ENDLOOP; -- process table 1 which contains the terminals, note that certain are treated special WHILE TRUE DO line: ROPE _ GetLineRope[stream]; lineStream: STREAM; toss: ROPE; terminal: ROPE; IF Length[line] = 0 THEN LOOP; lineStream _ RIS[line]; toss _ GetTokenRope[lineStream, BlankSepr].token; IF Equal[toss, "||TABLE2"] THEN {Close[lineStream]; EXIT}; terminal _ GetTokenRope[lineStream, BlankSepr].token; Close[lineStream]; SELECT TRUE FROM Equal["id", terminal] => gt["id", "tokenID"]; Equal["num", terminal] => gt["num", "tokenDECIMAL"]; Equal["lnum", terminal] => gt["lnum", "tokenDECIMAL"]; Equal["flnum", terminal] => gt["flnum", "tokenREAL"]; Equal["string", terminal] => gt["string", "tokenROPE"]; Equal["lstring", terminal] => gt["lstring", "tokenROPE"]; Equal["char", terminal] => gt["char", "tokenCHAR"]; Equal["atom", terminal] => gt["atom", "tokenATOM"]; Equal["eof", terminal] => NULL; Equal["'|", terminal] => ut["'|", "|"]; ENDCASE => ut[terminal, terminal]; ENDLOOP; -- process table 2 which contains the non terminals n["AugmentingGOAL"]; -- our special introduced goal to make it an augmented grammar WHILE TRUE DO line: ROPE _ GetLineRope[stream]; lineStream: STREAM; toss: ROPE; terminal: ROPE; IF Length[line] = 0 THEN LOOP; lineStream _ RIS[line]; toss _ GetTokenRope[lineStream, BlankSepr].token; IF Equal[toss, "||TABLE3"] THEN {Close[lineStream]; EXIT}; terminal _ GetTokenRope[lineStream, BlankSepr].token; Close[lineStream]; n[terminal]; ENDLOOP; -- ignore table 3 which contains some info about certain terminals WHILE TRUE DO line: ROPE _ GetLineRope[stream]; lineStream: STREAM; toss: ROPE; IF Length[line] = 0 THEN LOOP; lineStream _ RIS[line]; toss _ GetTokenRope[lineStream, BlankSepr].token; IF Equal[toss, "||TABLE4"] THEN {Close[lineStream]; EXIT}; Close[lineStream]; ENDLOOP; -- process table 4 which contains the productions BEGIN firstProduction: BOOLEAN _ TRUE; leftSide: ROPE; WHILE TRUE DO line: ROPE; lineStream: STREAM; prodNumber: ROPE; reductionNumber: ROPE; operator: ROPE; line _ GetLineRope[stream ! EndOfStream => {EXIT}]; IF Length[line] = 0 THEN LOOP; lineStream _ RIS[line]; prodNumber _ GetTokenRope[lineStream, BlankSepr].token; reductionNumber _ GetTokenRope[lineStream, BlankSepr].token; IF Equal[reductionNumber, "C"] THEN reductionNumber _ GetTokenRope[lineStream, BlankSepr].token; -- the C indicates a chain rule operator _ GetTokenRope[lineStream, BlankSepr].token; IF NOT Equal[operator, "|"] THEN BEGIN leftSide _ operator; operator _ GetTokenRope[lineStream, BlankSepr].token; IF NOT Equal[operator, "::="] THEN ERROR; END; IF firstProduction THEN BEGIN -- introduce our dummy production firstProduction _ FALSE; l[0, "AugmentingGOAL"]; r[leftSide]; END; l[LowHalf[CardFromRope[prodNumber]], leftSide]; WHILE TRUE DO token: ROPE _ GetTokenRope[lineStream, BlankSepr ! EndOfStream => {token _ NIL; EXIT}].token; r[token]; ENDLOOP; Close[lineStream]; ENDLOOP; END; END; -- Rec Function definition format RecFcnDefFormat1Stream: PUBLIC PROC[stream: STREAM, ut: PROC[ROPE, ROPE], gt: PROC[ROPE, ROPE], n: PROC[ROPE], l: PROC[CARDINAL, ROPE], r: PROC[ROPE]] = BEGIN token: Rope.ROPE; token _ GetCedarTokenRope[stream].token; IF NOT Equal[token, "RecFcnDefFormat1"] THEN ERROR; DO token _ GetCedarTokenRope[stream].token; SELECT TRUE FROM Equal[token, "SimpleTerminals"] => BEGIN IF NOT Equal[GetCedarTokenRope[stream].token, ":"] THEN ERROR; DO token _ GetCedarTokenRope[stream].token; IF Equal[token, ";"] THEN EXIT; ut[token, token]; ENDLOOP; END; Equal[token, "SpelledTerminals"] => BEGIN IF NOT Equal[GetCedarTokenRope[stream].token, ":"] THEN ERROR; DO token2: ROPE; token _ GetCedarTokenRope[stream].token; IF Equal[token, ";"] THEN EXIT; token2 _ GetCedarTokenRope[stream].token; ut[token, token2]; ENDLOOP; END; Equal[token, "GenericTerminals"] => BEGIN IF NOT Equal[GetCedarTokenRope[stream].token, ":"] THEN ERROR; DO case: ROPE; token _ GetCedarTokenRope[stream].token; IF Equal[token, ";"] THEN EXIT; case _ GetCedarTokenRope[stream].token; IF Equal[token, ";"] THEN ERROR; gt[token, case]; ENDLOOP; END; Equal[token, "NonTerminals"] => BEGIN IF NOT Equal[GetCedarTokenRope[stream].token, ":"] THEN ERROR; DO token _ GetCedarTokenRope[stream].token; IF Equal[token, ";"] THEN EXIT; n[token]; ENDLOOP; END; Equal[token, "Prod"] => EXIT; ENDCASE => ERROR; ENDLOOP; DO index: CARDINAL; left: ROPE; IF NOT Equal[token, "Prod"] THEN ERROR; index _ CardFromRope[GetCedarTokenRope[stream].token]; IF NOT Equal[GetCedarTokenRope[stream].token, ":"] THEN ERROR; left _ GetCedarTokenRope[stream].token; l[index, left]; IF NOT Equal[GetCedarTokenRope[stream].token, "_"] THEN ERROR; DO right: ROPE; right _ GetCedarTokenRope[stream].token; IF Equal[right, ";"] THEN EXIT; r[right]; ENDLOOP; token _ GetCedarTokenRope[stream].token; IF Equal[token, "EndOfSyntax"] THEN EXIT; ENDLOOP; END; END.. -- RTE: November 1, 1984 11:16:17 am PST: ran into a grammar with start symbol = GOAL, which confilicted with our augmenting start symbol GOAL. So, change to AugmentingGOAL. Êu˜Jšœ˜J˜.J˜˜ Jšœ˜Jšœ˜Jšœn˜nJšœ ˜ Jšœ˜—J˜J˜Jšœb˜b˜Jšœ%˜%J˜˜cJšœ˜J˜J˜˜1J˜,J˜—˜J˜3J˜J˜—J˜—J˜˜dJšœ˜J˜J˜J˜˜1J˜,J˜—˜J˜4J˜7J˜J˜—J˜—J˜˜aJšœ˜J˜J˜J˜˜1J˜,J˜—˜J˜4J˜4J˜J˜—J˜—J˜˜MJšœ˜J˜J˜˜1J˜,J˜—˜J˜3J˜J˜—J˜—J˜J˜˜ŒJšœ˜J˜J˜˜1J˜,J˜—J˜WJ˜X˜J˜3J˜J˜—J˜—J˜˜]Jšœ"˜"J˜J˜&J˜ J˜J˜—˜^Jšœ"˜"J˜J˜'J˜ ˜J˜——˜[Jšœ"˜"J˜J˜'J˜ ˜J˜——šœM˜MJšœ"˜"J˜J˜&J˜ ˜J˜——˜†Jšœ"˜"J˜J˜EJ˜ J˜J˜—šœ‹˜‹J˜J˜˜1J˜,J˜—J˜˜ J˜!J˜J˜ J˜J˜J˜0J˜J˜$J˜—J˜J˜V˜ J˜!J˜J˜ J˜J˜J˜J˜1J˜:J˜5J˜˜J˜-J˜4J˜6J˜5J˜7J˜9J˜3J˜3J˜J˜'J˜"—J˜—J˜J˜3J˜S˜ J˜!J˜J˜ J˜J˜J˜J˜1J˜:J˜5J˜J˜ J˜—J˜J˜B˜ J˜!J˜J˜ J˜J˜J˜1J˜:J˜J˜—J˜J˜1J˜J˜ J˜˜ J˜ J˜J˜J˜J˜˜J˜—J˜J˜J˜7J˜˜J˜(J˜J˜J˜—J˜—˜#J˜J˜>˜J˜ J˜(J˜J˜)J˜J˜—J˜—˜#J˜J˜>˜J˜ J˜(J˜J˜'J˜ Jšœ˜J˜—J˜—˜J˜J˜>˜J˜(J˜Jšœ ˜ J˜—J˜—J˜J˜—J˜—J˜˜J˜J˜ J˜'J˜6J˜>J˜'J˜J˜>˜J˜ J˜(J˜J˜ J˜—J˜(J˜)J˜—J˜—J˜J˜J˜J˜¯—J˜—…—#ò(m