CADSTAR Parts: Add parsing of hierarchy tree
This commit is contained in:
parent
b70fe88145
commit
59d88e1871
|
@ -68,6 +68,12 @@ struct spaced_ch : seq<star<WHITESPACE>, one<CHAR_TO_FIND...>>{};
|
||||||
*/
|
*/
|
||||||
struct QUOTED_STRING : seq<one<'"'>, STRING_EXCLUDING<one<'"'>>, one<'"'>> {};
|
struct QUOTED_STRING : seq<one<'"'>, STRING_EXCLUDING<one<'"'>>, one<'"'>> {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String inside single quotation marks
|
||||||
|
*/
|
||||||
|
struct SINGLE_QUOTED_STRING : seq<one<'\''>, STRING_EXCLUDING<one<'\''>>, one<'\''>> {};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String inside brackets with preceding spaces
|
* String inside brackets with preceding spaces
|
||||||
*/
|
*/
|
||||||
|
@ -104,6 +110,33 @@ struct FORMAT : seq
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
// 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<digit>{};
|
||||||
|
struct HIERARCHY_CURRENT_NODE : seq<one<'N'>, HIERARCHY_NODE_INDEX>{};
|
||||||
|
struct HIERARCHY_PARENT_NODE : seq<one<'N'>, 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<WHITESPACE_OR_CONTINUATION>,
|
||||||
|
opt<HIERARCHY_PARENT_NODE>, // N0
|
||||||
|
star<WHITESPACE_OR_CONTINUATION>,
|
||||||
|
HIERARCHY_NODE_NAME, // 'subnode1'
|
||||||
|
star<WHITESPACE_OR_CONTINUATION>,
|
||||||
|
plus<HIERARCHY_PART_NAME, star<WHITESPACE_OR_CONTINUATION>>, // 'part1' 'part2'
|
||||||
|
opt<eol>
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
// **************
|
// **************
|
||||||
// * PART ENTRY *
|
// * PART ENTRY *
|
||||||
// **************
|
// **************
|
||||||
|
@ -542,8 +575,9 @@ struct PART_ENTRY :
|
||||||
* Grammar for CADSTAR Parts Library file format (*.lib)
|
* Grammar for CADSTAR Parts Library file format (*.lib)
|
||||||
*/
|
*/
|
||||||
struct GRAMMAR :
|
struct GRAMMAR :
|
||||||
must<seq<
|
must<
|
||||||
opt<FORMAT>,
|
opt<FORMAT>,
|
||||||
|
star<star<EMPTY_LINE>, HIERARCHY_NODE_ENTRY>,
|
||||||
plus
|
plus
|
||||||
<
|
<
|
||||||
sor
|
sor
|
||||||
|
@ -555,8 +589,8 @@ struct GRAMMAR :
|
||||||
>,
|
>,
|
||||||
opt<TAO_PEGTL_ISTRING( ".END"), opt<eol>>,
|
opt<TAO_PEGTL_ISTRING( ".END"), opt<eol>>,
|
||||||
star<EMPTY_LINE>,
|
star<EMPTY_LINE>,
|
||||||
must<eolf>
|
tao::pegtl::eof // just putting "eof" results in ambiguous symbol
|
||||||
>>
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ struct CADSTAR_SWAP_GROUP;
|
||||||
struct CADSTAR_ATTRIBUTE_VALUE;
|
struct CADSTAR_ATTRIBUTE_VALUE;
|
||||||
struct CADSTAR_PART_SYMBOL_ENTRY;
|
struct CADSTAR_PART_SYMBOL_ENTRY;
|
||||||
struct CADSTAR_PART_PIN;
|
struct CADSTAR_PART_PIN;
|
||||||
|
struct CADSTAR_PART_NODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CADSTAR Parts Library (*.lib) model - a data structure describing the contents of the
|
* CADSTAR Parts Library (*.lib) model - a data structure describing the contents of the
|
||||||
|
@ -40,6 +41,7 @@ struct CADSTAR_PART_PIN;
|
||||||
struct CADSTAR_PARTS_LIB_MODEL
|
struct CADSTAR_PARTS_LIB_MODEL
|
||||||
{
|
{
|
||||||
std::optional<long> m_FormatNumber;
|
std::optional<long> m_FormatNumber;
|
||||||
|
std::map<long, CADSTAR_PART_NODE> m_HierarchyNodes;
|
||||||
std::vector<CADSTAR_PART_ENTRY> m_PartEntries;
|
std::vector<CADSTAR_PART_ENTRY> m_PartEntries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -230,4 +232,12 @@ struct CADSTAR_SWAP_GROUP
|
||||||
std::vector<std::vector<long>> m_Gates;
|
std::vector<std::vector<long>> m_Gates;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct CADSTAR_PART_NODE
|
||||||
|
{
|
||||||
|
std::optional<long> m_ParentNodeIdx;
|
||||||
|
std::string m_Name;
|
||||||
|
std::vector<std::string> m_PartNames; ///< Part names belonging to this hierarchy
|
||||||
|
};
|
||||||
|
|
||||||
#endif //CADSTAR_PARTS_LIB_MODEL_H
|
#endif //CADSTAR_PARTS_LIB_MODEL_H
|
||||||
|
|
|
@ -39,6 +39,8 @@ struct CADSTAR_LIB_PARSER_STATE
|
||||||
std::string m_CurrentAttrName;
|
std::string m_CurrentAttrName;
|
||||||
std::string m_CurrentSignalName;
|
std::string m_CurrentSignalName;
|
||||||
long m_CurrentLong = 0;
|
long m_CurrentLong = 0;
|
||||||
|
CADSTAR_PART_NODE m_CurrentNode;
|
||||||
|
long m_CurrentNodeIdx = 0;
|
||||||
std::vector<long> m_CurrentPinEquivalenceGroup;
|
std::vector<long> m_CurrentPinEquivalenceGroup;
|
||||||
std::set<std::string> m_CurrentElementsParsed;
|
std::set<std::string> m_CurrentElementsParsed;
|
||||||
bool m_ReadOnly = false;
|
bool m_ReadOnly = false;
|
||||||
|
@ -89,6 +91,7 @@ DEFINE_CONTENT_TO_NUMBER_ACTION( PINNUM, m_CurrentLong );
|
||||||
DEFINE_CONTENT_TO_NUMBER_ACTION( MAX_PIN_COUNT, m_CurrentPart.m_MaxPinCount );
|
DEFINE_CONTENT_TO_NUMBER_ACTION( MAX_PIN_COUNT, m_CurrentPart.m_MaxPinCount );
|
||||||
DEFINE_CONTENT_TO_NUMBER_ACTION( PIN_IDENTIFIER, m_CurrentPin.m_Identifier );
|
DEFINE_CONTENT_TO_NUMBER_ACTION( PIN_IDENTIFIER, m_CurrentPin.m_Identifier );
|
||||||
DEFINE_CONTENT_TO_NUMBER_ACTION( PIN_LOADING, m_CurrentPin.m_Loading );
|
DEFINE_CONTENT_TO_NUMBER_ACTION( PIN_LOADING, m_CurrentPin.m_Loading );
|
||||||
|
DEFINE_CONTENT_TO_NUMBER_ACTION( HIERARCHY_NODE_INDEX, m_CurrentLong );
|
||||||
|
|
||||||
|
|
||||||
// unfortunately the one below needs to be defined separately
|
// unfortunately the one below needs to be defined separately
|
||||||
|
@ -176,6 +179,69 @@ struct CADSTAR_LIB_PARSER_ACTION<STR_SEGMENT_EXCLUDING<EXCLUSION_RULES...>>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// HIERARCHY actions
|
||||||
|
//
|
||||||
|
template <>
|
||||||
|
struct CADSTAR_LIB_PARSER_ACTION<HIERARCHY_NODE_ENTRY>
|
||||||
|
{
|
||||||
|
static void apply0( CADSTAR_LIB_PARSER_STATE& s )
|
||||||
|
{
|
||||||
|
assert( s.m_CurrentString == "" && s.m_CurrentAttrName == "" );
|
||||||
|
s.m_ParsedModel.m_HierarchyNodes.insert(
|
||||||
|
{ s.m_CurrentNodeIdx, std::move( s.m_CurrentNode ) } );
|
||||||
|
s.m_CurrentNode = CADSTAR_PART_NODE();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CADSTAR_LIB_PARSER_ACTION<HIERARCHY_CURRENT_NODE>
|
||||||
|
{
|
||||||
|
static void apply0( CADSTAR_LIB_PARSER_STATE& s )
|
||||||
|
{
|
||||||
|
assert( s.m_CurrentString == "" && s.m_CurrentAttrName == "" );
|
||||||
|
s.m_CurrentNodeIdx = s.m_CurrentLong;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CADSTAR_LIB_PARSER_ACTION<HIERARCHY_PARENT_NODE>
|
||||||
|
{
|
||||||
|
static void apply0( CADSTAR_LIB_PARSER_STATE& s )
|
||||||
|
{
|
||||||
|
assert( s.m_CurrentString == "" && s.m_CurrentAttrName == "" );
|
||||||
|
s.m_CurrentNode.m_ParentNodeIdx = s.m_CurrentLong;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CADSTAR_LIB_PARSER_ACTION<HIERARCHY_NODE_NAME>
|
||||||
|
{
|
||||||
|
static void apply0( CADSTAR_LIB_PARSER_STATE& s )
|
||||||
|
{
|
||||||
|
assert( s.m_CurrentAttrName == "" );
|
||||||
|
s.m_CurrentNode.m_Name = std::move( s.m_CurrentString );
|
||||||
|
s.m_CurrentString = "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CADSTAR_LIB_PARSER_ACTION<HIERARCHY_PART_NAME>
|
||||||
|
{
|
||||||
|
static void apply0( CADSTAR_LIB_PARSER_STATE& s )
|
||||||
|
{
|
||||||
|
assert( s.m_CurrentAttrName == "" );
|
||||||
|
s.m_CurrentNode.m_PartNames.push_back( std::move( s.m_CurrentString ) );
|
||||||
|
s.m_CurrentString = "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// PART_ENTRY action
|
// PART_ENTRY action
|
||||||
// We just push the part to the vector of parts in our state
|
// We just push the part to the vector of parts in our state
|
||||||
template <>
|
template <>
|
||||||
|
|
|
@ -193,10 +193,15 @@ BOOST_AUTO_TEST_CASE( ReadContent )
|
||||||
"# Format 32\r\n"
|
"# Format 32\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
|
"+N0 'root' &\r\n"
|
||||||
|
"'part1' &\r\n"
|
||||||
|
"'part2'\r\n"
|
||||||
|
"+N1 N0 'subnode1' &\r\n"
|
||||||
|
"'part3' &\r\n"
|
||||||
|
"'part4'\r\n"
|
||||||
|
"\r\n"
|
||||||
" \r\n"
|
" \r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"\r\n"
|
|
||||||
"\r\n"
|
|
||||||
".<Part name> (<Part number>):<Part version>;<Description>\r\n"
|
".<Part name> (<Part number>):<Part version>;<Description>\r\n"
|
||||||
"<PCB Component Refname> (<PCB Alternate Refname>)\r\n"
|
"<PCB Component Refname> (<PCB Alternate Refname>)\r\n"
|
||||||
"*VALUE <Value>\r\n"
|
"*VALUE <Value>\r\n"
|
||||||
|
@ -242,6 +247,8 @@ BOOST_AUTO_TEST_CASE( ReadContent )
|
||||||
std::optional<std::string> nullOptString;
|
std::optional<std::string> nullOptString;
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL( result.m_FormatNumber, 32 );
|
BOOST_CHECK_EQUAL( result.m_FormatNumber, 32 );
|
||||||
|
BOOST_REQUIRE_EQUAL( result.m_HierarchyNodes.size(), 2 ); // root and subnode
|
||||||
|
|
||||||
BOOST_REQUIRE_EQUAL( result.m_PartEntries.size(), 1 );
|
BOOST_REQUIRE_EQUAL( result.m_PartEntries.size(), 1 );
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Name, "<Part name>" );
|
BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Name, "<Part name>" );
|
||||||
|
|
Loading…
Reference in New Issue