complete initial version of LIB_TABLE::Parse()

This commit is contained in:
Dick Hollenbeck 2010-12-27 15:22:12 -06:00
parent 364132cbe1
commit bdbd28a9f4
11 changed files with 282 additions and 80 deletions

View File

@ -144,9 +144,6 @@ set( sourceFileHeader
* your DSN lexer.
*/
//#include \"fctsys.h\"
//#include \"macros.h\"
#include \"${result}_lexer.h\"
namespace DSN {
@ -228,13 +225,13 @@ class ${RESULT}_LEXER : public DSNLEXER
public:
/**
* Constructor ${RESULT}_LEXER
* @param aClipboartTxt is std::string (8 bit) text possibly from the
* clipboard that you want to parse.
* @param aSExpression is (utf8) text possibly from the clipboard that you want to parse.
* @param aSource is a description of the origin of @a aSExpression, such as a filename.
* If left empty, then _("clipboard") is used.
*/
${RESULT}_LEXER( const std::string& aClipboardTxt ) :
DSNLEXER( aClipboardTxt,
DSN::${result}_keywords,
DSN::${result}_keyword_count )
${RESULT}_LEXER( const std::string& aSExpression, const wxString& aSource = wxEmptyString ) :
DSNLEXER( DSN::${result}_keywords, DSN::${result}_keyword_count,
aSExpression, aSource )
{
}
@ -248,9 +245,8 @@ public:
* @param aFilename is the name of the opened file, needed for error reporting.
*/
${RESULT}_LEXER( FILE* aFile, const wxString& aFilename ) :
DSNLEXER( aFile, aFilename,
DSN::${result}_keywords,
DSN::${result}_keyword_count )
DSNLEXER( DSN::${result}_keywords, DSN::${result}_keyword_count,
aFile, aFilename )
{
}

View File

@ -32,8 +32,8 @@
#include "dsnlexer.h"
#include "fctsys.h"
#include "pcbnew.h"
//#include "fctsys.h"
//#include "pcbnew.h"
//#define STANDALONE 1 // enable this for stand alone testing.
@ -60,8 +60,8 @@ void DSNLEXER::init()
}
DSNLEXER::DSNLEXER( FILE* aFile, const wxString& aFilename,
const KEYWORD* aKeywordTable, unsigned aKeywordCount ) :
DSNLEXER::DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
FILE* aFile, const wxString& aFilename ) :
keywords( aKeywordTable ),
keywordCount( aKeywordCount )
{
@ -71,12 +71,13 @@ DSNLEXER::DSNLEXER( FILE* aFile, const wxString& aFilename,
}
DSNLEXER::DSNLEXER( const std::string& aClipboardTxt,
const KEYWORD* aKeywordTable, unsigned aKeywordCount ) :
DSNLEXER::DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
const std::string& aClipboardTxt, const wxString& aSource ) :
keywords( aKeywordTable ),
keywordCount( aKeywordCount )
{
STRING_LINE_READER* stringReader = new STRING_LINE_READER( aClipboardTxt, _( "clipboard" ) );
STRING_LINE_READER* stringReader = new STRING_LINE_READER( aClipboardTxt, aSource.IsEmpty() ?
wxString( _( "clipboard" ) ) : aSource );
PushReader( stringReader );
init();
}
@ -206,7 +207,7 @@ wxString DSNLEXER::GetTokenString( int aTok )
{
wxString ret;
ret << wxT("'") << CONV_FROM_UTF8( GetTokenText(aTok) ) << wxT("'");
ret << wxT("'") << wxConvertMB2WX( GetTokenText(aTok) ) << wxT("'");
return ret;
}
@ -300,6 +301,7 @@ int DSNLEXER::NeedSYMBOLorNUMBER() throw( IO_ERROR )
return tok;
}
/**
* Function isspace
* strips the upper bits of the int to ensure the value passed to ::isspace() is

View File

@ -22,8 +22,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _DSNLEXER_H
#define _DSNLEXER_H
#ifndef DSNLEXER_H_
#define DSNLEXER_H_
#include <cstdio>
#include <string>
@ -162,12 +162,14 @@ public:
* @param aKeywordTable is an array of KEYWORDS holding \a aKeywordCount. This
* token table need not contain the lexer separators such as '(' ')', etc.
* @param aKeywordTable is the count of tokens in aKeywordTable.
* @param aFile is an open file, which will be closed when this is destructed.
* @param aFileName is the name of the file
*/
DSNLEXER( FILE* aFile, const wxString& aFilename,
const KEYWORD* aKeywordTable, unsigned aKeywordCount );
DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
FILE* aFile, const wxString& aFileName );
DSNLEXER( const std::string& aClipboardTxt,
const KEYWORD* aKeywordTable, unsigned aKeywordCount );
DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
const std::string& aClipboardTxt, const wxString& aSource = wxEmptyString );
~DSNLEXER()
{
@ -418,4 +420,4 @@ public:
}
};
#endif // _DSNLEXER_H
#endif // DSNLEXER_H_

