Don't eat opening parens on nested list

This commit is contained in:
Thomas Krijnen
2024-08-22 12:07:00 +02:00
parent 1534e7962e
commit 7d2066e7c2
4 changed files with 15 additions and 92 deletions
+8 -91
View File
@@ -41,86 +41,6 @@ namespace {
template<typename Variant, typename T>
constexpr bool is_type_in_variant_v = is_type_in_variant<Variant, T>::value;
IfcUtil::ArgumentType get_element_type(IfcUtil::ArgumentType aggregate) {
switch (aggregate) {
case IfcUtil::Argument_AGGREGATE_OF_INT:
return IfcUtil::Argument_INT;
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE:
return IfcUtil::Argument_DOUBLE;
case IfcUtil::Argument_AGGREGATE_OF_STRING:
return IfcUtil::Argument_STRING;
case IfcUtil::Argument_AGGREGATE_OF_BINARY:
return IfcUtil::Argument_BINARY;
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE:
return IfcUtil::Argument_ENTITY_INSTANCE;
case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE:
return IfcUtil::Argument_EMPTY_AGGREGATE;
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT:
return IfcUtil::Argument_AGGREGATE_OF_INT;
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE:
return IfcUtil::Argument_AGGREGATE_OF_DOUBLE;
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE:
return IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE;
default:
return IfcUtil::Argument_UNKNOWN;
}
}
bool can_coerce(IfcUtil::ArgumentType target, IfcUtil::ArgumentType source) {
if (source == IfcUtil::Argument_EMPTY_AGGREGATE) {
return target == IfcUtil::Argument_AGGREGATE_OF_INT ||
target == IfcUtil::Argument_AGGREGATE_OF_DOUBLE ||
target == IfcUtil::Argument_AGGREGATE_OF_STRING ||
target == IfcUtil::Argument_AGGREGATE_OF_BINARY ||
target == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE ||
target == IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE;
} if (source == IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE) {
return target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE;
} else if (source == IfcUtil::Argument_BOOL && target == IfcUtil::Argument_LOGICAL) {
return true;
} else {
// @todo make it configurable to coerce int to double, which is not standard compliant?
auto elt = get_element_type(target);
auto els = get_element_type(source);
if (elt != IfcUtil::Argument_UNKNOWN && els != IfcUtil::Argument_UNKNOWN) {
return can_coerce(elt, els);
}
return false;
}
}
// we need to have a compatibility between (#123, IfcLengthMeasure(123.))
// which are different token kinds
void get_token_type(std::vector<uint8_t>& r, const boost::variant<IfcUtil::IfcBaseClass*,IfcParse::Token, IfcParse::parse_context*>& v) {
r.push_back((uint8_t)v.which());
if (v.which() == 0) {
// pass
} else if (v.which() == 1) {
r.push_back((uint8_t)boost::get<IfcParse::Token>(v).type);
} else if (v.which() == 2) {
// @todo check for empty aggregate
get_token_type(r, boost::get<IfcParse::parse_context*>(v)->tokens_.front());
}
}
bool can_coerce(const std::vector<uint8_t>& target, const std::vector<uint8_t>& source) {
if (target == std::vector<uint8_t>{0, 0} && source == std::vector<uint8_t>{1, IfcParse::Token_IDENTIFIER}) {
return true;
}
if (source == std::vector<uint8_t>{0, 0} && target == std::vector<uint8_t>{1, IfcParse::Token_IDENTIFIER}) {
return true;
}
return source == target;
}
struct InstanceReference {
int v;
operator int() const {
@@ -149,7 +69,7 @@ namespace {
}
}
template <typename Fn>
template <size_t Depth, typename Fn>
void construct_(IfcParse::parse_context& p, const IfcParse::aggregation_type* aggr, Fn fn) {
if (p.tokens_.empty()) {
// @todo instead of ugly if-else we could also default initialize the respective
@@ -203,6 +123,7 @@ namespace {
vec_ptr->push_back(v);
} else {
// inconsistent aggregate valuation
// @todo boolean -> logical upgrade
}
}
} else {
@@ -216,14 +137,10 @@ namespace {
// @todo get aggregate of enumeration
dispatch_token(v, aggr && aggr->type_of_element()->as_named_type() ? aggr->type_of_element()->as_named_type()->declared_type() : nullptr, append_to_aggregate_storage);
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
/*construct_(*v, [&aggregate_storage](auto& v) {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<std::decay_t<decltype(v)>>{ v };
} else {
boost::get<std::vector<std::decay_t<decltype(v)>>>(aggregate_storage).push_back(v);
}
});*/
// Too deeply nested list
if constexpr (Depth < 3) {
construct_<Depth + 1>(*v, nullptr, append_to_aggregate_storage);
}
// nested list
} else {
append_to_aggregate_storage(v);
}
@@ -294,11 +211,11 @@ IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_re
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
const auto *pt = param_type;
if (pt) {
while (pt->as_named_type()) {
while (pt->as_named_type() && pt->as_named_type()->declared_type()->as_type_declaration()) {
pt = pt->as_named_type()->declared_type()->as_type_declaration()->declared_type();
}
}
construct_(*v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index](const auto& v) {
construct_<0>(*v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index](const auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<reference_or_simple_type>>) {
references_to_resolve.push_back({ {name, index }, v });
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<std::vector<reference_or_simple_type>>>) {
+5
View File
@@ -689,9 +689,11 @@ std::string TokenFunc::toString(const Token& token) {
void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::entity* entity, parse_context& context, int attribute_index) {
Token next = tokens->Next();
/*
if (TokenFunc::isOperator(next, '(')) {
next = tokens->Next();
}
*/
size_t attribute_index_within_data = 0;
size_t return_value = 0;
@@ -715,6 +717,7 @@ void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::enti
if (TokenFunc::isKeyword(next)) {
try {
parse_context ps;
tokens->Next();
load(0, nullptr, ps, -1);
const auto *decl = schema_->declaration_by_name(TokenFunc::asStringRef(next));
auto* simple_type_instance = schema_->instantiate(decl, ps.construct(-1, references_to_resolve, decl));
@@ -744,6 +747,7 @@ IfcEntityInstanceData IfcParse::read(unsigned int i, IfcFile* f) {
}
const IfcParse::declaration* ty = f->schema()->declaration_by_name(TokenFunc::asStringRef(datatype));
parse_context pc;
f->tokens->Next();
f->load(i, ty->as_entity(), pc, -1);
return IfcEntityInstanceData(pc.construct(i, f->references_to_resolve, ty));
}
@@ -1295,6 +1299,7 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
}
parse_context ps;
tokens->Next();
load(current_id, entity_type->as_entity(), ps, -1);
instance = schema_->instantiate(entity_type, ps.construct(current_id, references_to_resolve, entity_type));
instance->file_ = this;
+1
View File
@@ -39,6 +39,7 @@ using namespace IfcParse;
namespace {
IfcEntityInstanceData read_from_file(IfcFile* f, size_t s) {
parse_context pc;
f->tokens->Next();
f->load(-1, nullptr, pc, -1);
return pc.construct(-1, f->references_to_resolve, nullptr);
/*std::ostringstream oss;
+1 -1
View File
@@ -223,7 +223,7 @@ public:
// in various places.
throw IfcParse::IfcException(
"Type held at index " + std::to_string(index) + " is " +
get_type_name(index) + " and not " + typeid(T).name()
get_type_name(size_and_indices_[index + 1]) + " and not " + typeid(T).name()
);
}
using V = typename std::tuple_element<impl::TypeIndex_v<T, Types...>, impl::MapTypes_t<Types... >>::type;