Commit 115d1adb authored by Dick Hollenbeck's avatar Dick Hollenbeck

more sweet parser & beginnings of Format()ing

parent 5b0e60e6
...@@ -61,6 +61,9 @@ PROP1=" ...@@ -61,6 +61,9 @@ PROP1="
(effects (at 1 34 270)(font (size .5 1) italic bold)(visible no)) (effects (at 1 34 270)(font (size .5 1) italic bold)(visible no))
)" )"
KEYWORDS="
(keywords varistor batcave einstein)"
for C in ${CATEGORIES}; do for C in ${CATEGORIES}; do
...@@ -79,6 +82,7 @@ for C in ${CATEGORIES}; do ...@@ -79,6 +82,7 @@ for C in ${CATEGORIES}; do
$PIN1 $PIN1
$PIN2 $PIN2
$PROP1 $PROP1
$KEYWORDS
)" > $BASEDIR/$C/$P.part.$R )" > $BASEDIR/$C/$P.part.$R
done done
# also make the part without a rev: # also make the part without a rev:
...@@ -93,6 +97,7 @@ for C in ${CATEGORIES}; do ...@@ -93,6 +97,7 @@ for C in ${CATEGORIES}; do
$PIN1 $PIN1
$PIN2 $PIN2
$PROP1 $PROP1
$KEYWORDS
)" > $BASEDIR/$C/$P.part )" > $BASEDIR/$C/$P.part
done done
done done
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <sch_sweet_parser.h> #include <sch_sweet_parser.h>
#include <sch_lpid.h> #include <sch_lpid.h>
#include <sch_lib_table.h> #include <sch_lib_table.h>
//#include <richio.h>
using namespace SCH; using namespace SCH;
...@@ -74,6 +74,11 @@ void PART::clear() ...@@ -74,6 +74,11 @@ void PART::clear()
delete *it; delete *it;
properties.clear(); properties.clear();
keywords.clear();
contains = 0;
// @todo clear the mandatory fields
} }
...@@ -120,12 +125,68 @@ void PART::Parse( SWEET_PARSER* aParser, LIB_TABLE* aTable ) throw( IO_ERROR, PA ...@@ -120,12 +125,68 @@ void PART::Parse( SWEET_PARSER* aParser, LIB_TABLE* aTable ) throw( IO_ERROR, PA
} }
#if 0 && defined(DEBUG) void PART::PropertyDelete( const wxString& aPropertyName ) throw( IO_ERROR )
{
PROPERTIES::iterator it = propertyFind( aPropertyName );
if( it == properties.end() )
{
wxString msg;
msg.Printf( _( "Unable to find property: %s" ), aPropertyName.GetData() );
THROW_IO_ERROR( msg );
}
delete *it;
properties.erase( it );
return;
}
PROPERTIES::iterator PART::propertyFind( const wxString& aPropertyName )
{
PROPERTIES::iterator it;
for( it = properties.begin(); it!=properties.end(); ++it )
if( (*it)->name == aPropertyName )
break;
return it;
}
int main( int argc, char** argv ) void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const throw( IO_ERROR )
{ {
return 0; out->Print( indent, "(part %s", partNameAndRev.c_str() );
if( extends )
out->Print( 0, " inherits %s", extends->Format().c_str() );
out->Print( 0, "\n" );
/*
@todo
for( int i=0; i<MANDATORY_FIELDS; ++i )
{
}
*/
for( PROPERTIES::const_iterator it = properties.begin(); it != properties.end(); ++it )
{
(*it)->Format( out, indent+1, ctl );
}
if( anchor.x || anchor.y )
{
out->Print( indent+1, "(anchor (at %.6g %.6g))\n",
InternalToLogical( anchor.x ),
InternalToLogical( anchor.y ) );
}
for( GRAPHICS::const_iterator it = graphics.begin(); it != graphics.end(); ++it )
{
(*it)->Format( out, indent+1, ctl );
}
for( PINS::const_iterator it = pins.begin(); it != pins.end(); ++it )
{
(*it)->Format( out, indent+1, ctl );
}
} }
#endif
...@@ -34,8 +34,10 @@ ...@@ -34,8 +34,10 @@
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
#include <deque> #include <deque>
#include <vector> #include <vector>
#include <set>
#include <sweet_lexer.h> #include <sweet_lexer.h>
class OUTPUTFORMATTER;
namespace SCH { namespace SCH {
...@@ -114,6 +116,10 @@ public: ...@@ -114,6 +116,10 @@ public:
{} {}
virtual ~BASE_GRAPHIC() {} virtual ~BASE_GRAPHIC() {}
virtual void Format( OUTPUTFORMATTER* aOutputFormatter, int aNestLevel, int aControlBits ) const
throw( IO_ERROR )
{}
}; };
typedef std::deque<POINT> POINTS; typedef std::deque<POINT> POINTS;
...@@ -278,6 +284,11 @@ public: ...@@ -278,6 +284,11 @@ public:
isVisible( true ) isVisible( true )
{} {}
/*
void Format( OUTPUTFORMATTER* aOutputFormatter, int aNestLevel, int aControlBits ) const
throw( IO_ERROR );
*/
protected: protected:
PART* birthplace; ///< at which PART in inheritance chain was this PIN added PART* birthplace; ///< at which PART in inheritance chain was this PIN added
POINT pos; POINT pos;
...@@ -309,6 +320,7 @@ namespace SCH { ...@@ -309,6 +320,7 @@ namespace SCH {
typedef std::vector< BASE_GRAPHIC* > GRAPHICS; typedef std::vector< BASE_GRAPHIC* > GRAPHICS;
typedef std::vector< PIN* > PINS; typedef std::vector< PIN* > PINS;
typedef std::vector< PROPERTY* > PROPERTIES; typedef std::vector< PROPERTY* > PROPERTIES;
typedef std::set< wxString > KEYWORDS;
class LPID; class LPID;
class SWEET_PARSER; class SWEET_PARSER;
...@@ -347,6 +359,14 @@ protected: // not likely to have C++ descendants, but protected none-the-le ...@@ -347,6 +359,14 @@ protected: // not likely to have C++ descendants, but protected none-the-le
*/ */
void inherit( const PART& aBasePart ); void inherit( const PART& aBasePart );
/**
* Function propertyFind
* searches for aPropertyName and returns a PROPERTIES::iterator which
* is the found item or properties.end() if not found.
*/
PROPERTIES::iterator propertyFind( const wxString& aPropertyName );
POINT anchor; POINT anchor;
//PART( LIB* aOwner ); //PART( LIB* aOwner );
...@@ -396,14 +416,14 @@ protected: // not likely to have C++ descendants, but protected none-the-le ...@@ -396,14 +416,14 @@ protected: // not likely to have C++ descendants, but protected none-the-le
/// Alternate body forms. /// Alternate body forms.
//ALTERNATES alternates; //ALTERNATES alternates;
wxString keywords; KEYWORDS keywords;
public: public:
virtual ~PART(); virtual ~PART();
PART& operator=( const PART& other ); PART& operator = ( const PART& other );
/** /**
* Function Owner * Function Owner
...@@ -424,6 +444,21 @@ public: ...@@ -424,6 +444,21 @@ public:
*/ */
void Parse( SWEET_PARSER* aParser, LIB_TABLE* aLibTable ) throw( IO_ERROR, PARSE_ERROR ); void Parse( SWEET_PARSER* aParser, LIB_TABLE* aLibTable ) throw( IO_ERROR, PARSE_ERROR );
/**
* Function Format
* outputs this PART in UTF8 encoded s-expression format to @a aFormatter.
* @param aFormatter is the output sink to write to.
* @param aNestLevel is the initial indent level
* @param aControlBits are bit flags ORed together which control how the output
* is done.
*/
void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits = 0 ) const
throw( IO_ERROR );
void PropertyDelete( const wxString& aPropertyName ) throw( IO_ERROR );
/* /*
void SetValue( const wxString& aValue ) void SetValue( const wxString& aValue )
{ {
......
...@@ -34,7 +34,6 @@ using namespace PR; ...@@ -34,7 +34,6 @@ using namespace PR;
#define MAX_INHERITANCE_NESTING 6 ///< max depth of inheritance, 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
/** /**
...@@ -148,7 +147,7 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E ...@@ -148,7 +147,7 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
// Caller may not have read the first two tokens out of the // Caller may not have read the first two tokens out of the
// stream: T_LEFT and T_part, so ignore them if seen here. // stream: T_LEFT and T_part, so ignore them if seen here.
// The 1st two tokens T_LEFT and T_part are then optional in the grammar. // The 1st two tokens T_LEFT and T_part are then optional in the grammar.
if( (tok = NextTok() ) == T_LEFT ) if( ( tok = NextTok() ) == T_LEFT )
{ {
if( ( tok = NextTok() ) != T_part ) if( ( tok = NextTok() ) != T_part )
Expecting( T_part ); Expecting( T_part );
...@@ -174,236 +173,249 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E ...@@ -174,236 +173,249 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
for( ; tok!=T_RIGHT; tok = NextTok() ) for( ; tok!=T_RIGHT; tok = NextTok() )
{ {
if( tok==T_EOF )
Unexpected( T_EOF );
if( tok == T_LEFT ) if( tok == T_LEFT )
{
tok = NextTok(); tok = NextTok();
// because exceptions are thrown, any 'new' allocation has to be stored // because exceptions are thrown, any 'new' allocation has to be stored
// somewhere other than on the stack, ASAP. // somewhere other than on the stack, ASAP.
switch( tok ) switch( tok )
{ {
default: default:
// describe what we expect at this level // describe what we expect at this level
Expecting( Expecting(
"anchor|value|footprint|model|keywords|alternates\n" "anchor|value|footprint|model|keywords|alternates\n"
"|property\n" "|property\n"
" |property_del\n" " |property_del\n"
"|pin\n" "|pin\n"
" |pin_merge|pin_swap|pin_renum|pin_rename|route_pin_swap\n" " |pin_merge|pin_swap|pin_renum|pin_rename|route_pin_swap\n"
"|polyline|line|rectangle|circle|arc|bezier|text" "|polyline|line|rectangle|circle|arc|bezier|text"
); );
break; break;
case T_anchor: case T_anchor:
if( contains & PB(ANCHOR) ) if( contains & PB(ANCHOR) )
Duplicate( tok ); Duplicate( tok );
NeedNUMBER( "anchor x" ); NeedNUMBER( "anchor x" );
me->anchor.x = internal( CurText() ); me->anchor.x = internal( CurText() );
NeedNUMBER( "anchor y" ); NeedNUMBER( "anchor y" );
me->anchor.y = internal( CurText() ); me->anchor.y = internal( CurText() );
contains |= PB(ANCHOR); contains |= PB(ANCHOR);
break; break;
case T_line: case T_line:
case T_polyline: case T_polyline:
POLY_LINE* pl; POLY_LINE* pl;
pl = new POLY_LINE( me ); pl = new POLY_LINE( me );
me->graphics.push_back( pl ); me->graphics.push_back( pl );
parsePolyLine( pl ); parsePolyLine( pl );
break; break;
case T_rectangle: case T_rectangle:
RECTANGLE* rect; RECTANGLE* rect;
rect = new RECTANGLE( me ); rect = new RECTANGLE( me );
me->graphics.push_back( rect ); me->graphics.push_back( rect );
parseRectangle( rect ); parseRectangle( rect );
break; break;
case T_circle: case T_circle:
CIRCLE* circ; CIRCLE* circ;
circ = new CIRCLE( me ); circ = new CIRCLE( me );
me->graphics.push_back( circ ); me->graphics.push_back( circ );
parseCircle( circ ); parseCircle( circ );
break; break;
case T_arc: case T_arc:
ARC* arc; ARC* arc;
arc = new ARC( me ); arc = new ARC( me );
me->graphics.push_back( arc ); me->graphics.push_back( arc );
parseArc( arc ); parseArc( arc );
break; break;
case T_bezier: case T_bezier:
BEZIER* bezier; BEZIER* bezier;
bezier = new BEZIER( me ); bezier = new BEZIER( me );
me->graphics.push_back( bezier ); me->graphics.push_back( bezier );
parseBezier( bezier ); parseBezier( bezier );
break; break;
case T_text: case T_text:
GR_TEXT* text; GR_TEXT* text;
text = new GR_TEXT( me ); text = new GR_TEXT( me );
me->graphics.push_back( text ); me->graphics.push_back( text );
parseText( text ); parseText( text );
break; break;
// reference in a PART is incomplete, it is just the prefix of an // reference in a PART is incomplete, it is just the prefix of an
// unannotated reference. Only components have full reference designators. // unannotated reference. Only components have full reference designators.
case T_reference: case T_reference:
if( contains & PB(REFERENCE) ) if( contains & PB(REFERENCE) )
Duplicate( tok ); Duplicate( tok );
contains |= PB(REFERENCE); contains |= PB(REFERENCE);
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
me->reference.text = FromUTF8(); me->reference.text = FromUTF8();
tok = NextTok();
if( tok == T_LEFT )
{
tok = NextTok(); tok = NextTok();
if( tok != T_effects ) if( tok == T_LEFT )
Expecting( T_effects ); {
parseTextEffects( &me->reference.effects ); tok = NextTok();
NeedRIGHT(); if( tok != T_effects )
} Expecting( T_effects );
else if( tok != T_RIGHT ) parseTextEffects( &me->reference.effects );
Expecting( ") | effects" ); NeedRIGHT();
break; }
else if( tok != T_RIGHT )
Expecting( ") | effects" );
break;
case T_value: case T_value:
if( contains & PB(VALUE) ) if( contains & PB(VALUE) )
Duplicate( tok ); Duplicate( tok );
contains |= PB(VALUE); contains |= PB(VALUE);
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
me->value.text = FromUTF8(); me->value.text = FromUTF8();
tok = NextTok();
if( tok == T_LEFT )
{
tok = NextTok(); tok = NextTok();
if( tok != T_effects ) if( tok == T_LEFT )
Expecting( T_effects ); {
parseTextEffects( &me->value.effects ); tok = NextTok();
NeedRIGHT(); if( tok != T_effects )
} Expecting( T_effects );
else if( tok != T_RIGHT ) parseTextEffects( &me->value.effects );
Expecting( ") | effects" ); NeedRIGHT();
break; }
else if( tok != T_RIGHT )
Expecting( ") | effects" );
break;
case T_footprint: case T_footprint:
if( contains & PB(FOOTPRINT) ) if( contains & PB(FOOTPRINT) )
Duplicate( tok ); Duplicate( tok );
contains |= PB(FOOTPRINT); contains |= PB(FOOTPRINT);
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
me->footprint.text = FromUTF8(); me->footprint.text = FromUTF8();
tok = NextTok();
if( tok == T_LEFT )
{
tok = NextTok(); tok = NextTok();
if( tok != T_effects ) if( tok == T_LEFT )
Expecting( T_effects ); {
parseTextEffects( &me->footprint.effects ); tok = NextTok();
NeedRIGHT(); if( tok != T_effects )
} Expecting( T_effects );
else if( tok != T_RIGHT ) parseTextEffects( &me->footprint.effects );
Expecting( ") | effects" ); NeedRIGHT();
break; }
else if( tok != T_RIGHT )
Expecting( ") | effects" );
break;
case T_datasheet: case T_datasheet:
if( contains & PB(MODEL) ) if( contains & PB(MODEL) )
Duplicate( tok ); Duplicate( tok );
contains |= PB(MODEL); contains |= PB(MODEL);
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
me->datasheet.text = FromUTF8(); me->datasheet.text = FromUTF8();
tok = NextTok();
if( tok == T_LEFT )
{
tok = NextTok(); tok = NextTok();
if( tok != T_effects ) if( tok == T_LEFT )
Expecting( T_effects ); {
parseTextEffects( &me->datasheet.effects ); tok = NextTok();
NeedRIGHT(); if( tok != T_effects )
} Expecting( T_effects );
else if( tok != T_RIGHT ) parseTextEffects( &me->datasheet.effects );
Expecting( ") | effects" ); NeedRIGHT();
break; }
else if( tok != T_RIGHT )
Expecting( ") | effects" );
break;
case T_model: case T_model:
if( contains & PB(MODEL) ) if( contains & PB(MODEL) )
Duplicate( tok ); Duplicate( tok );
contains |= PB(MODEL); contains |= PB(MODEL);
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
me->model.text = FromUTF8(); me->model.text = FromUTF8();
tok = NextTok();
if( tok == T_LEFT )
{
tok = NextTok(); tok = NextTok();
if( tok != T_effects ) if( tok == T_LEFT )
Expecting( T_effects ); {
parseTextEffects( &me->model.effects ); tok = NextTok();
NeedRIGHT(); if( tok != T_effects )
} Expecting( T_effects );
else if( tok != T_RIGHT ) parseTextEffects( &me->model.effects );
Expecting( ") | effects" ); NeedRIGHT();
break; }
else if( tok != T_RIGHT )
Expecting( ") | effects" );
break;
case T_property: case T_property:
PROPERTY* property; PROPERTY* property;
property = new PROPERTY( me ); property = new PROPERTY( me );
// @todo check for uniqueness // @todo check for uniqueness
me->properties.push_back( property ); me->properties.push_back( property );
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
property->name = FromUTF8(); property->name = FromUTF8();
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
property->text = FromUTF8(); property->text = FromUTF8();
tok = NextTok();
if( tok == T_LEFT )
{
tok = NextTok(); tok = NextTok();
if( tok != T_effects ) if( tok == T_LEFT )
Expecting( T_effects ); {
parseTextEffects( &property->effects ); tok = NextTok();
if( tok != T_effects )
Expecting( T_effects );
parseTextEffects( &property->effects );
NeedRIGHT();
}
else if( tok != T_RIGHT )
Expecting( ") | effects" );
break;
case T_property_del:
NeedSYMBOLorNUMBER();
me->PropertyDelete( FromUTF8() );
NeedRIGHT(); NeedRIGHT();
} break;
else if( tok != T_RIGHT )
Expecting( ") | effects" );
break;
case T_pin: case T_pin:
PIN* pin; PIN* pin;
pin = new PIN( me ); pin = new PIN( me );
me->pins.push_back( pin ); me->pins.push_back( pin );
parsePin( pin ); parsePin( pin );
break; break;
case T_keywords:
parseKeywords( me );
break;
/* /*
@todo @todo
case T_keywords:
break;
case T_alternates: // do we want to inherit alternates?
break; case T_alternates:
break;
case T_property_del: case T_pin_merge:
break; break;
case T_pin_merge: case T_pin_swap:
break; break;
case T_pin_swap: case T_pin_renum:
break; break;
case T_pin_renum: case T_pin_rename:
break; break;
case T_pin_rename: case T_route_pin_swap:
break; break;
case T_route_pin_swap: */
break; }
}
*/ else
{
switch( tok )
{
default:
Unexpected( tok );
}
} }
} }
...@@ -413,6 +425,21 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E ...@@ -413,6 +425,21 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
} }
void SWEET_PARSER::parseKeywords( PART* me )
{
T tok;
while( ( tok = NextTok() ) != T_RIGHT )
{
if( !IsSymbol( tok ) && tok!=T_NUMBER )
Expecting( "symbol|number" );
// just insert them, duplicates are silently removed and tossed.
me->keywords.insert( FromUTF8() );
}
}
void SWEET_PARSER::parseFont( FONT* me ) void SWEET_PARSER::parseFont( FONT* me )
{ {
/* /*
...@@ -436,7 +463,7 @@ void SWEET_PARSER::parseFont( FONT* me ) ...@@ -436,7 +463,7 @@ void SWEET_PARSER::parseFont( FONT* me )
tok = NextTok(); tok = NextTok();
} }
while( tok != T_RIGHT ) for( ; tok != T_RIGHT; tok = NextTok() )
{ {
if( tok == T_LEFT ) if( tok == T_LEFT )
{ {
...@@ -483,8 +510,6 @@ void SWEET_PARSER::parseFont( FONT* me ) ...@@ -483,8 +510,6 @@ void SWEET_PARSER::parseFont( FONT* me )
Unexpected( "bold|italic" ); Unexpected( "bold|italic" );
} }
} }
tok = NextTok();
} }
} }
...@@ -681,7 +706,7 @@ void SWEET_PARSER::parseTextEffects( TEXT_EFFECTS* me ) ...@@ -681,7 +706,7 @@ void SWEET_PARSER::parseTextEffects( TEXT_EFFECTS* me )
/* /*
(effects [PROPERTY] (effects [PROPERTY]
# Position requires an X and Y coordinates. Position coordinates can be # Position requires X and Y coordinates. Position coordinates can be
# non-intergr. Angle is in degrees and defaults to 0 if not defined. # non-intergr. Angle is in degrees and defaults to 0 if not defined.
(at X Y [ANGLE]) (at X Y [ANGLE])
...@@ -709,7 +734,7 @@ void SWEET_PARSER::parseTextEffects( TEXT_EFFECTS* me ) ...@@ -709,7 +734,7 @@ void SWEET_PARSER::parseTextEffects( TEXT_EFFECTS* me )
tok = NextTok(); tok = NextTok();
} }
while( tok != T_RIGHT ) for( ; tok != T_RIGHT; tok = NextTok() )
{ {
if( tok != T_LEFT ) if( tok != T_LEFT )
Expecting( T_LEFT ); Expecting( T_LEFT );
...@@ -743,8 +768,6 @@ void SWEET_PARSER::parseTextEffects( TEXT_EFFECTS* me ) ...@@ -743,8 +768,6 @@ void SWEET_PARSER::parseTextEffects( TEXT_EFFECTS* me )
default: default:
Expecting( "at|font|visible" ); Expecting( "at|font|visible" );
} }
tok = NextTok();
} }
} }
......
...@@ -28,6 +28,16 @@ ...@@ -28,6 +28,16 @@
#include <utf8.h> #include <utf8.h>
#include <sweet_lexer.h> #include <sweet_lexer.h>
#define INTERNAL_PER_LOGICAL 10000 ///< no. internal units per logical unit
static inline double InternalToLogical( int aCoord )
{
return double( aCoord ) / INTERNAL_PER_LOGICAL;
}
class POINT; class POINT;
namespace SCH { namespace SCH {
...@@ -80,6 +90,7 @@ class SWEET_PARSER : public SWEET_LEXER ...@@ -80,6 +90,7 @@ class SWEET_PARSER : public SWEET_LEXER
void parseFont( FONT* me ); void parseFont( FONT* me );
void parsePinText( PINTEXT* me ); void parsePinText( PINTEXT* me );
void parseTextEffects( TEXT_EFFECTS* me ); void parseTextEffects( TEXT_EFFECTS* me );
void parseKeywords( PART* me );
public: public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment