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 (C) 2022-2023 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, EXCLUSION_RULES...>>, any>{};
52
56template <typename... EXCLUSION_RULES>
57struct STRING_EXCLUDING : plus<STR_SEGMENT_EXCLUDING<EXCLUSION_RULES...>, opt<LINE_CONTINUATION>> {};
58
59
63template <char... CHAR_TO_FIND>
64struct spaced_ch : seq<star<WHITESPACE>, one<CHAR_TO_FIND...>>{};
65
69struct QUOTED_STRING : seq<one<'"'>, STRING_EXCLUDING<one<'"'>>, one<'"'>> {};
70
74struct SINGLE_QUOTED_STRING : seq<one<'\''>, STRING_EXCLUDING<one<'\''>>, one<'\''>> {};
75
76
81 seq
82 <
83 spaced_ch<'('>,
84 sor<
85 QUOTED_STRING,
86 STRING_EXCLUDING<one<')'>>
87 >,
88 one<')'>
89 >
90{};
91
96 seq
97 <
98 spaced_ch<'('>,
99 sor<
100 QUOTED_STRING,
101 STRING_EXCLUDING<seq<one<')'>, eolf>>
102 >,
103 seq<one<')'>, eolf>
104 >
105{};
106
107
108// **************
109// * FORMAT *
110// **************
111
112// Definition of "Format"
113// # FORMAT <current format number>
114struct CURRENT_FORMAT_NUMBER : plus<digit> {};
115struct FORMAT : seq
116 <
117 bol,
118 one<'#'>,
119 star<WHITESPACE>,
120 TAO_PEGTL_ISTRING( "FORMAT" ),
121 star<WHITESPACE>,
122 CURRENT_FORMAT_NUMBER,
123 opt<eol>
124 >
125 {};
126
127
128// Newer Parts files have possibility of specifying a tree-like structure to show hierarchy
129//
130// Example:
131//+N0 'root' &
132//'part1' 'part2'
133//+N1 N0 'subnode1' 'part3' 'part4'
134struct HIERARCHY_NODE_INDEX : plus<digit>{};
135struct HIERARCHY_CURRENT_NODE : seq<one<'N'>, HIERARCHY_NODE_INDEX>{};
136struct HIERARCHY_PARENT_NODE : seq<one<'N'>, HIERARCHY_NODE_INDEX>{}; // Different action
140 seq
141 <
142 bol,
143 one<'+'>,
144 HIERARCHY_CURRENT_NODE, // N1
145 plus<WHITESPACE_OR_CONTINUATION>,
146 opt<HIERARCHY_PARENT_NODE>, // N0
147 star<WHITESPACE_OR_CONTINUATION>,
148 HIERARCHY_NODE_NAME, // 'subnode1'
149 star<WHITESPACE_OR_CONTINUATION>,
150 star<HIERARCHY_PART_NAME, star<WHITESPACE_OR_CONTINUATION>>, // 'part1' 'part2'
151 opt<eol>
152 >
153 {};
154
155// **************
156// * PART ENTRY *
157// **************
158
159// Part Header
160// -----------
161//.<Part name>_[(<Part number>)][:<Part version>][;<Description>]
162
163 // string filters:
164struct PART_HEADER_START : one <'.'>{};
165struct PART_NAME_FILTER : sor<spaced_ch<'('>, spaced_ch<':'>, spaced_ch<';'>>{};
166struct PART_NUMBER_FILTER : one<')'>{};
168
169 // part header elements:
170struct PART_NAME : STRING_EXCLUDING<PART_NAME_FILTER> {};
172struct PART_VERSION : STRING_EXCLUDING<PART_VERSION_FILTER> {};
174
176 seq
177 <
178 bol,
179 one<'.'>,
180 must<PART_NAME>,
181 opt<PART_NUMBER>,
182 opt<seq<spaced_ch<':'>, PART_VERSION>>,
183 opt<seq<spaced_ch<';'>, PART_DESCRIPTION>>,
184 opt<eol>
185 >
186{};
187
188// Part - PCB Component
189// --------------------
190//<PCB Component Refname>[_(<PCB Alternate Refname>)]
191
192 // string filters:
194struct PCB_ALTERNATE_FILTER : one<')'>{};
195
196 // pcb component elements
197struct PCB_COMPONENT : STRING_EXCLUDING<PCB_COMPONENT_FILTER> {};
199
201 seq
202 <
203 bol,
204 PCB_COMPONENT,
205 opt<PCB_ALTERNATE>,
206 opt<eol>
207 >
208{};
209
210// Part Value
211// -----------
212//[*VALUE_<Value>]
215 seq
216 <
217 bol,
218 TAO_PEGTL_ISTRING( "*VALUE"),
219 plus<WHITESPACE>,
220 VALUE,
221 opt<eol>
222 >
223{};
224
225struct PINNUM : plus<digit> {};
226
227// Pin Names
228//[*PNM_<Pinnum>=<Pinname>[_<Pinnum>=<Pinname>]_etc]
229// Maximum 10 characters allowed for Pinname according to documentation
230struct PINNAME : rep_min_max<1,10,alnum> {};
232 seq
233 <
234 plus<WHITESPACE_OR_CONTINUATION>,
235 PINNUM,
236 one<'='>,
237 PINNAME
238 >
239{};
240
242 seq
243 <
244 bol,
245 TAO_PEGTL_ISTRING( "*PNM"),
246 plus<PINNAME_ENTRY>,
247 opt<eol>
248 >
249{};
250
251// Pin Labels
252//[*PLB_<Pinnum>=<Pinlabel>[_<Pinnum>=<Pinlabel>]_etc]
253struct PINLABEL : sor<QUOTED_STRING, STRING_EXCLUDING<WHITESPACE>> {};
255 seq
256 <
257 plus<WHITESPACE_OR_CONTINUATION>,
258 PINNUM,
259 one<'='>,
260 PINLABEL
261 >
262{};
263
265 seq
266 <
267 bol,
268 TAO_PEGTL_ISTRING( "*PLB"),
269 plus<PINLABEL_ENTRY>,
270 opt<eol>
271 >
272{};
273
274// Pin Equivalences
275//[*EQU_<PinIdentifier>=<PinIdentifier>[=<PinIdentifier>=<PinIdentifier>_etc ...]]
276struct EQUIVALENT_PIN : PINNUM {}; // same grammar but different action to be applied
278 seq
279 <
280 plus<WHITESPACE_OR_CONTINUATION>,
281 EQUIVALENT_PIN,
282 plus<one<'='>, star<WHITESPACE_OR_CONTINUATION>, EQUIVALENT_PIN>
283 >
284{};
285
287 seq
288 <
289 bol,
290 TAO_PEGTL_ISTRING( "*EQU"),
291 EQUIVALENT_PINS_GROUP,
292 star<one<','>, EQUIVALENT_PINS_GROUP>,
293 opt<eol>
294 >
295{};
296
297
298// INTERNAL AND EXTERNAL PIN SWAPPING
299// *SYM_[<Element name>]
301struct SYM_LINE :
302 seq
303 <
304 bol,
305 TAO_PEGTL_ISTRING( "*SYM"),
306 star<WHITESPACE>,
307 opt<SYM_ELEMENT_NAME>,
308 opt<eol>
309 >
310{};
311
313 seq
314 <
315 plus<WHITESPACE>,
316 EQUIVALENT_PIN,
317 star
318 <
319 plus<WHITESPACE_OR_CONTINUATION>,
320 EQUIVALENT_PIN
321 >
322 >
323{};
324
325//[*INT_<Pinnum>_[<Pinnum>_ etc ...]]
327 seq
328 <
329 bol,
330 TAO_PEGTL_ISTRING( "*INT"),
331 GATE_PINS_LIST,
332 opt<eol>
333 >
334{};
335
336//[*EXT_<Pinnum>_[<Pinnum>_ etc ...]]
338 seq
339 <
340 bol,
341 TAO_PEGTL_ISTRING( "*EXT"),
342 GATE_PINS_LIST,
343 opt<eol>
344 >
345{};
346
347// Internal swapping group E.g.:
348//*SYM SYM1
349//*INT 2 3
350//*INT 4 5
352 seq
353 <
354 SYM_LINE,
355 plus<INTERNAL_SWAP_GATE>
356 >
357{};
358
359// External swapping group E.g.:
360//*SYM SYM1
361//*EXT 2 3
362//*EXT 4 5
364 seq
365 <
366 SYM_LINE,
367 plus<EXTERNAL_SWAP_GATE>
368 >
369{};
370
371// Part Definition
372// -----------
373//[*DFN_<Definition name>]
375struct DFN_LINE :
376 seq
377 <
378 bol,
379 TAO_PEGTL_ISTRING( "*DFN"),
380 plus<WHITESPACE>,
381 DEFINITION_NAME,
382 opt<eol>
383 >
384{};
385
386//[*NGS]
387struct NGS_LINE :
388 seq
389 <
390 bol,
391 TAO_PEGTL_ISTRING( "*NGS"),
392 opt<eol>
393 >
394{};
395
396//[*NPV]
397struct NPV_LINE :
398 seq
399 <
400 bol,
401 TAO_PEGTL_ISTRING( "*NPV"),
402 opt<eol>
403 >
404{};
405
406//[*STM_<Component name stem>]
407struct STEM : STRING_EXCLUDING<> {};
408struct STM_LINE :
409 seq
410 <
411 bol,
412 TAO_PEGTL_ISTRING( "*STM"),
413 plus<WHITESPACE>,
414 STEM,
415 opt<eol>
416 >
417{};
418
419//[*MXP <Maximum number of connector pins>]
420struct MAX_PIN_COUNT : plus<digit> {};
421struct MXP_LINE :
422 seq
423 <
424 bol,
425 TAO_PEGTL_ISTRING( "*MXP"),
426 plus<WHITESPACE>,
427 MAX_PIN_COUNT,
428 opt<eol>
429 >
430{};
431
432//[*SPI_[(<Part name>)]_[<Model>]_<Component Value>]
434struct SPICE_MODEL : sor<QUOTED_STRING, STRING_EXCLUDING<>> {};
435struct SPI_LINE :
436 seq
437 <
438 bol,
439 TAO_PEGTL_ISTRING( "*SPI"),
440 plus<WHITESPACE>,
441 opt<SPICE_PART_NAME>,
442 star<WHITESPACE>,
443 SPICE_MODEL,
444 opt<eol>
445 >
446{};
447
448
449//[*PAC_(<Part name>)_<Acceptance Text>]
452struct PAC_LINE :
453 seq
454 <
455 bol,
456 TAO_PEGTL_ISTRING( "*PAC"),
457 plus<WHITESPACE>,
458 opt<ACCEPTANCE_PART_NAME>,
459 plus<WHITESPACE>,
460 ACCEPTANCE_TEXT,
461 opt<eol>
462 >
463{};
464
465// User defined part attributes
466// -----------
467//[*<User-defined name>_<Value>]
468struct USER_PART_ATTRIBUTE_NAME : sor<QUOTED_STRING, STRING_EXCLUDING<WHITESPACE>> {};
471 seq
472 <
473 bol,
474 one<'*'>,
475 USER_PART_ATTRIBUTE_NAME,
476 plus<WHITESPACE>,
477 USER_PART_ATTRIBUTE_VALUE,
478 opt<eol>
479 >
480{};
481
482//----------------------------------------------------
483// In-built attributes: schematic, PCB, both (sch+pcb) and parts
484//----------------------------------------------------
485struct READONLY : one <'!'>{};
486struct ATTRIBUTE_NAME : sor<QUOTED_STRING, STRING_EXCLUDING< spaced_ch<'('>>> {};
489
490template<char START_TOKEN>
492 seq
493 <
494 bol,
495 one<START_TOKEN>,
496 opt<READONLY>,
497 ATTRIBUTE_NAME,
498 ATTRIBUTE_VALUE_EOLF
499 >
500{};
501
502//[$[!]<SCM Attribute name>(<Attribute value>)]
504
505
506//[%[!]<PCB Attribute name>(<Attribute value>)]
508
509
510//[~[!]<Parts Library Attribute Name>(<Attribute Value>)]
512
513
514//[@[!]<SCM/PCB Attribute name>(<Attribute value>)]
516
517
518//[<SCM Symbol Refname>][_(<SCM Alternate Refname>)]
519struct SCH_NAME : sor<QUOTED_STRING, STRING_EXCLUDING<spaced_ch<'('>>> {};
521struct SCH_SYMBOL_LINE : seq<SCH_NAME, opt<SCH_ALTERNATE>, opt<eol>>{};
522
523//[<PinIdentifier>[.<Position>] [!<Pintype>] [:<Loading>]]
524struct PIN_IDENTIFIER : plus<digit>{};
525struct PIN_POSITION : range<'0', '3'>{};
526struct PIN_TYPE : star<alpha>{};
527struct PIN_LOADING : plus<digit>{};
528
529struct PIN_ENTRY :
530 seq
531 <
532 PIN_IDENTIFIER,
533 one<'.'>,
534 PIN_POSITION,
535 opt< one<'!'>, PIN_TYPE>,
536 opt< one<':'>, PIN_LOADING>
537 >
538{};
539
540struct PIN_LIST : plus<PIN_ENTRY, star<WHITESPACE>, opt<LINE_CONTINUATION>> {};
541
542struct SYMBOL_ENTRY : seq<SCH_SYMBOL_LINE, PIN_LIST, opt<eol>>{};
543
544
545// /<Signame>_<PinIdentifier>[.<Position>][!<Pintype>][:<Loading>]
546struct PIN_SIGNAL_NAME : seq<one<'/'>, STRING_EXCLUDING<WHITESPACE>> {};
547struct HIDDEN_PIN_ENTRY : seq<PIN_SIGNAL_NAME, plus<WHITESPACE>, PIN_LIST, opt<eol>>{};
548
549
550//******************
551// Join all together
552
554 seq
555 <
556 PART_HEADER, //.<Part name>[ (1234): 1 ;<Description>]
557 PART_PCB_COMPONENT, //<PCB Component Refname> [(Alternate)]
558
559 // In any order:
560 star<sor<
561 PART_VALUE, //[*VALUE <Value>]
562 PIN_NAMES_LIST, //[*PNM <ID><Name>[ <ID><Name>] ...]
563 PIN_LABELS_LIST, //[*PLB <ID><Label>[ <ID><Label>] ...]
564 PIN_EQUIVALENCES, //[*EQU_<ID>=<ID>[=<ID>=<ID>_etc ...]]
565 INTERNAL_SWAP_GROUP, //[*SYM SYM1 |*INT 2 3 |*INT 4 5]
566 EXTERNAL_SWAP_GROUP, //[*SYM SYM1 |*EXT 2 3 |*EXT 4 5]
567 DFN_LINE, //[*DFN_<Definition name>]
568 NGS_LINE, //[*NGS]
569 NPV_LINE, //[*NPV]
570 STM_LINE, //[*STM_<Component name stem>]
571 MXP_LINE, //[*MXP <Maximum number of connector pins>]
572 SPI_LINE, //[*SPI_[(<Part name>)]_[<Model>]_<Component Value>]
573 PAC_LINE, //[*PAC_(<Part name>)_<Acceptance Text>]
574 USER_PART_ATTRIBUTE, //[*<User-defined name>_<Value>]
575 SCM_ATTRIBUTE, //[$[!]<SCM Attribute name>(<Attribute value>)]
576 PCB_ATTRIBUTE, //[%[!]<PCB Attribute name>(<Attribute value>)]
577 PART_ATTRIBUTE, //[~[!]<Parts Library Attribute Name>(<Attribute Value>)]
578 SCH_PCB_ATTRIBUTE //[@[!]<SCM/PCB Attribute name>(<Attribute value>)]
579 >>,
580 star<SYMBOL_ENTRY>, //[<SCM Symbol Refname>][_(<SCM Alternate Refname>)]
581 //[Pin entry] [Pin entry] ...
582
583 star<HIDDEN_PIN_ENTRY> //[/<Signame>_<Pin entry>]
584
585 >
586{};
587
588
592struct GRAMMAR :
593 must<
594 opt<FORMAT>,
595 star<star<EMPTY_LINE>, HIERARCHY_NODE_ENTRY>,
596 plus
597 <
598 sor
599 <
600 PART_ENTRY,
601 EMPTY_LINE // optional empty line
602 >,
603 opt<eol>
604 >,
605 opt<TAO_PEGTL_ISTRING( ".END"), opt<eol>>,
606 star<EMPTY_LINE>,
607 tao::pegtl::eof // just putting "eof" results in ambiguous symbol
608 >
609{};
610
611
619struct VALID_HEADER : sor<FORMAT, seq< rep_max<5,EMPTY_LINE>, PART_HEADER>>{};
620
621} // 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.