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 The 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, see <https://www.gnu.org/licenses/>.
18 */
19#ifndef SIM_XSPCIE_PARSER_H_
20#define SIM_XSPCIE_PARSER_H_
21
22#include "sim/sim_value.h"
23#include <pegtl.hpp>
24#include <pegtl/eol.hpp>
25#include <pegtl/rules.hpp>
26
28{
29using namespace SIM_VALUE_GRAMMAR;
30
41struct nodeName : one<'?'>
42{
43};
44struct squareBracketO : one<'['>
45{
46};
47struct squareBracketC : one<']'>
48{
49};
50struct invertionDigital : one<'~'>
51{
52};
53struct sep : opt<plus<sor<space,
54 one<'('>,
55 one<')'>>>>
56{
57};
58
59struct invertionSeparated : seq<sep, invertionDigital, sep>
60{
61};
62struct portInversionDouble : if_must<invertionSeparated, not_at<invertionSeparated>>
63{
64};
65struct portInversionVector : if_must<portInversionDouble, not_at<squareBracketO>>
66{
67};
68struct portInversion : if_must<portInversionVector, not_at<one<'%'>>>
69{
70};
71
72struct portModifiersSingleNames : sor<istring<'v', 'n', 'a', 'm'>,
73 string<'v'>,
74 istring<'i'>,
75 istring<'g'>,
76 istring<'h'>,
77 istring<'d'>>
78{
79};
81 : sor<istring<'v', 'd'>,
82 istring<'i', 'd'>,
83 istring<'g', 'd'>,
84 istring<'h', 'd'>>
85{
86};
87
88struct portModifierDigital : seq<one<'%'>, sep, istring<'d'>>
89{
90};
91struct portModifiersSingle : seq<one<'%'>, sep, portModifiersSingleNames>
92{
93};
94struct portModifiersDifferential : seq<one<'%'>, sep, portModifierDifferentialNames>
95{
96};
98 : until<if_must<one<'%'>, sep,
99 sor<portModifierDifferentialNames,
100 portModifiersSingleNames,
101 istring<'d'>>>>
102{
103};
104
105struct nodeNameSeparated : seq<sep, nodeName, sep>
106{
107};
109 : seq<sep, opt<portModifierDigital>, opt<portInversion>, rep_min<1, nodeNameSeparated>>
110{
111};
112struct nodeSingle : seq<sep, if_must<portModifiersSingle, sep, rep_min<1, nodeNameSeparated>>>
113{
114};
116 : seq<sep, if_must<portModifiersDifferential, sep, rep_min<2, nodeNameSeparated>>>
117{
118};
119struct nodeSequence : sor<nodeDifferential,
120 nodeDigital,
121 nodeSingle>
122{
123};
124
125struct vectorPattern : if_must<squareBracketO, until<squareBracketC, nodeSequence>>
126{
127};
128struct vectorExpr : seq<opt<portModifierDigital>, opt<portModifiersDifferential>,
129 opt<portModifiersSingle>, sep, vectorPattern>
130{
131};
132struct nodeSequenceGrammar : must<at<rep_min<0, validPortTypes>>, sep,
133 plus<sor<vectorExpr,
134 nodeSequence>>,
135 not_at<squareBracketC>>
136{
137};
138
139template <typename>
140inline constexpr const char* errorMessage = nullptr;
141template <>
143 "Expected at least one '?', are all modifiers and vectors correct?";
144template <>
146 "Vectors [ must be closed ] and not nested.";
147template <>
148inline constexpr auto
150 "Port type is invalid. '%%' needs to be followed by a valid name.";
151template <>
153template <>
155 "Port type is invalid. '%%' needs to be followed by a valid name and a '?'.";
156template <>
157inline constexpr auto errorMessage<not_at<invertionSeparated>> = "'~~' is not supported.";
158template <>
159inline constexpr auto errorMessage<not_at<one<'%'>>> =
160 "'~ %%d' not supported, consider changing to '%%d ~'.";
161template <>
163 "Differential ports need two nodes, and '~' is not supported for those nodes. Also check "
164 "if port modifier name is valid.";
165template <>
166inline constexpr auto errorMessage<not_at<squareBracketO>> = "'~[' not supported.";
167template <>
169 "Vector is either empty, open or nested.";
170template <>
171inline constexpr auto errorMessage<sep> = "";
172
173
174struct error
175{
176 template <typename Rule>
177 static constexpr bool raise_on_failure = false;
178 template <typename Rule>
179 static constexpr auto message = errorMessage<Rule>;
180};
181template <typename Rule>
182using control = must_if<error>::control<Rule>;
183
184
185template <typename Rule>
186struct spiceUnitSelector : std::false_type
187{
188};
189template <>
190struct spiceUnitSelector<squareBracketO> : std::true_type
191{
192};
193template <>
195{
196};
197template <>
199{
200};
201template <>
203{
204};
205template <>
206struct spiceUnitSelector<invertionDigital> : std::true_type
207{
208};
209template <>
210struct spiceUnitSelector<squareBracketC> : std::true_type
211{
212};
213template <>
214struct spiceUnitSelector<nodeName> : std::true_type
215{
216};
217
218} // namespace SIM_XSPICE_PARSER_GRAMMAR
219#endif // SIM_XSPCIE_PARSER_H_
must_if< error >::control< Rule > control
constexpr const char * errorMessage
static constexpr bool raise_on_failure
Notes: spaces are allowed everywhere in any number ~ can only be before ?