26#include <wx/translation.h>
29#include <pegtl/contrib/parse_tree.hpp>
35#define CALL_INSTANCE( ValueType, Notation, func, ... ) \
38 case SIM_VALUE::TYPE_INT: \
42 func<SIM_VALUE::TYPE_INT, NOTATION::SI>( __VA_ARGS__ ); \
45 case NOTATION::SPICE: \
46 func<SIM_VALUE::TYPE_INT, NOTATION::SPICE>( __VA_ARGS__ ); \
51 case SIM_VALUE::TYPE_FLOAT: \
55 func<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>( __VA_ARGS__ ); \
58 case NOTATION::SPICE: \
59 func<SIM_VALUE::TYPE_FLOAT, NOTATION::SPICE>( __VA_ARGS__ ); \
64 case SIM_VALUE::TYPE_BOOL: \
65 case SIM_VALUE::TYPE_COMPLEX: \
66 case SIM_VALUE::TYPE_STRING: \
67 case SIM_VALUE::TYPE_BOOL_VECTOR: \
68 case SIM_VALUE::TYPE_INT_VECTOR: \
69 case SIM_VALUE::TYPE_FLOAT_VECTOR: \
70 case SIM_VALUE::TYPE_COMPLEX_VECTOR: \
71 wxFAIL_MSG( "Unhandled SIM_VALUE type" ); \
80 template <
typename Rule>
118 NOTATION aNotation = NOTATION::SI );
122template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
123static inline void doIsValid( tao::pegtl::string_input<>& aIn )
125 tao::pegtl::parse<SIM_VALUE_PARSER::numberGrammar<ValueType, Notation>>( aIn );
132 tao::pegtl::string_input<> in( aString,
"from_content" );
138 catch(
const tao::pegtl::parse_error& )
147template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
148static inline std::unique_ptr<tao::pegtl::parse_tree::node>
doParse(
149 tao::pegtl::string_input<>& aIn )
151 return tao::pegtl::parse_tree::parse<SIM_VALUE_PARSER::numberGrammar<ValueType, Notation>,
157template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
166 for(
const auto& subnode : aNode.children )
171 aParseResult.
intPart = std::stoll( subnode->string() );
173 aParseResult.
fracPart = std::stoll( subnode->string() );
175 catch(
const std::exception& )
177 aParseResult.
isOk =
false;
183 aParseResult.
exponent = std::stoi( aNode.string() );
193 wxFAIL_MSG(
"Unhandled parse tree node" );
203 tao::pegtl::string_input<> in( aString,
"from_content" );
204 std::unique_ptr<tao::pegtl::parse_tree::node> root;
211 catch( tao::pegtl::parse_error& )
221 for(
const auto& node : root->children )
226 catch(
const std::invalid_argument& e )
228 wxFAIL_MSG( fmt::format(
"Parsing simulator value failed: {:s}", e.what() ) );
241 if( aPrefix.empty() )
246 case 'a':
return -18;
247 case 'f':
return -15;
248 case 'p':
return -12;
263 case NOTATION::SPICE:
264 std::transform( aPrefix.begin(), aPrefix.end(), aPrefix.begin(),
269 else if( aPrefix ==
"p" )
271 else if( aPrefix ==
"n" )
273 else if( aPrefix ==
"u" )
275 else if( aPrefix ==
"m" )
277 else if( aPrefix ==
"" )
279 else if( aPrefix ==
"k" )
281 else if( aPrefix ==
"meg" )
283 else if( aPrefix ==
"g" )
285 else if( aPrefix ==
"t" )
291 wxFAIL_MSG( fmt::format(
"Unknown simulator value suffix: '{:s}'", aPrefix ) );
299 if( aNotation == NOTATION::SI && aExponent >= -18 && aExponent <= -15 )
301 aExponentReduction = -18;
304 else if( aExponent >= -15 && aExponent < -12 )
306 aExponentReduction = -15;
309 else if( aExponent >= -12 && aExponent < -9 )
311 aExponentReduction = -12;
314 else if( aExponent >= -9 && aExponent < -6 )
316 aExponentReduction = -9;
319 else if( aExponent >= -6 && aExponent < -3 )
321 aExponentReduction = -6;
324 else if( aExponent >= -3 && aExponent < 0 )
326 aExponentReduction = -3;
329 else if( aExponent >= 0 && aExponent < 3 )
331 aExponentReduction = 0;
334 else if( aExponent >= 3 && aExponent < 6 )
336 aExponentReduction = 3;
339 else if( aExponent >= 6 && aExponent < 9 )
341 aExponentReduction = 6;
342 return ( aNotation == NOTATION::SI ) ?
"M" :
"Meg";
344 else if( aExponent >= 9 && aExponent < 12 )
346 aExponentReduction = 9;
349 else if( aExponent >= 12 && aExponent < 15 )
351 aExponentReduction = 12;
354 else if( aNotation == NOTATION::SI && aExponent >= 15 && aExponent < 18 )
356 aExponentReduction = 15;
359 else if( aNotation == NOTATION::SI && aExponent >= 18 && aExponent <= 21 )
361 aExponentReduction = 18;
365 aExponentReduction = 0;
373 wxString buf( aString );
374 buf.Replace(
',',
'.' );
387 int expReduction = 0;
392 return fmt::format(
"{:g}{}",
396 catch(
const std::invalid_argument& )
409 int expReduction = 0;
413 double reducedValue = aValue / std::pow( 10, expReduction );
415 return fmt::format(
"{:g}{}", reducedValue, prefix );
424 [](
const std::string& aStringVal )
426 for(
char c : aStringVal )
428 if( c !=
'.' && ( c <
'0' || c >
'9' ) )
435 if( plainNumber( aString ) )
457 catch(
const std::invalid_argument& )
489 return std::abs( aLH -
ToDouble( aRH ) ) <= std::numeric_limits<double>::epsilon();
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
static std::string Normalize(double aValue)
static bool Equal(double aLH, const std::string &aRH)
static std::string ConvertNotation(const std::string &aString, NOTATION aFromNotation, NOTATION aToNotation)
static double ToDouble(const std::string &aString, double aDefault=NAN)
static int ToInt(const std::string &aString, int aDefault=-1)
static std::string ToSpice(const std::string &aString)
bool IsValid(const std::string &aString, SIM_VALUE::TYPE aValueType=SIM_VALUE::TYPE_FLOAT, NOTATION aNotation=NOTATION::SI)
PARSE_RESULT Parse(const std::string &aString, NOTATION aNotation=NOTATION::SI, SIM_VALUE::TYPE aValueType=SIM_VALUE::TYPE_FLOAT)
int UnitPrefixToExponent(std::string aPrefix, NOTATION aNotation=NOTATION::SI)
std::string ExponentToUnitPrefix(double aExponent, int &aExponentReduction, NOTATION aNotation=NOTATION::SI)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
static void handleNodeForParse(tao::pegtl::parse_tree::node &aNode, SIM_VALUE_PARSER::PARSE_RESULT &aParseResult)
static std::unique_ptr< tao::pegtl::parse_tree::node > doParse(tao::pegtl::string_input<> &aIn)
#define CALL_INSTANCE(ValueType, Notation, func,...)
static void doIsValid(tao::pegtl::string_input<> &aIn)
std::optional< int64_t > fracPart
std::optional< int > unitPrefixExponent
std::optional< int > exponent
std::optional< int64_t > intPart