Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[memory][scs][parser] Don't generate arcs from sc-element classes #434

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d7438be
[memory][scs][parser] Don't generate arcs from sc-element classes
NikitaZotov Nov 11, 2024
b784cf1
[docs] Apply changes
NikitaZotov Nov 11, 2024
82bf402
[memory][scs][tests] Check that arc between type of sc-element and sc…
NikitaZotov Nov 11, 2024
7f21c26
[memory][scs][tests] Don't ignore arcs to types of elements nodes
NikitaZotov Nov 14, 2024
68c4989
[memory][scs][tests] Throw errors if element types are used incorrectly
NikitaZotov Nov 15, 2024
64cda93
[memory][template][scs][build][tests] Clarify exception if element is…
NikitaZotov Nov 15, 2024
49ef76b
[memory][scs][tests] Don't allows arcs from to arcs from sc-element t…
NikitaZotov Nov 21, 2024
dc2cc5a
[memory][scs][tests] Add sc-arcs from structure to element types if e…
NikitaZotov Nov 22, 2024
aa1e010
[memory][scs][tests] Fix duplicating adding sc-element types to struc…
NikitaZotov Nov 26, 2024
636dd68
[memory][scs] Use multimap instead of unordered_multimap to avoid cor…
NikitaZotov Nov 29, 2024
6db7a3b
[memory][scs] Check types of sc-elements denoting sc-elements types
NikitaZotov Dec 2, 2024
2d20d6a
[memory][scs][tests] Check extendability to sc.s-types
NikitaZotov Dec 5, 2024
a055bfb
Review fixes
NikitaZotov Dec 9, 2024
05b9f2b
[memory][scs][tests] Check that type of sc-elements can be extended t…
NikitaZotov Dec 9, 2024
2786023
Review fixes
NikitaZotov Dec 13, 2024
88ef24b
Review fixes
NikitaZotov Dec 17, 2024
2ddb74d
[memory][scs][tests] Check const and var masks
NikitaZotov Dec 20, 2024
f03dec5
[memory][scs] Clarify checks for extendability of source and target e…
NikitaZotov Dec 26, 2024
cfeb5c6
[memory][scs][tests] Tests const and var masks
NikitaZotov Dec 29, 2024
3233977
[memory][scs][tests] Review var and object names, comments
NikitaZotov Jan 13, 2025
02f6116
[refactor][memory][scs] Clarify names for vars with constancy of sour…
NikitaZotov Jan 16, 2025
b926ce1
[refactor] Format sources with scs substring
NikitaZotov Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ See documentation, to learn more about using new API.

### Changed

- SCsParser no longer generates sc-arcs from types of sc-elements to sc-elements
- Description of project in Readme
- Working directory for each test has been changed to the test's source dir
- `gtest` and `benchmark` are installed via Conan or OS package managers instead of using them as git submodules
Expand Down
1 change: 1 addition & 0 deletions sc-memory/sc-memory/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ add_dependencies(sc-memory
)

if(${SC_CLANG_FORMAT_CODE})
target_clangformat_setup(SCsParser)
target_clangformat_setup(sc-memory)
endif()

Expand Down
31 changes: 24 additions & 7 deletions sc-memory/sc-memory/include/sc-memory/scs/scs_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <stack>
#include <map>
#include <string>
#include <functional>
#include <unordered_set>

namespace scs
{
Expand Down Expand Up @@ -44,6 +46,7 @@ class ParsedElement
_SC_EXTERN ScType const & GetType() const;

_SC_EXTERN Visibility GetVisibility() const;
_SC_EXTERN bool IsElementType() const;

_SC_EXTERN std::string const & GetValue() const;

Expand All @@ -60,29 +63,33 @@ class ParsedElement
bool m_isReversed : 1; // flag used just for an connectors
std::string m_value; // string representation of content/link value
bool m_isURL : 1; // flag used to determine if ScLink value is an URL
bool m_isElementType; // flag denoting whether the element is an sc-element, denoting the type of sc-elements
};

