KiCad PCB EDA Suite
Loading...
Searching...
No Matches
cadstar_parts_lib_grammar.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) 2022 Roberto Fernandez Bautista <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <pegtl.hpp>
22
24{
25using namespace tao::pegtl;
26
27//-------------------- Grammar definition ----------------------------------------------------
28
32struct WHITESPACE : one<' ', '\t'>{};
33
37struct EMPTY_LINE : seq< bol, star<WHITESPACE>, eol>{};
38
42struct LINE_CONTINUATION : seq<one<'&'>, eol>{};
43
44
45struct WHITESPACE_OR_CONTINUATION : sor<WHITESPACE, LINE_CONTINUATION> {};
46
50template <typename... EXCLUSION_RULES>
51struct STR_SEGMENT_EXCLUDING : plus<not_at<sor<eolf, LINE_CONTINUATION,
52 EXCLUSION_RULES...>>, any>{};
53
57template <typename... EXCLUSION_RULES>
58struct STRING_EXCLUDING : plus<STR_SEGMENT_EXCLUDING<EXCLUSION_RULES...>,
59 opt<LINE_CONTINUATION>> {};
60
61
65template <char... CHAR_TO_FIND>
66struct spaced_ch : seq<star<WHITESPACE>, one<CHAR_TO_FIND...>>{};
67
71struct QUOTED_STRING : seq<one<'"'>, STRING_EXCLUDING<one<'"'>>, one<'"'>> {};
72
76struct SINGLE_QUOTED_STRING : seq<one<'\''>, STRING_EXCLUDING<one<'\''>>, one<'\''>> {};
77
78
83 seq
84 <
85 spaced_ch<'('>,
86 sor<
87 QUOTED_STRING,
88 STRING_EXCLUDING<one<')'>>
89 >,
90 one<')'>
91 >
92{};
93
98 seq
99 <
100 spaced_ch<'('>,
101 sor<
102 QUOTED_STRING,
103 STRING_EXCLUDING<seq<one<')'>, eolf>>
104 >,
105 seq<one<')'>, eolf>
106 >
107{};
108
109
110// **************
111// * FORMAT *
112// **************
113
114// Definition of "Format"
115// # FORMAT <current format number>
116struct CURRENT_FORMAT_NUMBER : plus<digit> {};
117struct FORMAT : seq
118 <
119 bol,
120 one<'#'>,
121 star<WHITESPACE>,
122 TAO_PEGTL_ISTRING( "FORMAT" ),
123 star<WHITESPACE>,
124 CURRENT_FORMAT_NUMBER,
125 opt<eol>
126 >
127{};
128
129
130// Newer Parts files have possibility of specifying a tree-like structure to show hierarchy
131//
132// Example:
133//+N0 'root' &
134//'part1' 'part2'
135//+N1 N0 'subnode1' 'part3' 'part4'
136struct HIERARCHY_NODE_INDEX : plus<digit>{};
137struct HIERARCHY_CURRENT_NODE : seq<one<'N'>, HIERARCHY_NODE_INDEX>{};
138struct HIERARCHY_PARENT_NODE : seq<one<'N'>, HIERARCHY_NODE_INDEX>{}; // Different action
142 seq
143 <
144 bol,
145 one<'+'>,
146 HIERARCHY_CURRENT_NODE, // N1
147 plus<WHITESPACE_OR_CONTINUATION>,
148 opt<HIERARCHY_PARENT_NODE>, // N0
149 star<WHITESPACE_OR_CONTINUATION>,
150 HIERARCHY_NODE_NAME, // 'subnode1'
151 star<WHITESPACE_OR_CONTINUATION>,
152 star<HIERARCHY_PART_NAME, star<WHITESPACE_OR_CONTINUATION>>, // 'part1' 'part2'
153 opt<eol>
154 >
155{};
156
157// **************
158// * PART ENTRY *
159// **************
160
161// Part Header
162// -----------
163//.<Part name>_[(<Part number>)][:<Part version>][;<Description>]
164
165 // string filters:
166struct PART_HEADER_START : one <'.'>{};
167struct PART_NAME_FILTER : sor<spaced_ch<'('>, spaced_ch<':'>, spaced_ch<';'>>{};
168struct PART_NUMBER_FILTER : one<')'>{};
170
171// part header elements:
172struct PART_NAME : STRING_EXCLUDING<PART_NAME_FILTER> {};
174struct PART_VERSION : STRING_EXCLUDING<PART_VERSION_FILTER> {};
176
178 seq
179 <
180 bol,
181 one<'.'>,
182 must<PART_NAME>,
183 opt<PART_NUMBER>,
184 opt<seq<spaced_ch<':'>, PART_VERSION>>,
185 opt<seq<spaced_ch<';'>, PART_DESCRIPTION>>,
186 opt<eol>
187 >
188{};
189
190// Part - PCB Component
191// --------------------
192//<PCB Component Refname>[_(<PCB Alternate Refname>)]
193
194// string filters:
196struct PCB_ALTERNATE_FILTER : one<')'>{};
197
198// pcb component elements
199struct PCB_COMPONENT : STRING_EXCLUDING<PCB_COMPONENT_FILTER> {};
201
203 seq
204 <
205 bol,
206 PCB_COMPONENT,
207 opt<PCB_ALTERNATE>,
208 opt<eol>
209 >
210{};
211
212// Part Value
213// -----------
214//[*VALUE_<Value>]
217 seq
218 <
219 bol,
220 TAO_PEGTL_ISTRING( "*VALUE"),
221 plus<WHITESPACE>,
222 VALUE,
223 opt<eol>
224 >
225{};
226
227struct PINNUM : plus<digit> {};
228
229// Pin Names
230//[*PNM_<Pinnum>=<Pinname>[_<Pinnum>=<Pinname>]_etc]
231// Maximum 10 characters allowed for Pinname according to documentation
232struct PINNAME : rep_min_max<1,10,alnum> {};
234 seq
235 <
236 plus<WHITESPACE_OR_CONTINUATION>,
237 PINNUM,
238 one<'='>,
239 PINNAME
240 >
241{};
242
244 seq
245 <
246 bol,
247 TAO_PEGTL_ISTRING( "*PNM"),
248 plus<PINNAME_ENTRY>,
249 opt<eol>
250 >
251{};
252
253// Pin Labels
254//[*PLB_<Pinnum>=<Pinlabel>[_<Pinnum>=<Pinlabel>]_etc]
255struct PINLABEL : sor<QUOTED_STRING, STRING_EXCLUDING<WHITESPACE>> {};
257 seq
258 <
259 plus<WHITESPACE_OR_CONTINUATION>,
260 PINNUM,
261 one<'='>,
262 PINLABEL
263 >
264{};
265
267 seq
268 <
269 bol,
270 TAO_PEGTL_ISTRING( "*PLB"),
271 plus<PINLABEL_ENTRY>,
272 opt<eol>
273 >
274{};
275
276// Pin Equivalences
277//[*EQU_<PinIdentifier>=<PinIdentifier>[=<PinIdentifier>=<PinIdentifier>_etc ...]]
278struct EQUIVALENT_PIN : PINNUM {}; // same grammar but different action to be applied
280 seq
281 <
282 plus<WHITESPACE_OR_CONTINUATION>,
283 EQUIVALENT_PIN,
284 plus<one<'='>, star<WHITESPACE_OR_CONTINUATION>, EQUIVALENT_PIN>
285 >
286{};
287
289 seq
290 <
291 bol,
292 TAO_PEGTL_ISTRING( "*EQU"),
293 EQUIVALENT_PINS_GROUP,
294 star<one<','>, EQUIVALENT_PINS_GROUP>,
295 opt<eol>
296 >
297{};
298
299
300// INTERNAL AND EXTERNAL PIN SWAPPING
301// *SYM_[<Element name>]
303struct SYM_LINE :
304 seq
305 <
306 bol,
307 TAO_PEGTL_ISTRING( "*SYM"),
308 star<WHITESPACE>,
309 opt<SYM_ELEMENT_NAME>,
310 opt<eol>
311 >
312{};
313
315 seq
316 <
317 plus<WHITESPACE>,
318 EQUIVALENT_PIN,
319 star
320 <
321 plus<WHITESPACE_OR_CONTINUATION>,
322 EQUIVALENT_PIN
323 >
324 >
325{};
326
327//[*INT_<Pinnum>_[<Pinnum>_ etc ...]]
329 seq
330 <
331 bol,
332 TAO_PEGTL_ISTRING( "*INT"),
333 GATE_PINS_LIST,
334 opt<eol>
335 >
336{};
337
338//[*EXT_<Pinnum>_[<Pinnum>_ etc ...]]
340 seq
341 <
342 bol,
343 TAO_PEGTL_ISTRING( "*EXT"),
344 GATE_PINS_LIST,
345 opt<eol>
346 >
347{};
348
349// Internal swapping group E.g.:
350//*SYM SYM1
351//*INT 2 3
352//*INT 4 5
354 seq
355 <
356 SYM_LINE,
357 plus<INTERNAL_SWAP_GATE>
358 >
359{};
360
361// External swapping group E.g.:
362//*SYM SYM1
363//*EXT 2 3
364//*EXT 4 5
366 seq
367 <
368 SYM_LINE,
369 plus<EXTERNAL_SWAP_GATE>
370 >
371{};
372
373// Part Definition
374// -----------
375// [*DFN_<Definition name>]
377struct DFN_LINE :
378 seq
379 <
380 bol,
381 TAO_PEGTL_ISTRING( "*DFN"),
382 plus<WHITESPACE>,
383 DEFINITION_NAME,
384 opt<eol>
385 >
386{};
387
388// [*NGS]
389struct NGS_LINE :
390 seq
391 <
392 bol,
393 TAO_PEGTL_ISTRING( "*NGS"),
394 opt<eol>
395 >
396{};
397
398// [*NPV]
399struct NPV_LINE :
400 seq
401 <
402 bol,
403 TAO_PEGTL_ISTRING( "*NPV"),
404 opt<eol>
405 >
406{};
407
408// [*STM_<Component name stem>]
409struct STEM : STRING_EXCLUDING<> {};
410struct STM_LINE :
411 seq
412 <
413 bol,
414 TAO_PEGTL_ISTRING( "*STM"),
415 plus<WHITESPACE>,
416 STEM,
417 opt<eol>
418 >
419{};
420
421// [*MXP <Maximum number of connector pins>]
422struct MAX_PIN_COUNT : plus<digit> {};
423struct MXP_LINE :
424 seq
425 <
426 bol,
427 TAO_PEGTL_ISTRING( "*MXP"),
428 plus<WHITESPACE>,
429 MAX_PIN_COUNT,
430 opt<eol>
431 >
432{};
433
434// [*SPI_[(<Part name>)]_[<Model>]_<Component Value>]
436struct SPICE_MODEL : sor<QUOTED_STRING, STRING_EXCLUDING<>> {};
437struct SPI_LINE :
438 seq
439 <
440 bol,
441 TAO_PEGTL_ISTRING( "*SPI"),
442 plus<WHITESPACE>,
443 opt<SPICE_PART_NAME>,
444 star<WHITESPACE>,
445 SPICE_MODEL,
446 opt<eol>
447 >
448{};
449
450
451// [*PAC_(<Part name>)_<Acceptance Text>]
454struct PAC_LINE :
455 seq
456 <
457 bol,
458 TAO_PEGTL_ISTRING( "*PAC"),
459 plus<WHITESPACE>,
460 opt<ACCEPTANCE_PART_NAME>,
461 plus<WHITESPACE>,
462 ACCEPTANCE_TEXT,
463 opt<eol>
464 >
465{};
466
467// User defined part attributes
468// -----------
469// [*<User-defined name>_<Value>]
470struct USER_PART_ATTRIBUTE_NAME : sor<QUOTED_STRING, STRING_EXCLUDING<WHITESPACE>> {};
473 seq
474 <
475 bol,
476 one<'*'>,
477 USER_PART_ATTRIBUTE_NAME,
478 plus<WHITESPACE>,
479 USER_PART_ATTRIBUTE_VALUE,
480 opt<eol>
481 >
482{};
483
484//----------------------------------------------------
485// In-built attributes: schematic, PCB, both (sch+pcb) and parts
486//----------------------------------------------------
487struct READONLY : one <'!'>{};
488struct ATTRIBUTE_NAME : sor<QUOTED_STRING, STRING_EXCLUDING< spaced_ch<'('>>> {};
491
492template<char START_TOKEN>
494 seq
495 <
496 bol,
497 one<START_TOKEN>,
498 opt<READONLY>,
499 ATTRIBUTE_NAME,
500 ATTRIBUTE_VALUE_EOLF
501 >
502{};
503
504// [$[!]<SCM Attribute name>(<Attribute value>)]
506
507
508// [%[!]<PCB Attribute name>(<Attribute value>)]
510
511
512// [~[!]<Parts Library Attribute Name>(<Attribute Value>)]
514
515
516// [@[!]<SCM/PCB Attribute name>(<Attribute value>)]
518
519
520// [<SCM Symbol Refname>][_(<SCM Alternate Refname>)]
521struct SCH_NAME : sor<QUOTED_STRING, STRING_EXCLUDING<spaced_ch<'('>>> {};
523struct SCH_SYMBOL_LINE : seq<SCH_NAME, opt<SCH_ALTERNATE>, opt<eol>>{};
524
525// [<PinIdentifier>[.<Position>] [!<Pintype>] [:<Loading>]]
526struct PIN_IDENTIFIER : plus<digit>{};
527struct PIN_POSITION : range<'0', '3'>{};
528struct PIN_TYPE : star<alpha>{};
529struct PIN_LOADING : plus<digit>{};
530
531struct PIN_ENTRY :
532 seq
533 <
534 PIN_IDENTIFIER,
535 one<'.'>,
536 PIN_POSITION,
537 opt< one<'!'>, PIN_TYPE>,
538 opt< one<':'>, PIN_LOADING>
539 >
540{};
541
542struct PIN_LIST : plus<PIN_ENTRY, star<WHITESPACE>, opt<LINE_CONTINUATION>> {};
543
544struct SYMBOL_ENTRY : seq<SCH_SYMBOL_LINE, PIN_LIST, opt<eol>>{};
545
546
547// /<Signame>_<PinIdentifier>[.<Position>][!<Pintype>][:<Loading>]
548struct PIN_SIGNAL_NAME : seq<one<'/'>, STRING_EXCLUDING<WHITESPACE>> {};
549struct HIDDEN_PIN_ENTRY : seq<PIN_SIGNAL_NAME, plus<WHITESPACE>, PIN_LIST, opt<eol>>{};
550
551
552//******************
553// Join all together
554
556 seq
557 <
558 PART_HEADER, // .<Part name>[ (1234): 1 ;<Description>]
559 PART_PCB_COMPONENT, // <PCB Component Refname> [(Alternate)]
560
561 // In any order:
562 star<sor<
563 PART_VALUE, // [*VALUE <Value>]
564 PIN_NAMES_LIST, // [*PNM <ID><Name>[ <ID><Name>] ...]
565 PIN_LABELS_LIST, // [*PLB <ID><Label>[ <ID><Label>] ...]
566 PIN_EQUIVALENCES, // [*EQU_<ID>=<ID>[=<ID>=<ID>_etc ...]]
567 INTERNAL_SWAP_GROUP, // [*SYM SYM1 |*INT 2 3 |*INT 4 5]
568 EXTERNAL_SWAP_GROUP, // [*SYM SYM1 |*EXT 2 3 |*EXT 4 5]
569 DFN_LINE, // [*DFN_<Definition name>]
570 NGS_LINE, // [*NGS]
571 NPV_LINE, // [*NPV]
572 STM_LINE, // [*STM_<Component name stem>]
573 MXP_LINE, // [*MXP <Maximum number of connector pins>]
574 SPI_LINE, // [*SPI_[(<Part name>)]_[<Model>]_<Component Value>]
575 PAC_LINE, // [*PAC_(<Part name>)_<Acceptance Text>]
576 USER_PART_ATTRIBUTE, // [*<User-defined name>_<Value>]
577 SCM_ATTRIBUTE, // [$[!]<SCM Attribute name>(<Attribute value>)]
578 PCB_ATTRIBUTE, // [%[!]<PCB Attribute name>(<Attribute value>)]
579 PART_ATTRIBUTE, // [~[!]<Parts Library Attribute Name>(<Attribute
580 // Value>)]
581 SCH_PCB_ATTRIBUTE // [@[!]<SCM/PCB Attribute name>(<Attribute value>)]
582 >>,
583 star<SYMBOL_ENTRY>, // [<SCM Symbol Refname>][_(<SCM Alternate Refname>)]
584 // [Pin entry] [Pin entry] ...
585
586 star<HIDDEN_PIN_ENTRY> // [/<Signame>_<Pin entry>]
587
588 >
589{};
590
591
595struct GRAMMAR :
596 must<
597 opt<FORMAT>,
598 star<star<EMPTY_LINE>, HIERARCHY_NODE_ENTRY>,
599 plus
600 <
601 sor
602 <
603 PART_ENTRY,
604 EMPTY_LINE // optional empty line
605 >,
606 opt<eol>
607 >,
608 opt<TAO_PEGTL_ISTRING( ".END"), opt<eol>>,
609 star<EMPTY_LINE>,
610 tao::pegtl::eof // just putting "eof" results in ambiguous symbol
611 >
612{};
613
614
623struct VALID_HEADER : sor<FORMAT, seq< rep_max<5,EMPTY_LINE>, PART_HEADER>>{};
624
625} // namespace CADSTAR_PART_LIB
Empty line with whitespaces.
Grammar for CADSTAR Parts Library file format (*.lib).
Any text in the format can span multiple lines using '&'.
String inside quotation marks.
String inside single quotation marks.
String with optional line continuation and exclusion rules.
String inside brackets with preceding spaces, ending with EOL or EOF.
String inside brackets with preceding spaces.
String segment( no line continuation ), with exclusion rules.
Grammar to parse the file header only.
Needed, because PEGTL "space" includes newline characters.
Control character with or without preceding whitespace.