You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
6.5 KiB

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