-- File ParserMain.Mesa -- November 8, 1980 2:47 PM DIRECTORY ParserTypeDefs: FROM "ParserTypeDefs" USING [InitTypes, FinishTypes, Path, Point, AllocatePath, FreePath, TList, AllocateTList, FreeTList, AppendTList, TEntry], SystemDefs: FROM "SystemDefs" USING [AllocateHeapString, FreeHeapString], ParserDefs: FROM "ParserDefs", ParserUtilityDefs: FROM "ParserUtilityDefs", IntDefs: FROM "IntDefs" USING [IWire, IDefineStart, IDefineEnd, IDeleteDef, ICallSymbol, ILayer, IFlash, IPolygon, IBox, IComment, IUserCommand, IEnd, SemanticError], ParserErrorDefs: FROM "ParserErrorDefs" USING [InitError, FinishError, Report], StringDefs: FROM "StringDefs" USING [AppendChar, StringBoundsFault, AppendString], ParserInputDefs: FROM "ParserInputDefs" USING[InitInput, FinishInput, GetChar, Peek, EndOfFile, Flush, EOF]; ParserMain: PROGRAM IMPORTS ParserInputDefs, ParserErrorDefs, IntDefs, ParserUtilityDefs, ParserTypeDefs, StringDefs, SystemDefs EXPORTS ParserDefs = BEGIN defInProg: BOOLEAN; --For debugging space leaks: NStrings: INTEGER _ 0; InitParser: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN defInProg _ FALSE; NStrings _ 0; IF ~ParserInputDefs.InitInput[] OR ~ParserErrorDefs.InitError[] OR ~ParserTypeDefs.InitTypes[] THEN RETURN[FALSE] ELSE RETURN[ParserUtilityDefs.InitUtilities[]]; END; FinishParser: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN IF ~ParserInputDefs.FinishInput[] OR ~ParserErrorDefs.FinishError[] OR ~ParserTypeDefs.FinishTypes[] THEN RETURN[FALSE] ELSE RETURN[ParserUtilityDefs.FinishUtilities[]]; END; ParseStatement: PUBLIC PROCEDURE RETURNS [ParserDefs.CommandType] = BEGIN OPEN ParserUtilityDefs; Command: ParserDefs.CommandType; Diameter: LONG CARDINAL; Center: ParserTypeDefs.Point; CurPath: ParserTypeDefs.Path; Length, Width: LONG CARDINAL; XRotation, YRotation: LONG INTEGER; SymbolNumber: LONG CARDINAL; LayerName: STRING _ [4]; CurChar: CHARACTER; UserCommand: [0..9]; CommentText, UserText: STRING; Multiplier, Divisor: LONG CARDINAL; XTrans, YTrans: LONG INTEGER; CurTList: ParserTypeDefs.TList; BEGIN ENABLE RecoverFromError => BEGIN OPEN ParserErrorDefs; SELECT errorCode FROM NullPath => Report["No Points in Path", FatalSyntax]; MissingLayer => Report["Layer Name Expected", FatalSyntax]; NumberTooBig => Report["Number Out Of Range", FatalSemantic]; MissingUnsigned => Report["Unsigned Integer Expected", FatalSyntax]; MissingSigned => Report["Signed Integer Expected", FatalSyntax]; MissingSemiColon => Report["Missing Semicolon, Inserted", FatalSyntax]; BadCommand => Report["Unknown Command Encountered", FatalSyntax]; BadComment => BEGIN FreeString[CommentText]; Report["End Of File Inside a Comment", FatalSyntax]; END; BadDefineCommand => Report["No Such Define Command", FatalSyntax]; BadUserCommand => BEGIN FreeString[UserText]; Report["End Of File Inside a User Command", FatalSyntax]; END; IllegalAxis => Report["No Such Axis in Mirror Command", FatalSyntax]; NestDef => Report["Symbol Definitions Can't Nest", FatalSyntax]; NestDD => Report["DD Not Allowed Inside Symbol Definition", FatalSyntax]; NestEnd => Report["End Command Inside Symbol Definition", FatalSyntax]; NoDS => Report["DF Without DS", FatalSyntax]; BadTransCommand => Report["No Such Transformation Command", FatalSyntax]; InternalError => Report["Parser Internal Error", FatalInternal]; ENDCASE => Report["Uncaught PossibleError", Fatal]; IF errorCode # MissingSemiColon AND errorCode # InternalError AND ParserInputDefs.Flush[';] = ParserInputDefs.EOF THEN Report["Unexpected End of Input File",FatalSyntax] ELSE Blank[]; Command _ SyntaxError; CONTINUE; END; CurPath _ ParserTypeDefs.AllocatePath[]; CurTList _ ParserTypeDefs.AllocateTList[]; -- flush all junk, sometimes redundant, but necessary for require files Blank[]; SELECT (CurChar _ ParserInputDefs.GetChar[]) FROM 'P => BEGIN GetPath[CurPath]; Command _ Polygon; END; 'B => BEGIN XRotation _ 1; YRotation _ 0; Length _ UnsignedLong[]; Width _ UnsignedLong[]; Center _ GetPoint[]; Sep[]; IF (CurChar_ParserInputDefs.Peek[]) IN ['0..'9] OR CurChar = '- THEN BEGIN XRotation _ SignedLong[]; YRotation _ SignedLong[]; END; Command _ Box; END; 'R => BEGIN Diameter _ UnsignedLong[]; Center _ GetPoint[]; Command _ Flash; END; 'W => BEGIN Width _ UnsignedLong[]; GetPath[CurPath]; Command _ Wire; END; 'L => BEGIN Blank[]; LayerName.length _ 0; THROUGH [1..4] WHILE (CurChar _ ParserInputDefs.Peek[]) IN ['0..'9] OR CurChar IN ['A..'Z] DO LayerName[LayerName.length] _ ParserInputDefs.GetChar[]; LayerName.length _ LayerName.length + 1; ENDLOOP; IF LayerName.length = 0 THEN ERROR RecoverFromError[MissingLayer]; Command _ Layer; END; 'D => BEGIN Blank[]; SELECT ParserInputDefs.GetChar[] FROM 'S => BEGIN IF defInProg THEN ERROR RecoverFromError[NestDef]; SymbolNumber _ UnsignedLong[]; Sep[]; Multiplier _ Divisor _ 1; IF ParserInputDefs.Peek[] IN ['0..'9] THEN BEGIN Multiplier _ UnsignedLong[]; Divisor _ UnsignedLong[]; END; defInProg _ TRUE; Command _ DefineStart; END; 'F => BEGIN IF ~defInProg THEN ERROR RecoverFromError[NoDS]; defInProg _ FALSE; Command _ DefineEnd; END; 'D => BEGIN IF defInProg THEN ERROR RecoverFromError[NestDD]; SymbolNumber _ UnsignedLong[]; Command _ DeleteDef; END; ENDCASE => ERROR RecoverFromError[BadDefineCommand]; END; 'C => BEGIN OPEN ParserTypeDefs; SymbolNumber _ UnsignedLong[]; Blank[]; WHILE TRUE DO SELECT ParserInputDefs.Peek[] FROM 'T => BEGIN [] _ ParserInputDefs.GetChar[]; XTrans _ SignedLong[]; YTrans _ SignedLong[]; AppendTList[CurTList,TEntry[Translate[ x: XTrans,y: YTrans]]]; END; 'M => BEGIN [] _ ParserInputDefs.GetChar[]; Blank[]; SELECT ParserInputDefs.GetChar[] FROM 'X => AppendTList[CurTList,TEntry[Mirror[coords: X]]]; 'Y => AppendTList[CurTList,TEntry[Mirror[coords: Y]]]; ENDCASE => ERROR RecoverFromError[IllegalAxis]; END; 'R => BEGIN [] _ ParserInputDefs.GetChar[]; XRotation _ SignedLong[]; YRotation _ SignedLong[]; AppendTList[CurTList,TEntry[Rotate[ xRot: XRotation,yRot: YRotation]]]; END; '; => EXIT; ENDCASE => ERROR RecoverFromError[BadTransCommand]; Blank[]; ENDLOOP; Command _ CallSymbol; END; '( => BEGIN ENABLE StringDefs.StringBoundsFault => BEGIN New: STRING; New _ AllocateString[s.length+50]; StringDefs.AppendString[New,s]; FreeString[s]; RESUME[CommentText_New]; END; Level: CARDINAL _ 1; CommentText _ AllocateString[50]; WHILE Level > 0 DO SELECT (CurChar_ParserInputDefs.GetChar[]) FROM '( => BEGIN Level _ Level+1; StringDefs.AppendChar[CommentText,'(]; END; ') => BEGIN Level _ Level-1; IF Level > 0 THEN StringDefs.AppendChar[CommentText,')]; END; ParserInputDefs.EOF => ERROR RecoverFromError[BadComment]; ENDCASE => StringDefs.AppendChar[CommentText,CurChar]; ENDLOOP; Command _ Comment; END; 'E => BEGIN IF defInProg THEN ERROR RecoverFromError[NestEnd]; Blank[]; IF NOT ParserInputDefs.EndOfFile[] THEN ParserErrorDefs.Report["More Text Follows End Command", Advisory]; Command _ End; IntDefs.IEnd[ ! IntDefs.SemanticError => BEGIN Command _ SemanticError; CONTINUE; END]; ParserTypeDefs.FreePath[CurPath]; ParserTypeDefs.FreeTList[CurTList]; RETURN[Command]; END; '; => BEGIN Blank[]; ParserTypeDefs.FreePath[CurPath]; ParserTypeDefs.FreeTList[CurTList]; RETURN[NullCommand]; END; IN ['0..'9] => BEGIN UserCommand _ CurChar - '0; UserText _ AllocateString[50]; WHILE NOT ParserInputDefs.EndOfFile[] AND ParserInputDefs.Peek[] # '; DO StringDefs.AppendChar[UserText,ParserInputDefs.GetChar[] ! StringDefs.StringBoundsFault => BEGIN New: STRING; New _ AllocateString[s.length+50]; StringDefs.AppendString[New,s]; FreeString[s]; RESUME[UserText_New]; END]; ENDLOOP; IF ParserInputDefs.EndOfFile[] THEN ERROR RecoverFromError[BadUserCommand]; Command _ UserCommand; END; ENDCASE => ERROR RecoverFromError[BadCommand]; IF Semi[] THEN BEGIN OPEN IntDefs; -- By now we have parsed a syntactically valid command ENABLE IntDefs.SemanticError => BEGIN Command _ SemanticError; CONTINUE; END; SELECT Command FROM Wire => IWire[Width, CurPath]; DefineStart => IDefineStart[SymbolNumber,Multiplier,Divisor]; DefineEnd => IDefineEnd[]; DeleteDef => IDeleteDef[SymbolNumber]; CallSymbol => ICallSymbol[SymbolNumber,CurTList]; Layer => ILayer[LayerName]; Flash => IFlash[Diameter, Center]; Polygon => IPolygon[CurPath]; Box => IBox[Length, Width, Center, XRotation, YRotation]; Comment => BEGIN IComment[CommentText ! IntDefs.SemanticError => CONTINUE]; FreeString[CommentText]; END; UserCommand => BEGIN IUserCommand[UserCommand,UserText ! IntDefs.SemanticError => CONTINUE]; FreeString[UserText]; END; ENDCASE => ERROR RecoverFromError[InternalError]; END ELSE ERROR RecoverFromError[MissingSemiColon]; END; ParserTypeDefs.FreePath[CurPath]; ParserTypeDefs.FreeTList[CurTList]; RETURN[Command]; END; AllocateString: PROCEDURE[length: CARDINAL] RETURNS [STRING] = BEGIN NStrings _ NStrings + 1; RETURN[SystemDefs.AllocateHeapString[length]]; END; FreeString: PROCEDURE[s: STRING] = BEGIN NStrings _ NStrings - 1; SystemDefs.FreeHeapString[s]; END; END. (670)\54b9B767i3I4b10B226b10B265b12B236b14B625i8I32i11I7i12I33i12I7i16I29i14I2i20I39i12I3i17I12i1I24i12I7i16I41i12I7i10I42i11I7i10I89i11I17i16I36i12I7i14I90i12I17i11I45i11I7i7I44i11I7i6I54i11I7i7I51i11I7i4I28i11I7i15I45i11I7i13I34i15I50i6I22i16I17i13I49i3I49i11I33i11I306i7I320i3I101i5I95i4I346i12I17i5I156i7I268i11I84i4I44i9I83i6I56i9I52i16I315i9I212i6I58i6I58i11I178i6I118i15I45i10I621i3I27i10I92i7I76i7I120i9I17i3I80i13I260i11I529i14I17i11I49i10I163i13I49i11I24i18I48i16I14i17I26i18I36i13I19i13I27i15I19i10I52i14I75i1I40i18I88i1I37i4I34i13I42i16I116b14B142b10B