kicad/eeschema/sim/sim_serde.h

170 lines
7.2 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mikolaj Wielgus
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef SIM_SERDE_H
#define SIM_SERDE_H
#include <sim/sim_model.h>
namespace SIM_SERDE_GRAMMAR
{
using namespace SIM_VALUE_GRAMMAR;
struct sep : plus<space> {};
struct legacyPinNumber : digits {};
struct legacyPinSequence : list<legacyPinNumber, sep> {};
struct legacyPinSequenceGrammar : must<legacyPinSequence,
tao::pegtl::eof> {};
struct pinNumber : plus<not_at<sep>, any> {};
struct pinSequence : list<pinNumber, sep> {};
struct pinSequenceGrammar : must<opt<sep>,
opt<pinSequence>,
opt<sep>,
tao::pegtl::eof> {};
struct param : plus<alnum> {};
struct unquotedString : plus<not_at<sep>, any> {};
struct quotedStringContent : star<not_at<one<'"'>>, any> {}; // TODO: Allow escaping '"'.
struct quotedString : seq<one<'"'>,
quotedStringContent,
one<'"'>> {};
struct fieldParamValuePair : if_must<param,
opt<sep>,
one<'='>,
opt<sep>,
sor<quotedString,
unquotedString>> {};
struct fieldParamValuePairs : list<fieldParamValuePair, sep> {};
struct fieldParamValuePairsGrammar : must<opt<sep>,
opt<fieldParamValuePairs>,
opt<sep>,
tao::pegtl::eof> {};
struct fieldInferValueType : plus<upper> {};
struct fieldInferValuePrimaryValue : seq<// HACK: Because `number` matches empty string,
// ensure it is not empty.
at<sor<tao::pegtl::digit,
seq<one<'.'>>,
tao::pegtl::digit>>,
// END HACK.
number<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>,
// Hackish: match anything until param-value pairs.
// Because the user may want to write something like
// "10k 30% 30mW w=0.4", but we care only about the
// "10k" and "w=0.4".
star<not_at<sep,
try_catch<fieldParamValuePairs>>,
any>> {};
struct fieldInferValue : sor<seq<fieldInferValueType,
opt<sep,
fieldParamValuePairs>>,
seq<opt<fieldInferValuePrimaryValue>,
opt<sep>,
opt<fieldParamValuePairs>>> {};
struct fieldInferValueGrammar : must<opt<sep>,
fieldInferValue,
opt<sep>,
tao::pegtl::eof> {};
template <typename> inline constexpr const char* errorMessage = nullptr;
template <> inline constexpr auto errorMessage<opt<sep>> = "";
template <> inline constexpr auto errorMessage<opt<pinSequence>> = "";
template <> inline constexpr auto errorMessage<opt<sor<fieldInferValueType,
fieldInferValuePrimaryValue>>> = "";
template <> inline constexpr auto errorMessage<one<'='>> =
"expected '='";
template <> inline constexpr auto errorMessage<sor<quotedString,
unquotedString>> =
"expected quoted or unquoted string";
template <> inline constexpr auto errorMessage<fieldParamValuePairs> =
"expected parameter=value pairs";
template <> inline constexpr auto errorMessage<opt<fieldParamValuePairs>> = "";
template <> inline constexpr auto errorMessage<fieldInferValue> =
"expected parameter=value pairs, together possibly preceded by a type or primary value";
template <> inline constexpr auto errorMessage<tao::pegtl::eof> =
"expected end of string";
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>;
}
/**
* SerDe = Serializer-Deserializer
*/
class SIM_SERDE
{
public:
static constexpr auto REFERENCE_FIELD = "Reference";
static constexpr auto VALUE_FIELD = "Value";
static constexpr auto DEVICE_TYPE_FIELD = "Sim.Device";
static constexpr auto TYPE_FIELD = "Sim.Type";
static constexpr auto PINS_FIELD = "Sim.Pins";
static constexpr auto PARAMS_FIELD = "Sim.Params";
static constexpr auto ENABLE_FIELD = "Sim.Enable";
SIM_SERDE( SIM_MODEL& aModel ) : m_model( aModel ) {}
std::string GenerateDevice() const;
std::string GenerateType() const;
std::string GenerateValue() const;
std::string GenerateParams() const;
std::string GeneratePins() const;
std::string GenerateEnable() const;
SIM_MODEL::TYPE ParseDeviceAndType( const std::string& aDevice,
const std::string& aType );
void ParseValue( const std::string& aValue );
void ParseParams( const std::string& aParams );
void ParsePins( const std::string& aPins );
void ParseEnable( const std::string& aEnable );
static SIM_MODEL::TYPE InferTypeFromRefAndValue( const std::string& aRef,
const std::string& aValue,
int aSymbolPinCount );
protected:
virtual std::string GenerateParamValuePair( const SIM_MODEL::PARAM& aParam ) const;
private:
SIM_MODEL& m_model;
};
#endif // SIM_SERDE_H