class ElementHandle
{
public:
_SC_EXTERN explicit ElementHandle(ElementID id);
_SC_EXTERN ElementHandle();
_SC_EXTERN ElementHandle(ElementID id, bool isLocal);
_SC_EXTERN ElementHandle(ElementID id, Visibility visibility, bool IsElementType = false);
_SC_EXTERN ElementHandle(ElementHandle const & other) = default;

_SC_EXTERN ElementID operator*() const;
_SC_EXTERN Visibility GetVisibility() const;
_SC_EXTERN bool IsLocal() const;
_SC_EXTERN bool IsElementType() const;
_SC_EXTERN bool IsValid() const;
_SC_EXTERN bool operator==(ElementHandle const & other) const;
_SC_EXTERN bool operator!=(ElementHandle const & other) const;
_SC_EXTERN ElementHandle & operator=(ElementHandle const & other);
_SC_EXTERN bool operator<(ElementHandle const & other) const;

private:
static const ElementID INVALID_ID = std::numeric_limits<ElementID>::max();
static ElementID const INVALID_ID = std::numeric_limits<ElementID>::max();

ElementID m_id;
bool m_isLocal;
Visibility m_visibility;
bool m_isElementType;
};

struct ParsedTriple
Expand All @@ -104,7 +111,7 @@ class Parser
friend class scsParser;

// Number of parsed elements, to preallocate container
static const size_t PARSED_PREALLOC_NUM = 1024;
static size_t const PARSED_PREALLOC_NUM = 1024;

public:
using TripleVector = std::vector<ParsedTriple>;
Expand All @@ -115,8 +122,10 @@ class Parser
_SC_EXTERN Parser();

_SC_EXTERN bool Parse(std::string const & str);
_SC_EXTERN ParsedElement const & GetParsedElement(ElementHandle const & elID) const;
_SC_EXTERN ParsedElement const & GetParsedElement(ElementHandle const & handle) const;
_SC_EXTERN TripleVector const & GetParsedTriples() const;
_SC_EXTERN void ForEachTripleForGeneration(
std::function<void(ParsedElement const &, ParsedElement const &, ParsedElement const &)> const & callback) const;
_SC_EXTERN std::string const & GetParseError() const;
_SC_EXTERN AliasHandles const & GetAliases() const;

Expand All @@ -130,8 +139,9 @@ class Parser
}

protected:
ParsedElement & GetParsedElementRef(ElementHandle const & elID);
ParsedElement & GetParsedElementRef(ElementHandle const & handle);

bool IsElementTypeOutgoingBaseArc(ParsedElement const & element) const;
ElementHandle ResolveAlias(std::string const & name);
ElementHandle ProcessIdentifier(std::string const & name);
ElementHandle ProcessIdentifierLevel1(std::string const & type, std::string const & name);
Expand All @@ -144,10 +154,15 @@ class Parser
void ProcessContourBegin();
void ProcessContourEnd(ElementHandle const & contourHandle);

void ProcessTriple(ElementHandle const & source, ElementHandle const & connector, ElementHandle const & target);
void ProcessTriple(
ElementHandle const & sourceHandle,
ElementHandle const & connectorHandle,
ElementHandle const & targetHandle);
void ProcessAssign(std::string const & alias, ElementHandle const & value);

private:
ParsedElementVector & GetContainerByElementVisibilityRef(Visibility visibility);
ParsedElementVector const & GetContainerByElementVisibility(Visibility visibility) const;
ElementHandle AppendElement(
std::string idtf,
ScType const & type = ScType::Unknown,
Expand All @@ -169,6 +184,8 @@ class Parser
TripleVector m_parsedTriples;
IdtfToParsedElementMap m_idtfToParsedElement;
AliasHandles m_aliasHandles;
std::unordered_set<std::string> m_elementTypeOutgoingBaseArcs;
std::multimap<std::string, ElementHandle> m_elementTypeNotOutgoingBaseArcsToElementTypes;

std::string m_lastError;

Expand Down
4 changes: 2 additions & 2 deletions sc-memory/sc-memory/include/sc-memory/scs/scs_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ class TypeResolver final
static std::string GetSCsElementKeynode(ScType const & type);

static ScType const & GetConnectorType(std::string const & connectorAlias);
static ScType const & GetKeynodeType(std::string const & keynodeAlias);
static ScType const & GetElementType(std::string const & keynodeAlias);

static bool IsConnectorReversed(std::string const & connectorAlias);
static bool IsConst(std::string const & idtf);
static bool IsConnectorAttrConst(std::string const & attr);
static bool IsKeynodeType(std::string const & alias);
static bool IsElementType(std::string const & alias);
static bool IsUnnamed(std::string const & alias);

protected:
Expand Down
69 changes: 41 additions & 28 deletions sc-memory/sc-memory/src/sc_scs_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,38 @@ class StructGenerator
}

