Sim: Output more descriptive parsing errors
This commit is contained in:
parent
5f85c3b8b9
commit
5fa0a1a064
|
@ -44,7 +44,7 @@ namespace NETLIST_EXPORTER_SPICE_PARSER
|
|||
{
|
||||
using namespace SPICE_GRAMMAR;
|
||||
|
||||
struct textGrammar : spiceSourceGrammar {};
|
||||
struct textGrammar : must<spiceSourceNothrow> {};
|
||||
|
||||
template <typename Rule> struct textSelector : std::false_type {};
|
||||
template <> struct textSelector<modelUnit> : std::true_type {};
|
||||
|
@ -204,7 +204,8 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
|
|||
try
|
||||
{
|
||||
root = tao::pegtl::parse_tree::parse<NETLIST_EXPORTER_SPICE_PARSER::textGrammar,
|
||||
NETLIST_EXPORTER_SPICE_PARSER::textSelector>
|
||||
NETLIST_EXPORTER_SPICE_PARSER::textSelector,
|
||||
NETLIST_EXPORTER_SPICE_PARSER::control>
|
||||
( in );
|
||||
}
|
||||
catch( const tao::pegtl::parse_error& e )
|
||||
|
|
|
@ -35,8 +35,7 @@ namespace SIM_LIBRARY_SPICE_PARSER
|
|||
using namespace SPICE_GRAMMAR;
|
||||
|
||||
// TODO: unknownLine is already handled in spiceUnit.
|
||||
struct library : spiceSource {};
|
||||
struct libraryGrammar : must<library> {};
|
||||
struct libraryGrammar : spiceSourceGrammar {};
|
||||
|
||||
|
||||
template <typename Rule> struct librarySelector : std::false_type {};
|
||||
|
@ -57,7 +56,9 @@ void SIM_LIBRARY_SPICE::ReadFile( const wxString& aFilePath )
|
|||
{
|
||||
tao::pegtl::file_input in( aFilePath.ToStdString() );
|
||||
auto root = tao::pegtl::parse_tree::parse<SIM_LIBRARY_SPICE_PARSER::libraryGrammar,
|
||||
SIM_LIBRARY_SPICE_PARSER::librarySelector>
|
||||
SIM_LIBRARY_SPICE_PARSER::librarySelector,
|
||||
tao::pegtl::nothing,
|
||||
SIM_LIBRARY_SPICE_PARSER::control>
|
||||
( in );
|
||||
|
||||
SIM_LIBRARY::ReadFile( aFilePath );
|
||||
|
|
|
@ -390,7 +390,8 @@ TYPE SIM_MODEL::ReadTypeFromSpiceCode( const wxString& aSpiceCode )
|
|||
try
|
||||
{
|
||||
root = tao::pegtl::parse_tree::parse<SIM_MODEL_SPICE_PARSER::spiceUnitGrammar,
|
||||
SIM_MODEL_SPICE_PARSER::spiceUnitSelector>
|
||||
SIM_MODEL_SPICE_PARSER::spiceUnitSelector,
|
||||
SIM_MODEL_SPICE_PARSER::control>
|
||||
( in );
|
||||
}
|
||||
catch( const tao::pegtl::parse_error& e )
|
||||
|
@ -853,7 +854,8 @@ void SIM_MODEL::ReadSpiceCode( const wxString& aSpiceCode )
|
|||
try
|
||||
{
|
||||
root = tao::pegtl::parse_tree::parse<SIM_MODEL_SPICE_PARSER::spiceUnitGrammar,
|
||||
SIM_MODEL_SPICE_PARSER::spiceUnitSelector>
|
||||
SIM_MODEL_SPICE_PARSER::spiceUnitSelector,
|
||||
SIM_MODEL_SPICE_PARSER::control>
|
||||
( in );
|
||||
}
|
||||
catch( tao::pegtl::parse_error& e )
|
||||
|
|
|
@ -87,7 +87,6 @@ namespace SIM_MODEL_GRAMMAR
|
|||
opt<sep>,
|
||||
sor<quotedString,
|
||||
unquotedString>> {};
|
||||
|
||||
struct fieldParamValuePairs : list<fieldParamValuePair, sep> {};
|
||||
struct fieldParamValuePairsGrammar : must<opt<sep>,
|
||||
opt<fieldParamValuePairs>,
|
||||
|
|
|
@ -81,7 +81,8 @@ void SIM_MODEL_SUBCKT::ReadSpiceCode( const wxString& aSpiceCode )
|
|||
try
|
||||
{
|
||||
root = tao::pegtl::parse_tree::parse<SIM_MODEL_SUBCKT_SPICE_PARSER::spiceUnitGrammar,
|
||||
SIM_MODEL_SUBCKT_SPICE_PARSER::spiceUnitSelector>
|
||||
SIM_MODEL_SUBCKT_SPICE_PARSER::spiceUnitSelector,
|
||||
SIM_MODEL_SUBCKT_SPICE_PARSER::control>
|
||||
( in );
|
||||
}
|
||||
catch( const tao::pegtl::parse_error& e )
|
||||
|
|
|
@ -88,6 +88,10 @@ namespace SPICE_GRAMMAR
|
|||
struct sep : sor<plus<continuation>,
|
||||
garbage> {};
|
||||
|
||||
struct modelName : plus<not_at<garbage>, any> {};
|
||||
|
||||
struct dotModelType : plus<alpha> {};
|
||||
|
||||
// Ngspice has some heuristic logic to allow + and - in tokens. We replicate that here.
|
||||
struct tokenStart : seq<opt<one<'+', '-'>>,
|
||||
opt<seq<star<sor<tao::pegtl::digit,
|
||||
|
@ -108,25 +112,20 @@ namespace SPICE_GRAMMAR
|
|||
sep,
|
||||
paramValue> {};
|
||||
struct paramValuePairs : list<paramValuePair, sep> {};
|
||||
|
||||
struct modelName : plus<not_at<garbage>, any> {};
|
||||
|
||||
struct dotModelType : plus<alpha> {};
|
||||
struct dotModel : seq<opt<sep>,
|
||||
TAO_PEGTL_ISTRING( ".model" ),
|
||||
sep,
|
||||
modelName,
|
||||
sep,
|
||||
dotModelType,
|
||||
opt<sep,
|
||||
paramValuePairs>,
|
||||
opt<sep>,
|
||||
newline> {};
|
||||
if_must<TAO_PEGTL_ISTRING( ".model" ),
|
||||
sep,
|
||||
modelName,
|
||||
sep,
|
||||
dotModelType,
|
||||
opt<sep,
|
||||
paramValuePairs>,
|
||||
opt<sep>,
|
||||
newline>> {};
|
||||
|
||||
|
||||
struct dotSubcktPinName : seq<not_at<TAO_PEGTL_ISTRING( "params:" )>,
|
||||
plus<not_at<space>,
|
||||
any>> {};
|
||||
plus<not_at<space>, any>> {};
|
||||
struct dotSubcktPinSequence : list<dotSubcktPinName, sep> {};
|
||||
struct dotSubcktParams : seq<TAO_PEGTL_ISTRING( "params:" ),
|
||||
sep,
|
||||
|
@ -135,23 +134,24 @@ namespace SPICE_GRAMMAR
|
|||
until<newline>> {};
|
||||
struct spiceUnit;
|
||||
struct dotSubckt : seq<opt<sep>,
|
||||
TAO_PEGTL_ISTRING( ".subckt" ),
|
||||
sep,
|
||||
modelName,
|
||||
opt<sep,
|
||||
dotSubcktPinSequence>,
|
||||
opt<sep,
|
||||
dotSubcktParams>,
|
||||
opt<sep>,
|
||||
newline,
|
||||
until<dotSubcktEnd,
|
||||
spiceUnit>> {};
|
||||
if_must<TAO_PEGTL_ISTRING( ".subckt" ),
|
||||
sep,
|
||||
modelName,
|
||||
opt<sep,
|
||||
dotSubcktPinSequence>,
|
||||
opt<sep,
|
||||
dotSubcktParams>,
|
||||
opt<sep>,
|
||||
newline,
|
||||
until<dotSubcktEnd,
|
||||
spiceUnit>>> {};
|
||||
|
||||
|
||||
struct modelUnit : sor<dotModel,
|
||||
dotSubckt> {};
|
||||
|
||||
|
||||
// Intentionally no if_must<>.
|
||||
struct dotControl : seq<opt<sep>,
|
||||
TAO_PEGTL_ISTRING( ".control" ),
|
||||
until<TAO_PEGTL_ISTRING( ".endc" )>,
|
||||
|
@ -159,6 +159,7 @@ namespace SPICE_GRAMMAR
|
|||
|
||||
|
||||
struct dotTitleTitle : star<not_at<newline>, any> {};
|
||||
// Intentionally no if_must<>.
|
||||
struct dotTitle : seq<opt<sep>,
|
||||
TAO_PEGTL_ISTRING( ".title" ),
|
||||
sep,
|
||||
|
@ -169,6 +170,7 @@ namespace SPICE_GRAMMAR
|
|||
struct dotIncludePathWithoutQuotes : star<not_one<'"'>> {};
|
||||
struct dotIncludePathWithoutApostrophes : star<not_one<'\''>> {};
|
||||
struct dotIncludePath : star<not_at<newline>, any> {};
|
||||
// Intentionally no if_must<>.
|
||||
struct dotInclude : seq<opt<sep>,
|
||||
TAO_PEGTL_ISTRING( ".include" ),
|
||||
sep,
|
||||
|
@ -183,6 +185,13 @@ namespace SPICE_GRAMMAR
|
|||
newline> {};
|
||||
|
||||
|
||||
// Intentionally no if_must<>.
|
||||
struct dotLine : seq<opt<sep>,
|
||||
one<'.'>,
|
||||
until<newline>> {};
|
||||
|
||||
|
||||
// Intentionally no if_must<>.
|
||||
struct kLine : seq<opt<sep>,
|
||||
one<'K'>,
|
||||
until<sep>,
|
||||
|
@ -192,12 +201,8 @@ namespace SPICE_GRAMMAR
|
|||
until<sep>,
|
||||
until<newline>> {};
|
||||
|
||||
|
||||
struct dotLine : seq<opt<sep>,
|
||||
one<'.'>,
|
||||
until<newline>> {};
|
||||
|
||||
struct unknownLine : seq<plus<not_at<newline>, any>, until<newline>> {};
|
||||
struct unknownLine : seq<plus<not_at<newline>, any>,
|
||||
until<newline>> {};
|
||||
|
||||
|
||||
struct spiceUnit : sor<modelUnit,
|
||||
|
@ -212,7 +217,36 @@ namespace SPICE_GRAMMAR
|
|||
|
||||
|
||||
struct spiceSource : star<spiceUnit> {};
|
||||
struct spiceSourceGrammar : must<spiceSource> {};
|
||||
struct spiceSourceNothrow : star<try_catch<spiceUnit>> {};
|
||||
struct spiceSourceGrammar : spiceSource {};
|
||||
|
||||
|
||||
template <typename> inline constexpr const char* errorMessage = nullptr;
|
||||
template <> inline constexpr auto errorMessage<newline> =
|
||||
"expected newline not followed by a line continuation";
|
||||
template <> inline constexpr auto errorMessage<sep> =
|
||||
"expected token separator (typ. one or more whitespace, parenthesis, '=', ',', line continuation)";
|
||||
template <> inline constexpr auto errorMessage<opt<sep>> = "";
|
||||
template <> inline constexpr auto errorMessage<modelName> = "expected model name";
|
||||
template <> inline constexpr auto errorMessage<dotModelType> = "expected model type";
|
||||
template <> inline constexpr auto errorMessage<opt<sep,
|
||||
paramValuePairs>> = "";
|
||||
template <> inline constexpr auto errorMessage<opt<sep,
|
||||
dotSubcktPinSequence>> = "";
|
||||
template <> inline constexpr auto errorMessage<opt<sep,
|
||||
dotSubcktParams>> = "";
|
||||
template <> inline constexpr auto errorMessage<until<dotSubcktEnd,
|
||||
spiceUnit>> =
|
||||
"expected a (possibly empty) sequence of Spice lines followed by an .ends line";
|
||||
|
||||
// We create a custom PEGTL control to modify the parser error messages.
|
||||
struct error
|
||||
{
|
||||
template <typename Rule> static constexpr bool raise_on_failure = false;
|
||||
template <typename Rule> static constexpr auto message = errorMessage<Rule>;
|
||||
};
|
||||
|
||||
template <typename Rule> using control = must_if<error>::control<Rule>;
|
||||
}
|
||||
|
||||
#endif // SPICE_GRAMMAR_H
|
||||
|
|
Loading…
Reference in New Issue