IMPLEMENTATION MODULE Parser; FROM Memory IMPORT ALLOCATE, AddMarker; FROM Lib IMPORT IncAddr; IMPORT Str; FROM FIO IMPORT File, Open, IOresult, Close; FROM Buffers IMPORT ReadChar, ReadWord, Rewind, CharSet; FROM Buffers IMPORT position, OpenInput, CloseInput, ReportError; FROM Machine IMPORT EmptyClosure, tempDef, wPackage, link, HandlePackage, Reduce; FROM Machine IMPORT Join, AddEnv, AddValuedEnv, Root, Copy, result; FROM Machine IMPORT ChangeDefinition, NewLayer, StartLayer, PopLayer; FROM Machine IMPORT MakeDef, MakePrimitive, MakeString, MakePacked, ExtractPacked; FROM Machine IMPORT MarkString, MarkClosure; FROM Library IMPORT wChar, wString, wCharSet, wNumber, wError, errorCodes; FROM Library IMPORT wType, wStruct, wFile, wUndefined, wDescription; FROM Names IMPORT FindWord, DefEntry, AddPrimWord, DefineWord, wMeaning; FROM Names IMPORT NewDictionary, OldDictionary; FROM Grammars IMPORT wSequence, wLexSequence, wValSequence, wLexValSequence; FROM Grammars IMPORT wEndSeq, wChoice, wOption; FROM Grammars IMPORT wDummy, wFail, wDone, wRaise, wDiscard, wGrammar, wNext; FROM Grammars IMPORT wSpaceChars, wSpaces, wComment, wFrameGrammar, wCustomGrammar; FROM Grammars IMPORT wCharGrammar, wCharSetGrammar, wStrGrammar, wNumGrammar; FROM Grammars IMPORT wIdentifier, wIdentGrammar, wFirst, wTail; FROM Grammars IMPORT wStructGrammar; FROM Grammars IMPORT Failure, Confirmation; FROM ParseLow IMPORT ParsePrimitive, buildTree; FROM ParseLow IMPORT ParseSequencePrimitive, ParseEndSequence, ParseChoice, ParseOption; CONST MaxStrLength=200; all=CharSet{0C..377C}; TYPE CharPtr=POINTER TO CHAR; string=ARRAY [0..MaxStrLength] OF CHAR; VAR firstSet,tailSet:CharSet; originalFirst,originalTail:closure; strPtr:POINTER TO string; PROCEDURE pSpaces; VAR prevPos:LONGCARD; spaces:POINTER TO CharSet; str:ARRAY [0..1] OF CHAR; BEGIN StartLayer; ChangeDefinition(wCharSet,HandlePackage); Reduce(wSpaceChars^); PopLayer; ExtractPacked(result,spaces); IF Root(wComment^)=wFail THEN ReadWord(str,spaces^,spaces^) ELSE REPEAT ReadWord(str,spaces^,spaces^); prevPos:=position; StartLayer; ChangeDefinition(wGrammar,wComment^); ParsePrimitive; PopLayer; UNTIL Root(result)=wFail; Rewind(prevPos) END; result:=Confirmation END pSpaces; PROCEDURE ParseLexValSequence; BEGIN ParseSequencePrimitive(TRUE) END ParseLexValSequence; PROCEDURE ParseLexSequence; BEGIN ParseSequencePrimitive(FALSE) END ParseLexSequence; PROCEDURE ParseValSequence; BEGIN Reduce(wSpaces^); ParseSequencePrimitive(TRUE) END ParseValSequence; PROCEDURE ParseSequence; BEGIN Reduce(wSpaces^); ParseSequencePrimitive(FALSE) END ParseSequence; PROCEDURE ParseTheLetter; VAR chExpect,chRead:CHAR; BEGIN ExtractPacked(wPackage^,chExpect); ReadChar(chRead); IF chRead=chExpect THEN IF buildTree THEN MakePacked(result,wChar,chRead) ELSE result:=Confirmation END ELSE result:=Failure END END ParseTheLetter; VAR strRest:CharPtr; PROCEDURE ParseTheString; VAR ch:CHAR; strExpect:CharPtr; BEGIN ExtractPacked(wPackage^,strExpect); strRest:=strExpect; LOOP IF strRest^=0C THEN EXIT END; ReadChar(ch); IF strRest^#ch THEN EXIT END; IncAddr(strRest,1) END; IF strRest^=0C THEN IF buildTree THEN MakeString(result,wString,strExpect) ELSE result:=Confirmation END ELSE result:=Failure END END ParseTheString; PROCEDURE ParseTheCharSet; VAR ch:CHAR; s:POINTER TO CharSet; BEGIN ExtractPacked(wPackage^,s); ReadChar(ch); IF ch IN s^ THEN IF buildTree THEN MakePacked(result,wChar,ch) ELSE result:=Confirmation END ELSE result:=Failure END END ParseTheCharSet; PROCEDURE ParseNumber; VAR ch:CHAR; minus:BOOLEAN; x:CARDINAL; BEGIN ReadChar(ch); IF ch='-' THEN minus:=TRUE; ReadChar(ch) ELSE minus:=FALSE; IF ch='+' THEN ReadChar(ch) END END; x:=0; IF ch IN CharSet{'0'..'9'} THEN REPEAT IF x <= (MAX(INTEGER)-ORD(ch)+ORD('0')) DIV 10 THEN x:=10*x+ORD(ch)-ORD('0') END; ReadChar(ch) UNTIL NOT (ch IN CharSet{'0'..'9'}); Rewind(position-1); IF minus THEN MakePacked(result,wNumber,-INTEGER(x)) ELSE MakePacked(result,wNumber,x) END ELSE result:=Failure END END ParseNumber; PROCEDURE ParseChar; VAR delimiter,chRead:CHAR; BEGIN ReadChar(delimiter); IF delimiter="'" THEN ReadChar(chRead); ReadChar(delimiter); IF delimiter="'" THEN MakePacked(result,wChar,chRead) ELSE result:=Failure END ELSE result:=Failure END END ParseChar; PROCEDURE ParseCharSET; VAR ch,second,i:CHAR; s:CharSet; complement:BOOLEAN; BEGIN ReadChar(ch); IF ch='{' THEN s:=CharSet{}; ReadChar(ch); IF ch='~' THEN complement:=TRUE; ELSE complement:=FALSE; Rewind(position-1) END; LOOP pSpaces; ReadChar(ch); IF ch='}' THEN EXIT ELSIF ch='\' THEN ReadChar(ch); END; pSpaces; ReadChar(second); IF second='-' THEN pSpaces; ReadChar(second); IF second