// generate triples
auto const & triples = parser.GetParsedTriples();
for (auto const & t : triples)
{
auto const & src = parser.GetParsedElement(t.m_source);
auto const & connector = parser.GetParsedElement(t.m_connector);
auto const & trg = parser.GetParsedElement(t.m_target);

auto const & srcAddrResult = ResolveElement(src);
auto const & trgAddrResult = ResolveElement(trg);
std::unordered_set<std::string> typeArcsCache;
parser.ForEachTripleForGeneration(
[&](scs::ParsedElement const & source,
scs::ParsedElement const & connector,
scs::ParsedElement const & target) -> void
{
auto const & sourceResult = ResolveElement(source);
auto const & targetResult = ResolveElement(target);

if (!connector.GetType().IsConnector())
SC_THROW_EXCEPTION(utils::ExceptionInvalidType, "Specified sc-connector in triple has incorrect type.");
ScType const & connectorType = connector.GetType();
std::string const & connectorIdtf = connector.GetIdtf();
if (!connectorType.IsConnector())
SC_THROW_EXCEPTION(
utils::ExceptionInvalidType,
"Specified in triple sc-connector `" << connectorIdtf << "` has incorrect type `"
<< std::string(connectorType) << "`.");

ScAddr const arcAddr = m_ctx.GenerateConnector(connector.GetType(), srcAddrResult.first, trgAddrResult.first);
m_idtfCache.insert({connector.GetIdtf(), arcAddr});
ScAddr const connectorAddr = m_ctx.GenerateConnector(connectorType, sourceResult.first, targetResult.first);
m_idtfCache.insert({connectorIdtf, connectorAddr});

if (m_outputStructure.IsValid())
{
AppendToOutputStructure(srcAddrResult.first, arcAddr, trgAddrResult.first);
AppendToOutputStructure(srcAddrResult.second);
AppendToOutputStructure(trgAddrResult.second);
}
}
if (m_outputStructure.IsValid())
{
AppendToOutputStructure(sourceResult.first, connectorAddr, targetResult.first);
AppendToOutputStructure(sourceResult.second);
AppendToOutputStructure(targetResult.second);
}
});

parser.ForEachParsedElement(
[this](scs::ParsedElement const & el)
{
if (m_idtfCache.find(el.GetIdtf()) == m_idtfCache.end() && !el.GetType().IsConnector()
&& !scs::TypeResolver::IsKeynodeType(el.GetIdtf()))
if (m_idtfCache.find(el.GetIdtf()) == m_idtfCache.cend() && !el.GetType().IsConnector())
ResolveElement(el);
});
}
Expand Down Expand Up @@ -160,14 +163,21 @@ class StructGenerator
{
if (type.IsLink())
{
// TODO(NikitaZotov): Throw exception if this sc-link is a sc-link with system identifier of sc-element
// denoting sc-elements type, and type of sc-element, for which this sc-link is specified as a system
// identifier, can't be extended to ScType::ConstNodeClass. See
// SCsHelperTest.GenerateBySCs_ContourWithExplicitlySpecifiedElementTypeSystemIdentifier.
resultAddr = m_ctx.GenerateLink(type);
SetupLinkContent(resultAddr, el);
}
else
resultAddr = m_ctx.GenerateNode(type);
}
else
SC_THROW_EXCEPTION(utils::ExceptionInvalidState, "Incorrect element type at this state.");
SC_THROW_EXCEPTION(
utils::ExceptionInvalidState,
"Element `" << el.GetIdtf() << "` can't be resolved, because it has not sc-node type `"
<< std::string(type) << "`.");

// setup system identifier
if (el.GetVisibility() == scs::Visibility::System)
Expand All @@ -177,9 +187,7 @@ class StructGenerator
result = {quintuple.addr2, quintuple.addr3, quintuple.addr4, quintuple.addr5};
}
else if (el.GetVisibility() == scs::Visibility::Global)
{
result = SetSCsGlobalIdtf(el.GetIdtf(), resultAddr);
}
}
else
{
Expand All @@ -190,12 +198,15 @@ class StructGenerator
if (oldType.CanExtendTo(newType))
m_ctx.SetElementSubtype(resultAddr, newType);
else if (!newType.CanExtendTo(oldType))
SC_THROW_EXCEPTION(utils::ExceptionInvalidType, "Duplicate element type for " + el.GetIdtf());
SC_THROW_EXCEPTION(
utils::ExceptionInvalidType,
"Can't extend type `" << std::string(oldType) << "` to type `" << std::string(newType)
<< "` for element `" << el.GetIdtf() << "`.");
}
}

// anyway save in cache
m_idtfCache.insert(std::make_pair(idtf, resultAddr));
m_idtfCache.insert({idtf, resultAddr});
}

