From fa37d84030adf6eae60fbd818457d8a7d6d05a17 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sat, 19 Mar 2011 20:59:17 -0500 Subject: [PATCH] sweet parsing of pins started --- include/dsnlexer.h | 18 +-- new/make-dir-lib-source-test-data.sh | 8 ++ new/sch_part.cpp | 8 +- new/sch_part.h | 92 +++++++++---- new/sch_sweet_parser.cpp | 189 ++++++++++++++++++++++----- new/sch_sweet_parser.h | 5 + new/sweet.keywords | 2 + 7 files changed, 257 insertions(+), 65 deletions(-) diff --git a/include/dsnlexer.h b/include/dsnlexer.h index e34f7dd762..4590fe612f 100644 --- a/include/dsnlexer.h +++ b/include/dsnlexer.h @@ -398,6 +398,15 @@ public: */ void Unexpected( int aTok ) throw( IO_ERROR ); + /** + * Function Unexpected + * throws an IO_ERROR exception with an input file specific error message. + * @param aToken is the token which was not expected at the + * current input location. + * @throw IO_ERROR with the location within the input file of the problem. + */ + void Unexpected( const char* aToken ) throw( IO_ERROR ); + /** * Function Duplicate * throws an IO_ERROR exception with a message saying specifically that aTok @@ -408,15 +417,6 @@ public: */ void Duplicate( int aTok ) throw( IO_ERROR ); - /** - * Function Unexpected - * throws an IO_ERROR exception with an input file specific error message. - * @param aToken is the token which was not expected at the - * current input location. - * @throw IO_ERROR with the location within the input file of the problem. - */ - void Unexpected( const char* aToken ) throw( IO_ERROR ); - /** * Function NeedLEFT * calls NextTok() and then verifies that the token read in is a DSN_LEFT. diff --git a/new/make-dir-lib-source-test-data.sh b/new/make-dir-lib-source-test-data.sh index eda2cc3d6a..9ef6827b9d 100755 --- a/new/make-dir-lib-source-test-data.sh +++ b/new/make-dir-lib-source-test-data.sh @@ -15,6 +15,12 @@ ARC="(arc (pos 22 33)(radius 12)(start 2 4)(end 13 33)(line_width 2.3)(fill fill BEZIER="(bezier (fill none)(line_width 2.0)(pts (xy 0 1)(xy 2 4)))" TEXT="(text \"This is some text\" (at 23 23 90.0)(justify left bottom)(visible yes)(fill filled))" +PIN="(pin input line (at 7 8 90.0)(length 2)(visible YES))" +# add to pin +# (name NAME (font [FONT] (size HEIGHT WIDTH) [ITALIC] [BOLD])(visible YES)) +# (number NUMBER (font [FONT] (size HEIGHT WIDTH) [ITALIC] [BOLD] (visible YES)) + + for C in ${CATEGORIES}; do mkdir -p $BASEDIR/$C @@ -28,6 +34,7 @@ for C in ${CATEGORIES}; do $ARC $BEZIER $TEXT + $PIN )" > $BASEDIR/$C/$P.part.$R done # also make the part without a rev: @@ -38,6 +45,7 @@ for C in ${CATEGORIES}; do $ARC $BEZIER $TEXT + $PIN )" > $BASEDIR/$C/$P.part done done diff --git a/new/sch_part.cpp b/new/sch_part.cpp index b978c52ca4..6104f0047d 100644 --- a/new/sch_part.cpp +++ b/new/sch_part.cpp @@ -53,13 +53,17 @@ void PART::clear() extends = 0; } - // graphics objects I own, and the container will not destroy them: + // delete graphics I own, since their container will not destroy them: for( GRAPHICS::iterator it = graphics.begin(); it != graphics.end(); ++it ) delete *it; graphics.clear(); + // delete PINs I own, since their container will not destroy them. + for( PINS::iterator it = pins.begin(); it != pins.end(); ++it ) + delete *it; + pins.clear(); - // @todo delete all properties, pins, and graphics + // @todo delete all properties } diff --git a/new/sch_part.h b/new/sch_part.h index bc51098868..04097b4925 100644 --- a/new/sch_part.h +++ b/new/sch_part.h @@ -7,10 +7,19 @@ //----------------------- -typedef wxPoint POINT; - #include #include +#include +#include + + +class POINT : public wxPoint +{ +public: + POINT( int x, int y ) : wxPoint( x, y ) {} + POINT() : wxPoint() {} +}; + namespace SCH { @@ -36,7 +45,7 @@ public: typedef std::deque POINTS; -class POLY_LINE : BASE_GRAPHIC +class POLY_LINE : public BASE_GRAPHIC { friend class PART; friend class SWEET_PARSER; @@ -52,7 +61,7 @@ public: {} }; -class BEZIER : POLY_LINE +class BEZIER : public POLY_LINE { friend class PART; friend class SWEET_PARSER; @@ -63,7 +72,7 @@ public: {} }; -class RECTANGLE : BASE_GRAPHIC +class RECTANGLE : public BASE_GRAPHIC { friend class PART; friend class SWEET_PARSER; @@ -81,16 +90,16 @@ public: }; -class CIRCLE : BASE_GRAPHIC +class CIRCLE : public BASE_GRAPHIC { friend class PART; friend class SWEET_PARSER; protected: - double lineWidth; - int fillType; // T_none, T_filled, or T_transparent POINT center; int radius; + double lineWidth; + int fillType; // T_none, T_filled, or T_transparent public: CIRCLE( PART* aOwner ) : @@ -99,15 +108,15 @@ public: }; -class ARC : BASE_GRAPHIC +class ARC : public BASE_GRAPHIC { friend class PART; friend class SWEET_PARSER; protected: + POINT pos; double lineWidth; int fillType; // T_none, T_filled, or T_transparent - POINT pos; int radius; POINT start; POINT end; @@ -119,7 +128,7 @@ public: }; -class GR_TEXT : BASE_GRAPHIC +class GR_TEXT : public BASE_GRAPHIC { friend class PART; friend class SWEET_PARSER; @@ -127,24 +136,54 @@ class GR_TEXT : BASE_GRAPHIC protected: POINT pos; float angle; - int fillType; // T_none, T_filled, or T_transparent - int hjustify; // T_center, T_right, or T_left - int vjustify; // T_center, T_top, or T_bottom + int fillType; ///< T_none, T_filled, or T_transparent + int hjustify; ///< T_center, T_right, or T_left + int vjustify; ///< T_center, T_top, or T_bottom bool isVisible; wxString text; // FONT font; public: GR_TEXT( PART* aOwner ) : - BASE_GRAPHIC( aOwner ) -/* - , - fillType( T_filled ), - hjustify( T_left ), - vjustify( T_bottom ), + BASE_GRAPHIC( aOwner ), angle( 0 ), + fillType( PR::T_filled ), + hjustify( PR::T_left ), + vjustify( PR::T_bottom ), + isVisible( true ) + {} +}; + + +class PIN : public BASE_GRAPHIC +{ + friend class PART; + friend class SWEET_PARSER; + +protected: + POINT pos; + float angle; + int connectionType; ///< T_input, T_output, T_bidirectional, T_tristate, T_passive, T_unspecified, + ///< T_power_in, T_power_out, T_open_collector, T_open_emitter, or T_unconnected. + int shape; ///< T_none, T_line, T_inverted, T_clock, T_inverted_clk, T_input_low, T_clock_low, + ///< T_falling_edge, T_non_logic. + int length; ///< length of pin in internal units + wxString name; + wxString number; + bool nameIsVisible; ///< name is visible + bool numIsVisible; ///< number is visible + bool isVisible; ///< pin is visible + +public: + PIN( PART* aOwner ) : + BASE_GRAPHIC( aOwner ), + angle( 0 ), + connectionType( PR::T_input ), + shape( PR::T_line ), + length( 0 ), + nameIsVisible( true ), + numIsVisible( true ), isVisible( true ) -*/ {} }; @@ -156,7 +195,8 @@ public: namespace SCH { -typedef std::deque< BASE_GRAPHIC* > GRAPHICS; +typedef std::vector< BASE_GRAPHIC* > GRAPHICS; +typedef std::vector< PIN* > PINS; class LPID; class SWEET_PARSER; @@ -227,8 +267,12 @@ protected: // not likely to have C++ descendants, but protected none-the-le */ GRAPHICS graphics; - /// A pin list - //PINS pins; + /** + * Member pins + * owns all the PINs in pins. + */ + PINS pins; + /// Alternate body forms. //ALTERNATES alternates; diff --git a/new/sch_sweet_parser.cpp b/new/sch_sweet_parser.cpp index b38d1eb68a..dca40a18d7 100644 --- a/new/sch_sweet_parser.cpp +++ b/new/sch_sweet_parser.cpp @@ -33,17 +33,19 @@ using namespace SCH; using namespace PR; -#define MAX_INHERITANCE_NESTING 6 // no problem going larger +#define MAX_INHERITANCE_NESTING 6 ///< max depth of inheritance, no problem going larger +#define INTERNAL_PER_LOGICAL 10000 ///< no. internal units per logical unit + /** * Function log2int * converts a logical coordinate to an internal coordinate. Logical coordinates * are defined as the standard distance between pins being equal to one. - * Internal coordinates are 1000 times that. + * Internal coordinates are currently INTERNAL_PER_LOGICAL times that. */ static inline int log2int( double aCoord ) { - return int( aCoord * 1000 ); + return int( aCoord * INTERNAL_PER_LOGICAL ); } static inline int internal( const STRING& aCoord ) @@ -80,7 +82,6 @@ static inline const int PB( PartBit oneBitOnly ) } - void SWEET_PARSER::parseExtends( PART* me ) { PART* base; @@ -280,6 +281,13 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E NeedRIGHT(); break; + case T_pin: + PIN* pin; + pin = new PIN( me ); + me->pins.push_back( pin ); + parsePin( pin ); + break; + /* case T_keywords: break; @@ -293,9 +301,6 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E case T_property_del: break; - case T_pin: - break; - case T_pin_merge: break; @@ -329,6 +334,130 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E } +void SWEET_PARSER::parseBool( bool* aBool ) +{ + T tok = NeedSYMBOL(); + + switch( tok ) + { + case T_yes: + case T_no: + *aBool = (tok == T_yes); + break; + default: + Expecting( "yes|no" ); + } +} + + +void SWEET_PARSER::parsePin( PIN* me ) +{ + /* + (pin TYPE SHAPE + (at X Y [ANGLE]) + (length LENGTH) + (name NAME (font [FONT] (size HEIGHT WIDTH) [ITALIC] [BOLD])(visible YES)) + (number NUMBER (font [FONT] (size HEIGHT WIDTH) [ITALIC] [BOLD] (visible YES)) + (visible YES) + ) + */ + + T tok; + bool sawShape = false; + bool sawType = false; + bool sawAt = false; + bool sawLen = false; + bool sawName = false; + bool sawNum = false; + bool sawVis = false; + + while( ( tok = NextTok() ) != T_RIGHT ) + { + if( tok == T_LEFT ) + { + tok = NextTok(); + + switch( tok ) + { + case T_at: + if( sawAt ) + Duplicate( tok ); + sawAt = true; + parseAt( &me->pos, &me->angle ); + break; + + case T_length: + if( sawLen ) + Duplicate( tok ); + sawLen = true; + NeedNUMBER( "length" ); + me->length = internal( CurText() ); + NeedRIGHT(); + break; + +/* @todo and associated fonts + case T_name: + case T_number: + break; +*/ + + case T_visible: + if( sawVis ) + Duplicate( tok ); + parseBool( &me->isVisible ); + NeedRIGHT(); + sawVis = true; + break; + + default: + Unexpected( tok ); + } + } + + else // not wrapped in parentheses + { + switch( tok ) + { + case T_input: + case T_output: + case T_bidirectional: + case T_tristate: + case T_passive: + case T_unspecified: + case T_power_in: + case T_power_out: + case T_open_collector: + case T_open_emitter: + case T_unconnected: + if( sawType ) + Duplicate( tok ); + sawType = true; + me->connectionType = tok; + break; + + case T_none: + case T_line: + case T_inverted: + case T_clock: + case T_inverted_clk: + case T_input_low: + case T_clock_low: + case T_falling_edge: + case T_non_logic: + if( sawShape ) + Duplicate( tok ); + sawShape = true; + me->shape = tok; + break; + + default: + Unexpected( tok ); + } + } + } +} + + void SWEET_PARSER::parsePolyLine( POLY_LINE* me ) { T tok; @@ -646,6 +775,27 @@ void SWEET_PARSER::parseArc( ARC* me ) } +void SWEET_PARSER::parseAt( POINT* pos, float* angle ) +{ + T tok; + + NeedNUMBER( "at x" ); + pos->x = internal( CurText() ); + + NeedNUMBER( "at y" ); + pos->y = internal( CurText() ); + + tok = NextTok(); + if( angle && tok == T_NUMBER ) + { + *angle = strtod( CurText(), NULL ); + tok = NextTok(); + } + if( tok != T_RIGHT ) + Expecting( T_RIGHT ); +} + + void SWEET_PARSER::parseText( GR_TEXT* me ) { T tok; @@ -670,19 +820,7 @@ void SWEET_PARSER::parseText( GR_TEXT* me ) case T_at: if( sawAt ) Duplicate( tok ); - NeedNUMBER( "at x" ); - me->pos.x = internal( CurText() ); - NeedNUMBER( "at y" ); - me->pos.y = internal( CurText() ); - - tok = NextTok(); - if( tok == T_NUMBER ) - { - me->angle = strtod( CurText(), NULL ); - tok = NextTok(); - } - if( tok != T_RIGHT ) - Expecting( T_RIGHT ); + parseAt( &me->pos, &me->angle ); sawAt = true; break; @@ -737,16 +875,7 @@ void SWEET_PARSER::parseText( GR_TEXT* me ) case T_visible: if( sawVis ) Duplicate( tok ); - tok = NeedSYMBOL(); - switch( tok ) - { - case T_yes: - case T_no: - me->isVisible = (tok == T_yes); - break; - default: - Expecting( "yes|no" ); - } + parseBool( &me->isVisible ); NeedRIGHT(); sawVis = true; break; diff --git a/new/sch_sweet_parser.h b/new/sch_sweet_parser.h index e658903634..cb39e0a4e3 100644 --- a/new/sch_sweet_parser.h +++ b/new/sch_sweet_parser.h @@ -28,6 +28,7 @@ #include #include +class POINT; namespace SCH { @@ -41,6 +42,7 @@ class CIRCLE; class ARC; class BEZIER; class GR_TEXT; +class PIN; /** @@ -66,6 +68,9 @@ class SWEET_PARSER : public SWEET_LEXER void parseCircle( CIRCLE* me ); void parseArc( ARC* me ); void parseText( GR_TEXT* me ); + void parsePin( PIN* me ); + void parseAt( POINT* pos, float* angle ); + void parseBool( bool* aBool ); public: diff --git a/new/sweet.keywords b/new/sweet.keywords index 63e98747d2..ba5692bb96 100644 --- a/new/sweet.keywords +++ b/new/sweet.keywords @@ -14,6 +14,7 @@ effects end end_angle extends +falling_edge fill filled font @@ -31,6 +32,7 @@ line_width model name no +non_logic none number open_collector