DIRECTORY IO, ParserTypeDefs, ParserDefs, ParserUtilityDefs, IntDefs, ParserErrorDefs, ParserInputDefs, Rope; ParserMain: CEDAR PROGRAM IMPORTS IO, ParserInputDefs, ParserErrorDefs, IntDefs, ParserUtilityDefs, ParserTypeDefs, Rope EXPORTS ParserDefs = BEGIN defInProg: BOOLEAN; InitParser: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN defInProg _ FALSE; 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: REF TEXT _ NEW[TEXT[100]]; CurChar: CHARACTER; UserCommand: [0..9]; CommentText, UserText: Rope.ROPE; 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 Report["End Of File Inside a Comment", FatalSyntax]; END; BadDefineCommand => Report["No Such Define Command", FatalSyntax]; BadUserCommand => BEGIN 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[]; 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,NEW[TranslateRec _ [ x: XTrans,y: YTrans]]]; END; 'M => BEGIN [] _ ParserInputDefs.GetChar[]; Blank[]; SELECT ParserInputDefs.GetChar[] FROM 'X => AppendTList[CurTList,NEW[MirrorRec _ [coords: X]]]; 'Y => AppendTList[CurTList,NEW[MirrorRec _ [coords: Y]]]; ENDCASE => ERROR RecoverFromError[IllegalAxis]; END; 'R => BEGIN [] _ ParserInputDefs.GetChar[]; XRotation _ SignedLong[]; YRotation _ SignedLong[]; AppendTList[CurTList,NEW[RotateRec _ [ xRot: XRotation,yRot: YRotation]]]; END; '; => EXIT; ENDCASE => ERROR RecoverFromError[BadTransCommand]; Blank[]; ENDLOOP; Command _ CallSymbol; END; '( => BEGIN Level: CARDINAL _ 1; CommentTextStream: IO.STREAM _ IO.ROS[]; WHILE Level > 0 DO SELECT (CurChar_ParserInputDefs.GetChar[]) FROM '( => BEGIN Level _ Level+1; CommentTextStream.PutChar['(]; END; ') => BEGIN Level _ Level-1; IF Level > 0 THEN CommentTextStream.PutChar[')]; END; ParserInputDefs.EOF => ERROR RecoverFromError[BadComment]; ENDCASE => CommentTextStream.PutChar[CurChar]; ENDLOOP; CommentText _ CommentTextStream.RopeFromROS[]; 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 UserTextStream: IO.STREAM _ IO.ROS[]; UserCommand _ CurChar - '0; WHILE NOT ParserInputDefs.EndOfFile[] AND ParserInputDefs.Peek[] = ' DO [] _ ParserInputDefs.GetChar[]; ENDLOOP; WHILE NOT ParserInputDefs.EndOfFile[] AND ParserInputDefs.Peek[] # '; DO UserTextStream.PutChar[ParserInputDefs.GetChar[]]; ENDLOOP; UserText _ UserTextStream.RopeFromROS[]; IF ParserInputDefs.EndOfFile[] THEN ERROR RecoverFromError[BadUserCommand]; Command _ UserCommand; END; ENDCASE => ERROR RecoverFromError[BadCommand]; IF Semi[] THEN BEGIN OPEN IntDefs; 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[Rope.FromRefText[LayerName]]; Flash => IFlash[Diameter, Center]; Polygon => IPolygon[CurPath]; Box => IBox[Length, Width, Center, XRotation, YRotation]; Comment => BEGIN IComment[CommentText ! IntDefs.SemanticError => CONTINUE]; END; UserCommand => BEGIN IUserCommand[UserCommand,UserText ! IntDefs.SemanticError => CONTINUE]; END; ENDCASE => ERROR RecoverFromError[InternalError]; END ELSE ERROR RecoverFromError[MissingSemiColon]; END; ParserTypeDefs.FreePath[CurPath]; ParserTypeDefs.FreeTList[CurTList]; RETURN[Command]; END; END. èFile ParserMain.Mesa November 8, 1980 2:47 PM Last Edited by: McCreight, March 12, 1985 1:58:38 pm PST flush all junk, sometimes redundant, but necessary for require files By now we have parsed a syntactically valid command Ê ˜Jšœ™Jšœ™Jšœ8™8J˜šÏk ˜ Jšœa˜c—J˜šœ œ˜JšœœT˜^Jšœ ˜Jš˜J˜Jšœ œ˜J˜š Ïn œœ œœœ˜0Jš˜Jšœ œ˜šœœœ˜cJšœœ˜ —š˜Jšœ$˜*—Jšœ˜J˜—š ž œœ œœœ˜2Jš˜šœ œ œ˜iJšœœ˜ —š˜Jšœ&˜,—Jšœ˜J˜—šžœœ œœ˜CJšœœ˜J˜J˜ Jšœ œœ˜J˜J˜Jšœœœ˜Jšœœœ˜#Jšœœœ˜Jš œ œœœœ˜%Jšœ œ˜J˜Jšœœ˜!Jšœœœ˜#Jšœœœ˜J˜˜Jš˜šœ˜Jšœœ˜J˜Jšœ ˜˜J˜5J˜;J˜=J˜DJ˜@J˜GJ˜A˜ Jš˜J˜4Jšœ˜—J˜B˜Jš˜J˜9Jšœ˜—J˜EJ˜@J˜IJ˜GJ˜-J˜IJ˜@Jšœ,˜3J˜—š œœœ-œ˜vJ˜2—Jšœ ˜ J˜J˜Jšœ˜ Jšœ˜J˜——J˜(J˜*J˜JšœD™DJ˜Jšœ'˜1˜˜Jš˜J˜J˜Jšœ˜J˜—˜Jš˜J˜J˜0J˜šœ"œ œ˜DJš˜J˜J˜Jšœ˜—J˜Jšœ˜J˜—˜Jš˜J˜J˜J˜Jšœ˜J˜—˜Jš˜J˜J˜J˜Jšœ˜J˜—˜Jš˜J˜J˜š œœ$œ œ œ ˜]J˜8J˜(Jšœ˜—Jšœœœ ˜BJ˜Jšœ˜J˜—˜Jš˜J˜šœ˜%˜Jš˜Jšœ œœ˜2J˜J˜J˜šœœ ˜*Jš˜J˜J˜Jšœ˜—Jšœ œ˜J˜Jšœ˜—˜Jš˜Jšœ œœ˜0Jšœ œ˜J˜Jšœ˜—˜Jš˜Jšœ œœ˜1J˜J˜Jšœ˜—Jšœœ$˜4—Jšœ˜J˜—˜Jšœœ˜J˜J˜šœœ˜ šœ˜"šœ˜ J˜J˜J˜šœœ˜)J˜—Jšœ˜—šœ˜ J˜J˜šœ˜%Jšœœœ˜9Jšœœœ˜9Jšœœ˜/—Jšœ˜—šœ˜ J˜J˜J˜šœœ˜&J˜#—Jšœ˜—Jšœœ˜ Jšœœ#˜3—J˜Jšœ˜—J˜Jšœ˜J˜—˜Jš˜Jšœœ˜Jš œœœœœ˜(šœ ˜šœ%˜/šœ˜ J˜Jšœ˜Jšœ˜—šœ˜ J˜Jšœ œ˜0Jšœ˜—Jšœœœ˜:Jšœ'˜.—Jšœ˜—Jšœ.˜.Jšœ˜Jšœ˜J˜—˜Jš˜Jšœ œœ˜2J˜šœœ˜'J˜B—J˜˜ ˜Jš˜J˜Jšœ˜ Jšœ˜——J˜!J˜#Jšœ ˜Jšœ˜J˜—˜Jš˜J˜J˜!J˜#Jšœ˜Jšœ˜J˜—šœ ˜Jš˜Jš œœœœœ˜%J˜šœœœ˜HJšœ˜Jšœ˜—šœœœ˜HJšœ2˜2Jšœ˜—Jšœ(˜(Jšœœœ"˜KJ˜Jšœ˜J˜—Jšœœ˜.J˜šœ˜Jšœœ ˜Jšœ3™3J˜šœ˜Jš˜J˜Jšœ˜ Jšœ˜J˜—šœ ˜J˜J˜=J˜J˜&J˜1J˜-J˜"J˜J˜9˜ Jš˜Jšœ0œ˜:Jšœ˜—˜Jš˜Jšœ=œ˜GJšœ˜—Jšœœ!˜1—Jš˜J˜—Jšœœ$˜.J˜Jšœ˜J˜—J˜!J˜#Jšœ ˜J˜Jšœ˜J˜—Jšœ˜J˜——…—¸'¾