return {resultAddr, result};
Expand Down Expand Up @@ -232,7 +243,8 @@ class StructGenerator
{
// check if it's a number format
std::regex const rNumber(
"^\\^\"(int8|int16|int32|int64|uint8|uint16|uint32|uint64|float|double)\\s*:\\s*([0-9]+|[0-9]+[.][0-9]+)\"$");
"^\\^\"(int8|int16|int32|int64|uint8|uint16|uint32|uint64|float|double)\\s*:\\s*([0-9]+|[0-9]+[.][0-9]+)"
"\"$");
std::smatch result;
if (std::regex_match(el.GetValue(), result, rNumber))
{
Expand Down Expand Up @@ -289,6 +301,7 @@ class StructGenerator
SCsHelper::SCsHelper(ScMemoryContext & ctx, SCsFileInterfacePtr fileInterface)
: m_ctx(ctx)
, m_fileInterface(std::move(fileInterface))

{
}

Expand Down
48 changes: 18 additions & 30 deletions sc-memory/sc-memory/src/sc_template_scs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,56 +36,44 @@ class ScTemplateBuilderFromScs
utils::ScKeynodeCache keynodes(m_ctx);
std::unordered_set<std::string> passed;

auto const MakeTemplItem = [&passed, &keynodes](scs::ParsedElement const & el, ScTemplateItem & outValue) -> bool
auto const MakeTemplItem = [&passed, &keynodes](scs::ParsedElement const & el, ScTemplateItem & outValue) -> void
{
std::string const & idtf = el.GetIdtf();
bool const isUnnamed = scs::TypeResolver::IsUnnamed(idtf);
bool const isPassed = passed.find(idtf) != passed.cend();

if (!isUnnamed && isPassed)
{
outValue.SetReplacement(idtf.c_str());
}
else
{
sc_char const * alias = (isUnnamed ? nullptr : idtf.c_str());
sc_char const * alias = isUnnamed ? nullptr : idtf.c_str();
ScAddr const addr = keynodes.GetKeynode(idtf);
if (addr.IsValid())
{
outValue.SetAddr(addr, alias);
}
else if (el.GetType().IsVar())
outValue.SetType(el.GetType(), alias);
else
{
if (el.GetType().IsVar())
{
outValue.SetType(el.GetType(), alias);
}
else
{
SC_THROW_EXCEPTION(utils::ExceptionInvalidState, "Can't find element " << idtf);
return false;
}
}
SC_THROW_EXCEPTION(
utils::ExceptionInvalidState,
"Specified element with system identifier `" << idtf << "` can't be found.");
}

passed.insert(idtf);

return true;
};

for (scs::ParsedTriple const & t : m_parser.GetParsedTriples())
{
scs::ParsedElement const & src = m_parser.GetParsedElement(t.m_source);
scs::ParsedElement const & connector = m_parser.GetParsedElement(t.m_connector);
scs::ParsedElement const & trg = m_parser.GetParsedElement(t.m_target);

ScTemplateItem srcItem, connectorItem, trgItem;
m_parser.ForEachTripleForGeneration(
[&](scs::ParsedElement const & source,
scs::ParsedElement const & connector,
scs::ParsedElement const & target) -> void
{
ScTemplateItem sourceItem, connectorItem, targetItem;

if (!MakeTemplItem(src, srcItem) || !MakeTemplItem(connector, connectorItem) || !MakeTemplItem(trg, trgItem))
break;
MakeTemplItem(source, sourceItem);
MakeTemplItem(connector, connectorItem);
MakeTemplItem(target, targetItem);

templ->Triple(srcItem, connectorItem, trgItem);
}
templ->Triple(sourceItem, connectorItem, targetItem);
});
}

private:
Expand Down
6 changes: 1 addition & 5 deletions sc-memory/sc-memory/src/scs/scs.g4
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,7 @@ idtf_set_elements [std::string setType]
locals [ElementHandle prevArc]
: {
std::string const setIdtf = "..set_" + std::to_string($ctx->start->getLine()) + "_" + std::to_string($ctx->start->getCharPositionInLine());
$ctx->handle = m_parser->ProcessIdentifier(setIdtf);
ElementHandle const typeArc = m_parser->ProcessConnector("->");
ElementHandle const typeClass = m_parser->ProcessIdentifier("sc_node_tuple");

m_parser->ProcessTriple(typeClass, typeArc, $ctx->handle);
$ctx->handle = m_parser->ProcessIdentifierLevel1("sc_node_tuple", setIdtf);
}
a1=attr_list? i1=idtf_common
{
Expand Down
Loading