/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2022 Roberto Fernandez Bautista * Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include namespace CADSTAR_PARTS_LIB { using namespace tao::pegtl; //-------------------- Grammar definition ---------------------------------------------------- /** * Needed, because PEGTL "space" includes newline characters */ struct WHITESPACE : one<' ', '\t'>{}; /** * Empty line with whitespaces */ struct EMPTY_LINE : seq< bol, star, eol>{}; /** * Any text in the format can span multiple lines using '&' */ struct LINE_CONTINUATION : seq, eol>{}; struct WHITESPACE_OR_CONTINUATION : sor {}; /** * String segment( no line continuation ), with exclusion rules */ template struct STR_SEGMENT_EXCLUDING : plus>, any>{}; /** * String with optional line continuation and exclusion rules */ template struct STRING_EXCLUDING : plus, opt> {}; /** * Control character with or without preceding whitespace */ template struct spaced_ch : seq, one>{}; /** * String inside quotation marks */ struct QUOTED_STRING : seq, STRING_EXCLUDING>, one<'"'>> {}; /** * String inside single quotation marks */ struct SINGLE_QUOTED_STRING : seq, STRING_EXCLUDING>, one<'\''>> {}; /** * String inside brackets with preceding spaces */ struct STRING_IN_BRACKETS : seq < spaced_ch<'('>, sor< QUOTED_STRING, STRING_EXCLUDING> >, one<')'> > {}; /** * String inside brackets with preceding spaces, ending with EOL or EOF */ struct STRING_IN_BRACKETS_EOLF : seq < spaced_ch<'('>, sor< QUOTED_STRING, STRING_EXCLUDING, eolf>> >, seq, eolf> > {}; // ************** // * FORMAT * // ************** // Definition of "Format" // # FORMAT struct CURRENT_FORMAT_NUMBER : plus {}; struct FORMAT : seq < bol, one<'#'>, star, TAO_PEGTL_ISTRING( "FORMAT" ), star, CURRENT_FORMAT_NUMBER, opt > {}; // Newer Parts files have possibility of specifying a tree-like structure to show hierarchy // // Example: //+N0 'root' & //'part1' 'part2' //+N1 N0 'subnode1' 'part3' 'part4' struct HIERARCHY_NODE_INDEX : plus{}; struct HIERARCHY_CURRENT_NODE : seq, HIERARCHY_NODE_INDEX>{}; struct HIERARCHY_PARENT_NODE : seq, HIERARCHY_NODE_INDEX>{}; // Different action struct HIERARCHY_NODE_NAME : SINGLE_QUOTED_STRING {}; struct HIERARCHY_PART_NAME : SINGLE_QUOTED_STRING {}; struct HIERARCHY_NODE_ENTRY : seq < bol, one<'+'>, HIERARCHY_CURRENT_NODE, // N1 plus, opt, // N0 star, HIERARCHY_NODE_NAME, // 'subnode1' star, star>, // 'part1' 'part2' opt > {}; // ************** // * PART ENTRY * // ************** // Part Header // ----------- //._[()][:][;] // string filters: struct PART_HEADER_START : one <'.'>{}; struct PART_NAME_FILTER : sor, spaced_ch<':'>, spaced_ch<';'>>{}; struct PART_NUMBER_FILTER : one<')'>{}; struct PART_VERSION_FILTER : spaced_ch<';'>{}; // part header elements: struct PART_NAME : STRING_EXCLUDING {}; struct PART_NUMBER : STRING_IN_BRACKETS {}; struct PART_VERSION : STRING_EXCLUDING {}; struct PART_DESCRIPTION : STRING_EXCLUDING<> {}; struct PART_HEADER : seq < bol, one<'.'>, must, opt, opt, PART_VERSION>>, opt, PART_DESCRIPTION>>, opt > {}; // Part - PCB Component // -------------------- //[_()] // string filters: struct PCB_COMPONENT_FILTER : spaced_ch<'('>{}; struct PCB_ALTERNATE_FILTER : one<')'>{}; // pcb component elements struct PCB_COMPONENT : STRING_EXCLUDING {}; struct PCB_ALTERNATE : STRING_IN_BRACKETS {}; struct PART_PCB_COMPONENT : seq < bol, PCB_COMPONENT, opt, opt > {}; // Part Value // ----------- //[*VALUE_] struct VALUE : STRING_EXCLUDING<> {}; struct PART_VALUE : seq < bol, TAO_PEGTL_ISTRING( "*VALUE"), plus, VALUE, opt > {}; struct PINNUM : plus {}; // Pin Names //[*PNM_=[_=]_etc] // Maximum 10 characters allowed for Pinname according to documentation struct PINNAME : rep_min_max<1,10,alnum> {}; struct PINNAME_ENTRY : seq < plus, PINNUM, one<'='>, PINNAME > {}; struct PIN_NAMES_LIST : seq < bol, TAO_PEGTL_ISTRING( "*PNM"), plus, opt > {}; // Pin Labels //[*PLB_=[_=]_etc] struct PINLABEL : sor> {}; struct PINLABEL_ENTRY : seq < plus, PINNUM, one<'='>, PINLABEL > {}; struct PIN_LABELS_LIST : seq < bol, TAO_PEGTL_ISTRING( "*PLB"), plus, opt > {}; // Pin Equivalences //[*EQU_=[==_etc ...]] struct EQUIVALENT_PIN : PINNUM {}; // same grammar but different action to be applied struct EQUIVALENT_PINS_GROUP : seq < plus, EQUIVALENT_PIN, plus, star, EQUIVALENT_PIN> > {}; struct PIN_EQUIVALENCES : seq < bol, TAO_PEGTL_ISTRING( "*EQU"), EQUIVALENT_PINS_GROUP, star, EQUIVALENT_PINS_GROUP>, opt > {}; // INTERNAL AND EXTERNAL PIN SWAPPING // *SYM_[] struct SYM_ELEMENT_NAME : STRING_EXCLUDING<> {}; struct SYM_LINE : seq < bol, TAO_PEGTL_ISTRING( "*SYM"), star, opt, opt > {}; struct GATE_PINS_LIST : seq < plus, EQUIVALENT_PIN, star < plus, EQUIVALENT_PIN > > {}; //[*INT__[_ etc ...]] struct INTERNAL_SWAP_GATE : seq < bol, TAO_PEGTL_ISTRING( "*INT"), GATE_PINS_LIST, opt > {}; //[*EXT__[_ etc ...]] struct EXTERNAL_SWAP_GATE : seq < bol, TAO_PEGTL_ISTRING( "*EXT"), GATE_PINS_LIST, opt > {}; // Internal swapping group E.g.: //*SYM SYM1 //*INT 2 3 //*INT 4 5 struct INTERNAL_SWAP_GROUP : seq < SYM_LINE, plus > {}; // External swapping group E.g.: //*SYM SYM1 //*EXT 2 3 //*EXT 4 5 struct EXTERNAL_SWAP_GROUP : seq < SYM_LINE, plus > {}; // Part Definition // ----------- //[*DFN_] struct DEFINITION_NAME : STRING_EXCLUDING<> {}; struct DFN_LINE : seq < bol, TAO_PEGTL_ISTRING( "*DFN"), plus, DEFINITION_NAME, opt > {}; //[*NGS] struct NGS_LINE : seq < bol, TAO_PEGTL_ISTRING( "*NGS"), opt > {}; //[*NPV] struct NPV_LINE : seq < bol, TAO_PEGTL_ISTRING( "*NPV"), opt > {}; //[*STM_] struct STEM : STRING_EXCLUDING<> {}; struct STM_LINE : seq < bol, TAO_PEGTL_ISTRING( "*STM"), plus, STEM, opt > {}; //[*MXP ] struct MAX_PIN_COUNT : plus {}; struct MXP_LINE : seq < bol, TAO_PEGTL_ISTRING( "*MXP"), plus, MAX_PIN_COUNT, opt > {}; //[*SPI_[()]_[]_] struct SPICE_PART_NAME : STRING_IN_BRACKETS {}; struct SPICE_MODEL : sor> {}; struct SPI_LINE : seq < bol, TAO_PEGTL_ISTRING( "*SPI"), plus, opt, star, SPICE_MODEL, opt > {}; //[*PAC_()_] struct ACCEPTANCE_PART_NAME : STRING_IN_BRACKETS {}; struct ACCEPTANCE_TEXT : STRING_EXCLUDING<> {}; struct PAC_LINE : seq < bol, TAO_PEGTL_ISTRING( "*PAC"), plus, opt, plus, ACCEPTANCE_TEXT, opt > {}; // User defined part attributes // ----------- //[*_] struct USER_PART_ATTRIBUTE_NAME : sor> {}; struct USER_PART_ATTRIBUTE_VALUE : STRING_EXCLUDING<> {}; struct USER_PART_ATTRIBUTE : seq < bol, one<'*'>, USER_PART_ATTRIBUTE_NAME, plus, USER_PART_ATTRIBUTE_VALUE, opt > {}; //---------------------------------------------------- // In-built attributes: schematic, PCB, both (sch+pcb) and parts //---------------------------------------------------- struct READONLY : one <'!'>{}; struct ATTRIBUTE_NAME : sor>> {}; struct ATTRIBUTE_VALUE : STRING_IN_BRACKETS {}; struct ATTRIBUTE_VALUE_EOLF : STRING_IN_BRACKETS_EOLF {}; template struct GENERIC_ATTRIBUTE : seq < bol, one, opt, ATTRIBUTE_NAME, ATTRIBUTE_VALUE_EOLF > {}; //[$[!]()] struct SCM_ATTRIBUTE : GENERIC_ATTRIBUTE<'$'>{}; //[%[!]()] struct PCB_ATTRIBUTE : GENERIC_ATTRIBUTE<'%'>{}; //[~[!]()] struct PART_ATTRIBUTE : GENERIC_ATTRIBUTE<'~'>{}; //[@[!]()] struct SCH_PCB_ATTRIBUTE : GENERIC_ATTRIBUTE<'@'>{}; //[][_()] struct SCH_NAME : sor>> {}; struct SCH_ALTERNATE : STRING_IN_BRACKETS {}; struct SCH_SYMBOL_LINE : seq, opt>{}; //[[.] [!] [:]] struct PIN_IDENTIFIER : plus{}; struct PIN_POSITION : range<'0', '3'>{}; struct PIN_TYPE : star{}; struct PIN_LOADING : plus{}; struct PIN_ENTRY : seq < PIN_IDENTIFIER, one<'.'>, PIN_POSITION, opt< one<'!'>, PIN_TYPE>, opt< one<':'>, PIN_LOADING> > {}; struct PIN_LIST : plus, opt> {}; struct SYMBOL_ENTRY : seq>{}; // /_[.][!][:] struct PIN_SIGNAL_NAME : seq, STRING_EXCLUDING> {}; struct HIDDEN_PIN_ENTRY : seq, PIN_LIST, opt>{}; //****************** // Join all together struct PART_ENTRY : seq < PART_HEADER, //.[ (1234): 1 ;] PART_PCB_COMPONENT, // [(Alternate)] // In any order: star] PIN_NAMES_LIST, //[*PNM [ ] ...] PIN_LABELS_LIST, //[*PLB