/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2024 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 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 */ #ifndef SIM_XSPCIE_PARSER_H_ #define SIM_XSPCIE_PARSER_H_ #include "sim/sim_value.h" #include #include #include namespace SIM_XSPICE_PARSER_GRAMMAR { using namespace SIM_VALUE_GRAMMAR; /** * Notes: * spaces are allowed everywhere in any number * ~ can only be before ? * ~~ is not allowed * [] can enclose as many '?' with modifiers as we want * nested vectors are not allowed [ [?] ? ] * () and spaces are allowed and treated as separators * we want at least one node '?' **/ struct nodeName : one<'?'> { }; struct squareBracketO : one<'['> { }; struct squareBracketC : one<']'> { }; struct invertionDigital : one<'~'> { }; struct sep : opt, one<')'>>>> { }; struct invertionSeparated : seq { }; struct portInversionDouble : if_must> { }; struct portInversionVector : if_must> { }; struct portInversion : if_must>> { }; struct portModifiersSingleNames : sor, string<'v'>, istring<'i'>, istring<'g'>, istring<'h'>, istring<'d'>> { }; struct portModifierDifferentialNames : sor, istring<'i', 'd'>, istring<'g', 'd'>, istring<'h', 'd'>> { }; struct portModifierDigital : seq, sep, istring<'d'>> { }; struct portModifiersSingle : seq, sep, portModifiersSingleNames> { }; struct portModifiersDifferential : seq, sep, portModifierDifferentialNames> { }; struct validPortTypes : until, sep, sor>>> { }; struct nodeNameSeparated : seq { }; struct nodeDigital : seq, opt, rep_min<1, nodeNameSeparated>> { }; struct nodeSingle : seq>> { }; struct nodeDifferential : seq>> { }; struct nodeSequence : sor { }; struct vectorPattern : if_must> { }; struct vectorExpr : seq, opt, opt, sep, vectorPattern> { }; struct nodeSequenceGrammar : must>, sep, plus>, not_at> { }; template inline constexpr const char* errorMessage = nullptr; template <> inline constexpr auto errorMessage>> = "Expected at least one '?', are all modifiers and vectors correct?"; template <> inline constexpr auto errorMessage> = "Vectors [ must be closed ] and not nested."; template <> inline constexpr auto errorMessage>> = "Port type is invalid. '%%' needs to be followed by a valid name."; template <> inline constexpr auto errorMessage>> = ""; template <> inline constexpr auto errorMessage> = "Port type is invalid. '%%' needs to be followed by a valid name and a '?'."; template <> inline constexpr auto errorMessage> = "'~~' is not supported."; template <> inline constexpr auto errorMessage>> = "'~ %%d' not supported, consider changing to '%%d ~'."; template <> inline constexpr auto errorMessage> = "Differential ports need two nodes, and '~' is not supported for those nodes. Also check " "if port modifier name is valid."; template <> inline constexpr auto errorMessage> = "'~[' not supported."; template <> inline constexpr auto errorMessage> = "Vector is either empty, open or nested."; template <> inline constexpr auto errorMessage = ""; struct error { template static constexpr bool raise_on_failure = false; template static constexpr auto message = errorMessage; }; template using control = must_if::control; template struct spiceUnitSelector : std::false_type { }; template <> struct spiceUnitSelector : std::true_type { }; template <> struct spiceUnitSelector : std::true_type { }; template <> struct spiceUnitSelector : std::true_type { }; template <> struct spiceUnitSelector : std::true_type { }; template <> struct spiceUnitSelector : std::true_type { }; template <> struct spiceUnitSelector : std::true_type { }; template <> struct spiceUnitSelector : std::true_type { }; } // namespace SIM_XSPICE_PARSER_GRAMMAR #endif // SIM_XSPCIE_PARSER_H_