View File

@ -196,7 +196,7 @@ public:
* The last line does not necessarily need a trailing '\n'.
*
* @param aSource describes the source of aString for error reporting purposes
* can be anything meaninful, such as wxT( "cliboard" ).
* can be anything meaninful, such as wxT( "clipboard" ).
*/
STRING_LINE_READER( const std::string& aString, const wxString& aSource ) :
LINE_READER( LINE_READER_LINE_DEFAULT_MAX ),

View File

@ -60,14 +60,22 @@ endif()
include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )
add_executable( test_dir_lib_source sch_dir_lib_source.cpp )
add_executable( test_dir_lib_source
sch_dir_lib_source.cpp
)
target_link_libraries( test_dir_lib_source ${wxWidgets_LIBRARIES} )
add_executable( test_lib_table sch_lib_table.cpp sch_lib_table_keywords.cpp )
target_link_libraries( test_lib_table ${wxWidgets_LIBRARIES} )
add_executable( test_sch_lib_table
sch_lib_table.cpp
sch_lib_table_keywords.cpp
sch_lib.cpp
${PROJECT_SOURCE_DIR}/common/richio.cpp
${PROJECT_SOURCE_DIR}/common/dsnlexer.cpp
)
target_link_libraries( test_sch_lib_table ${wxWidgets_LIBRARIES} )
add_executable( test_sch_part sch_part.cpp )
target_link_libraries( test_lib_table ${wxWidgets_LIBRARIES} )
target_link_libraries( test_sch_part ${wxWidgets_LIBRARIES} )
make_lexer(

View File

@ -151,14 +151,14 @@ public:
* tree, otherwise only a single version of each part is recognized, namely the
* one without the ".revN[N..]" trailer.
*/
DIR_LIB_SOURCE( const STRING& aDirectoryPath, const STRING& aOptions = StrEmpty )
DIR_LIB_SOURCE( const STRING& aDirectoryPath, const STRING& aOptions = "" )
throw( IO_ERROR );
~DIR_LIB_SOURCE();
//-----<LIB_SOURCE implementation functions >------------------------------
void ReadPart( STRING* aResult, const STRING& aPartName, const STRING& aRev = StrEmpty )
void ReadPart( STRING* aResult, const STRING& aPartName, const STRING& aRev = "" )
throw( IO_ERROR );
void ReadParts( STRINGS* aResults, const STRINGS& aPartNames )
@ -166,7 +166,7 @@ public:
void GetCategories( STRINGS* aResults ) throw( IO_ERROR );
void GetCategoricalPartNames( STRINGS* aResults, const STRING& aCategory = StrEmpty )
void GetCategoricalPartNames( STRINGS* aResults, const STRING& aCategory = "" )
throw( IO_ERROR );
void GetRevisions( STRINGS* aResults, const STRING& aPartName ) throw( IO_ERROR )

45
new/sch_lib.cpp Normal file
View File

@ -0,0 +1,45 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sch_lib.h>
using namespace SCH;
LIB::LIB( const STRING& aLogicalLibrary, LIB_SOURCE* aSource, LIB_SINK* aSink ) :
name( aLogicalLibrary ),
source( aSource ),
sink( aSink )
{
}
LIB::~LIB()
{
delete source;
delete sink;
}

View File

@ -207,7 +207,7 @@ protected:
*/
class LIB
{
friend class LIBS; ///< the LIB factory is LIBS::GetLibrary()
friend class LIB_TABLE; ///< the LIB factory is LIB_TABLE
protected: // constructor is not public, called from LIBS only.
@ -224,21 +224,11 @@ protected: // constructor is not public, called from LIBS only.
* @param aSink is an open LIB_SINK whose ownership is given over
* to this LIB, and it is normally NULL.
*/
LIB( const STRING& aLogicalLibrary, LIB_SOURCE* aSource, LIB_SINK* aSink=NULL ) :
name( aLogicalLibrary ),
source( aSource ),
sink( aSink )
{
}
LIB( const STRING& aLogicalLibrary, LIB_SOURCE* aSource, LIB_SINK* aSink = NULL );
public:
~LIB()
{
delete source;
delete sink;
}
~LIB();
/**
* Function HasSink
@ -294,9 +284,9 @@ public:
* saves the part to non-volatile storage and returns the next new revision
* name in the sequence established by the LIB_SINK.
*/
virtual STRING WritePart( PART* aPart ) throw( IO_ERROR );
STRING WritePart( PART* aPart ) throw( IO_ERROR );
virtual void SetPartBody( PART* aPart, const STRING& aSExpression ) throw( IO_ERROR );
void SetPartBody( PART* aPart, const STRING& aSExpression ) throw( IO_ERROR );
/**
* Function GetRevisions
@ -346,6 +336,4 @@ protected:
} // namespace SCH
const STRING StrEmpty = "";
#endif // SCH_LIB_H_

View File

@ -22,10 +22,158 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sch_lib_table.h>
#include <sch_lib_table.h>
#include <sch_lib_table_lexer.h>
using namespace std;
using namespace SCH;
LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable )
{
if( aFallBackTable )
{
const ROWS& t = aFallBackTable->rows;
for( ROWS_CITER it = t.begin(); it != t.end(); ++it )
{
// our rows are empty, expect no collisions here
auto_ptr<ROW> row( new ROW( *it ) );
row->owner = this;
rows.insert( row.release() );
}
}
}
void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
{
/* grammar:
(lib_table
(lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
(lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
(lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
)
note: "(lib_table" has already been read in.
*/
ELT_T tok;
while( (tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
{
// (lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
if( tok != T_LEFT )
in->Expecting( T_LEFT );
if( ( tok = in->NextTok() ) != T_lib )
in->Expecting( T_lib );
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_logical )
in->Expecting( T_logical );
in->NeedSYMBOLorNUMBER();
auto_ptr<ROW> row( new ROW( this ) );
row->SetLogicalName( in->CurText() );
in->NeedRIGHT();
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_type )
in->Expecting( T_type );
in->NeedSYMBOLorNUMBER();
// verify that type is one of: {dir, schematic, subversion, http}
if( strcmp( in->CurText(), "dir" ) &&
strcmp( in->CurText(), "schematic" ) &&
strcmp( in->CurText(), "subversion" ) &&
strcmp( in->CurText(), "http" ) )
{
in->Expecting( wxT( "dir|schematic|subversion|http" ) );
}
row->SetType( in->CurText() );
in->NeedRIGHT();
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_full_uri )
in->Expecting( T_full_uri );
in->NeedSYMBOLorNUMBER();
row->SetFullURI( in->CurText() );
in->NeedRIGHT();
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_options )
in->Expecting( T_options );
in->NeedSYMBOLorNUMBER();
row->SetOptions( in->CurText() );
in->NeedRIGHT();
in->NeedRIGHT(); // teriminate the (lib..)
rows.insert( row.release() );
}
return;
}
#if 1
int main( int argc, char** argv )
{
// the null string is not really a legal DSN token since any double quotes
// as assumed to be a single quote. To pass an empty string, we pass " "
// to (options " ")
SCH_LIB_TABLE_LEXER slr(
"(lib_table \n"
" (lib (logical meparts) (type dir) (full_uri /tmp/eeschema-lib) (options \" \"))\n"
" (lib (logical old-project) (type schematic)(full_uri /tmp/old-schematic.sch) (options \" \"))\n"
" (lib (logical www) (type http) (full_uri http://kicad.org/libs) (options \" \"))\n",
wxT( "inline text" ) // source
);
LIB_TABLE lib_table;
// read the "( lib_table" pair of tokens
try
{
slr.NextTok();
slr.NextTok();
lib_table.Parse( &slr );
}
catch( std::exception& ex )
{
printf( "std::exception\n" );
}
catch( IO_ERROR ioe )
{
printf( "caught\n" );
printf( "exception: %s\n", (const char*) wxConvertWX2MB( ioe.errorText ) );
}
lib_table.Show();
return 0;
}
#endif

