KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sim_xspice_parser.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23#ifndef SIM_XSPCIE_PARSER_H_
24#define SIM_XSPCIE_PARSER_H_
25
26#include "sim/sim_value.h"
27#include <pegtl.hpp>
28#include <pegtl/eol.hpp>
29#include <pegtl/rules.hpp>
30
32{
33using namespace SIM_VALUE_GRAMMAR;
34
45struct nodeName : one<'?'>
46{
47};
48struct squareBracketO : one<'['>
49{
50};
51struct squareBracketC : one<']'>
52{
53};
54struct invertionDigital : one<'~'>
55{
56};
57struct sep : opt<plus<sor<space,
58 one<'('>,
59 one<')'>>>>
60{
61};
62
63struct invertionSeparated : seq<sep, invertionDigital, sep>
64{
65};
66struct portInversionDouble : if_must<invertionSeparated, not_at<invertionSeparated>>
67{
68};
69struct portInversionVector : if_must<portInversionDouble, not_at<squareBracketO>>
70{
71};
72struct portInversion : if_must<portInversionVector, not_at<one<'%'>>>
73{
74};
75
76struct portModifiersSingleNames : sor<istring<'v', 'n', 'a', 'm'>,
77 string<'v'>,
78 istring<'i'>,
79 istring<'g'>,
80 istring<'h'>,
81 istring<'d'>>
82{
83};
85 : sor<istring<'v', 'd'>,
86 istring<'i', 'd'>,
87 istring<'g', 'd'>,
88 istring<'h', 'd'>>
89{
90};
91
92struct portModifierDigital : seq<one<'%'>, sep, istring<'d'>>
93{
94};
95struct portModifiersSingle : seq<one<'%'>, sep, portModifiersSingleNames>
96{
97};
98struct portModifiersDifferential : seq<one<'%'>, sep, portModifierDifferentialNames>
99{
100};
102 : until<if_must<one<'%'>, sep,
103 sor<portModifierDifferentialNames,
104 portModifiersSingleNames,
105 istring<'d'>>>>
106{
107};
108
109struct nodeNameSeparated : seq<sep, nodeName, sep>
110{
111};
113 : seq<sep, opt<portModifierDigital>, opt<portInversion>, rep_min<1, nodeNameSeparated>>
114{
115};
116struct nodeSingle : seq<sep, if_must<portModifiersSingle, sep, rep_min<1, nodeNameSeparated>>>
117{
118};
120 : seq<sep, if_must<portModifiersDifferential, sep, rep_min<2, nodeNameSeparated>>>
121{
122};
123struct nodeSequence : sor<nodeDifferential,
124 nodeDigital,
125 nodeSingle>
126{
127};
128
129struct vectorPattern : if_must<squareBracketO, until<squareBracketC, nodeSequence>>
130{
131};
132struct vectorExpr : seq<opt<portModifierDigital>, opt<portModifiersDifferential>,
133 opt<portModifiersSingle>, sep, vectorPattern>
134{
135};
136struct nodeSequenceGrammar : must<at<rep_min<0, validPortTypes>>, sep,
137 plus<sor<vectorExpr,
138 nodeSequence>>,
139 not_at<squareBracketC>>
140{
141};
142
143template <typename>
144inline constexpr const char* errorMessage = nullptr;
145template <>
146inline constexpr auto errorMessage<plus<sor<vectorExpr, nodeSequence>>> =
147 "Expected at least one '?', are all modifiers and vectors correct?";
148template <>
149inline constexpr auto errorMessage<until<squareBracketC, nodeSequence>> =
150 "Vectors [ must be closed ] and not nested.";
151template <>
152inline constexpr auto
154 "Port type is invalid. '%%' needs to be followed by a valid name.";
155template <>
156inline constexpr auto errorMessage<at<rep_min<0, validPortTypes>>> = "";
157template <>
158inline constexpr auto errorMessage<rep_min<1, nodeNameSeparated>> =
159 "Port type is invalid. '%%' needs to be followed by a valid name and a '?'.";
160template <>
161inline constexpr auto errorMessage<not_at<invertionSeparated>> = "'~~' is not supported.";
162template <>
163inline constexpr auto errorMessage<not_at<one<'%'>>> =
164 "'~ %%d' not supported, consider changing to '%%d ~'.";
165template <>
166inline constexpr auto errorMessage<rep_min<2, nodeNameSeparated>> =
167 "Differential ports need two nodes, and '~' is not supported for those nodes. Also check "
168 "if port modifier name is valid.";
169template <>
170inline constexpr auto errorMessage<not_at<squareBracketO>> = "'~[' not supported.";
171template <>
172inline constexpr auto errorMessage<not_at<squareBracketC>> =
173 "Vector is either empty, open or nested.";
174template <>
175inline constexpr auto errorMessage<sep> = "";
176
177
178struct error
179{
180 template <typename Rule>
181 static constexpr bool raise_on_failure = false;
182 template <typename Rule>
183 static constexpr auto message = errorMessage<Rule>;
184};
185template <typename Rule>
186using control = must_if<error>::control<Rule>;
187
188
189template <typename Rule>
190struct spiceUnitSelector : std::false_type
191{
192};
193template <>
194struct spiceUnitSelector<squareBracketO> : std::true_type
195{
196};
197template <>
199{
200};
201template <>
203{
204};
205template <>
207{
208};
209template <>
210struct spiceUnitSelector<invertionDigital> : std::true_type
211{
212};
213template <>
214struct spiceUnitSelector<squareBracketC> : std::true_type
215{
216};
217template <>
218struct spiceUnitSelector<nodeName> : std::true_type
219{
220};
221
222} // namespace SIM_XSPICE_PARSER_GRAMMAR
223#endif // SIM_XSPCIE_PARSER_H_
must_if< error >::control< Rule > control
constexpr auto errorMessage< sep >
constexpr const char * errorMessage
static constexpr bool raise_on_failure
Notes: spaces are allowed everywhere in any number ~ can only be before ? ~~ is not allowed [] can en...