Remove attempting to parse SPICE text items when generating netlists.

We don't do anything with the parse tree, and we have to check it for
directives again afterwards to account for when our parsing failed, so
there's not much point in parsing it to begin with.
This commit is contained in:
Jeff Young 2023-01-12 23:39:12 +00:00
parent dc9aaf7844
commit d8867b7a66
2 changed files with 53 additions and 40 deletions

View File

@ -46,12 +46,15 @@
#include <dialogs/html_message_box.h> #include <dialogs/html_message_box.h>
#include <fmt/core.h> #include <fmt/core.h>
#include <paths.h> #include <paths.h>
#include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp>
#include <wx/dir.h> #include <wx/dir.h>
#include <locale_io.h> #include <locale_io.h>
#include "markup_parser.h" #include "markup_parser.h"
#if 0
#include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp>
namespace NETLIST_EXPORTER_SPICE_PARSER namespace NETLIST_EXPORTER_SPICE_PARSER
{ {
using namespace SPICE_GRAMMAR; using namespace SPICE_GRAMMAR;
@ -75,6 +78,7 @@ namespace NETLIST_EXPORTER_SPICE_PARSER
template <> struct textSelector<dotLine> : std::true_type {}; template <> struct textSelector<dotLine> : std::true_type {};
} }
#endif
std::string NAME_GENERATOR::Generate( const std::string& aProposedName ) std::string NAME_GENERATOR::Generate( const std::string& aProposedName )
@ -120,9 +124,6 @@ bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsign
// Cleanup list to avoid duplicate if the netlist exporter is run more than once. // Cleanup list to avoid duplicate if the netlist exporter is run more than once.
m_rawIncludes.clear(); m_rawIncludes.clear();
// Default title.
m_title = "KiCad schematic";
if( !ReadSchematicAndLibraries( aNetlistOptions, aReporter ) ) if( !ReadSchematicAndLibraries( aNetlistOptions, aReporter ) )
return false; return false;
@ -145,7 +146,7 @@ bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsign
void NETLIST_EXPORTER_SPICE::WriteHead( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ) void NETLIST_EXPORTER_SPICE::WriteHead( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
{ {
aFormatter.Print( 0, ".title %s\n", m_title.c_str() ); aFormatter.Print( 0, "KiCad schematic\n" );
} }
@ -380,46 +381,59 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
else else
continue; continue;
tao::pegtl::string_input<> in( text.ToUTF8(), "from_content" ); // Send anything that contains directives to SPICE
std::unique_ptr<tao::pegtl::parse_tree::node> root; wxStringTokenizer tokenizer( text, wxT( "\r\n" ), wxTOKEN_STRTOK );
bool foundDirective = false;
try while( tokenizer.HasMoreTokens() )
{ {
root = tao::pegtl::parse_tree::parse<NETLIST_EXPORTER_SPICE_PARSER::textGrammar, wxString line = tokenizer.GetNextToken().Upper();
NETLIST_EXPORTER_SPICE_PARSER::textSelector,
tao::pegtl::nothing,
NETLIST_EXPORTER_SPICE_PARSER::control>
( in );
}
catch( const tao::pegtl::parse_error& )
{
// Even if we couldn't parse it, send anything that _looks_ like it contains
// directives straight through to SPICE
wxStringTokenizer tokenizer( text, wxT( "\r\n" ), wxTOKEN_STRTOK );
while( tokenizer.HasMoreTokens() ) if( line.StartsWith( wxT( ".AC" ) )
|| line.StartsWith( wxT( ".CONTROL" ) )
|| line.StartsWith( wxT( ".CSPARAM" ) )
|| line.StartsWith( wxT( ".DISTO" ) )
|| line.StartsWith( wxT( ".ELSE" ) )
|| line.StartsWith( wxT( ".ELSEIF" ) )
|| line.StartsWith( wxT( ".END" ) )
|| line.StartsWith( wxT( ".ENDC" ) )
|| line.StartsWith( wxT( ".ENDIF" ) )
|| line.StartsWith( wxT( ".ENDS" ) )
|| line.StartsWith( wxT( ".FOUR" ) )
|| line.StartsWith( wxT( ".FUNC" ) )
|| line.StartsWith( wxT( ".GLOBAL" ) )
|| line.StartsWith( wxT( ".IC" ) )
|| line.StartsWith( wxT( ".IF" ) )
|| line.StartsWith( wxT( ".INCLUDE" ) )
|| line.StartsWith( wxT( ".LIB" ) )
|| line.StartsWith( wxT( ".MEAS" ) )
|| line.StartsWith( wxT( ".MODEL" ) )
|| line.StartsWith( wxT( ".NODESET" ) )
|| line.StartsWith( wxT( ".NOISE" ) )
|| line.StartsWith( wxT( ".OP" ) )
|| line.StartsWith( wxT( ".OPTIONS" ) )
|| line.StartsWith( wxT( ".PARAM" ) )
|| line.StartsWith( wxT( ".PLOT" ) )
|| line.StartsWith( wxT( ".PRINT" ) )
|| line.StartsWith( wxT( ".PROBE" ) )
|| line.StartsWith( wxT( ".PZ" ) )
|| line.StartsWith( wxT( ".SAVE" ) )
|| line.StartsWith( wxT( ".SENS" ) )
|| line.StartsWith( wxT( ".SP" ) )
|| line.StartsWith( wxT( ".SUBCKT" ) )
|| line.StartsWith( wxT( ".TEMP" ) )
|| line.StartsWith( wxT( ".TF" ) )
|| line.StartsWith( wxT( ".TITLE" ) )
|| line.StartsWith( wxT( ".TRAN" ) )
|| line.StartsWith( wxT( ".WIDTH" ) ) )
{ {
wxString line = tokenizer.GetNextToken(); foundDirective = true;
break;
if( line.StartsWith( "." ) )
{
m_directives.emplace_back( text );
break;
}
} }
continue;
} }
wxASSERT( root ); if( foundDirective )
m_directives.emplace_back( text );
for( const auto& node : root->children )
{
if( node->is_type<NETLIST_EXPORTER_SPICE_PARSER::dotTitle>() )
m_title = node->children.at( 0 )->string();
else
m_directives.emplace_back( node->string() );
}
} }
} }
} }

View File

@ -153,7 +153,6 @@ private:
SIM_LIB_MGR m_libMgr; ///< Holds libraries and models SIM_LIB_MGR m_libMgr; ///< Holds libraries and models
NAME_GENERATOR m_modelNameGenerator; ///< Generates unique model names NAME_GENERATOR m_modelNameGenerator; ///< Generates unique model names
NAME_GENERATOR m_netNameGenerator; ///< Generates unique net names (only unique for NC nets for now) NAME_GENERATOR m_netNameGenerator; ///< Generates unique net names (only unique for NC nets for now)
std::string m_title; ///< Spice simulation title found in the schematic sheet
std::vector<std::string> m_directives; ///< Spice directives found in the schematic sheet std::vector<std::string> m_directives; ///< Spice directives found in the schematic sheet
//std::map<std::string, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries //std::map<std::string, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries
std::set<wxString> m_rawIncludes; ///< include directives found in symbols std::set<wxString> m_rawIncludes; ///< include directives found in symbols