View File

@ -29,12 +29,10 @@
#include <boost/ptr_container/ptr_set.hpp>
#include <sch_lib.h>
class SCH_LIB_TABLE_LEXER; // outside namespace SCH, since make_lexer() Functions.cmake can't do namespace
namespace SCH {
class LIB_TABLE_LEXER;
/**
* Class LIB_TABLE
* holds LIB_TABLE::ROW records, and can be searched in a very high speed
@ -52,6 +50,8 @@ public:
*/
class ROW
{
friend class LIB_TABLE;
public:
bool operator<( const ROW& other ) const
@ -101,9 +101,18 @@ public:
delete lib;
}
#if defined(DEBUG)
void Show() const
{
printf( "(lib (logical \"%s\")(type \"%s\")(full_uri \"%s\")(options \"%s\"))\n",
logicalName.c_str(), libType.c_str(), fullURI.c_str(), options.c_str() );
}
#endif
protected:
ROW() :
ROW( LIB_TABLE* aOwner ) :
owner( aOwner ),
lib( 0 )
{}
@ -145,37 +154,28 @@ public:
}
private:
STRING logicalName;
STRING libType;
STRING fullURI;
STRING options;
LIB_TABLE* owner;
STRING logicalName;
STRING libType;
STRING fullURI;
STRING options;
LIB* lib;
LIB* lib;
};
/**
* Constructor LIB_TABLE
* builds a library table from an s-expression form of the library table.
* @param aLibraryTable is an s-expression form of all the rows in a library
* table fragment. These rows take presedence over rows in @a aFallBackTable.
* @param aFallBackTable is another LIB_TABLE which is searched only when
* a record is not found in this table.
* a record is not found in this table. No ownership is taken of aFallBackTable.
*/
LIB_TABLE( const STRING& aLibraryTable, LIB_TABLE* aFallBackTable = NULL )
throw( PARSE_ERROR )
{
// s-expression is chosen so we can read a table fragment from either
// a schematic or a disk file, for schematic resident or
// personal table, respectively.
}
LIB_TABLE( LIB_TABLE* aFallBackTable = NULL );
protected:
/**
* Function Parse
* fills this object from information in the input stream \a aSpec, which
* is a DSN_LEXER customized for the grammar needed to describe instances of this object.
* fills this object from information in the input stream \a aLexer, which
* is a DSNLEXER customized for the grammar needed to describe instances of this object.
* The entire textual element spec is <br>
* (lib_table (logical _yourfieldname_)(value _yourvalue_) visible))
*
@ -183,21 +183,33 @@ protected:
* (lib_table
* (lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS"))
* (lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS"))
(lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS"))
* (lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS"))
* </pre>
*
* When this function is called, the input token stream given by \a aSpec
* When this function is called, the input token stream given by \a aLexer
* is assumed to be positioned at the '^' in the following example, i.e. just after the
* identifying keyword and before the content specifying stuff.<br>
* (lib_table ^ (....) )
*
* @param aSpec is the input token stream of keywords and symbols.
*/
void Parse( LIB_TABLE_LEXER* aLexer ) throw( PARSE_ERROR );
void Parse( SCH_LIB_TABLE_LEXER* aLexer ) throw( IO_ERROR );
private:
#if defined(DEBUG)
void Show() const
{
printf("(lib_table\n" );
for( ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
it->Show();
printf(")\n" );
}
#endif
typedef boost::ptr_set<ROW> ROWS;
typedef ROWS::iterator ROWS_ITER;
typedef ROWS::const_iterator ROWS_CITER;
private:
ROWS rows;
};

View File

@ -3,3 +3,4 @@ logical
type
full_uri
options
lib