First Commit
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
# IfcOpenShell express schema parser and code generator
|
||||
|
||||
This folder contains Python code to generate C++ type information based on an
|
||||
Express schema. In particular is has only been tested using recent version of
|
||||
the IFC schema and will most likely fail on any other Express schema.
|
||||
|
||||
The code can be invoked in the following way and results in several code outputs
|
||||
named according to the schema name in the Express file. A python 3 interpreter
|
||||
with the `pyparsing` (`pip install pyparsing`) library is required.
|
||||
|
||||
note:
|
||||
**Keep in mind that Express is not very suitable for this kind of usage. In the end, (as far as I can tell) no tool is able to read your model, because it doesn't understand the schema as it has no notion of the core part vs the addition.**
|
||||
|
||||
## Command line usage for code generation
|
||||
|
||||
The usage for C++ project.
|
||||
~~~
|
||||
# bootstrap.py express.bnf in ifcopenshell-python.ifcopenshell.express.
|
||||
>>> python3 bootstrap.py express.bnf > express_parser.py
|
||||
>>> python3 express_parser.py IFC2X3_TC1.exp header implementation schema_class definitions
|
||||
~~~
|
||||
|
||||
The usage for python project.
|
||||
~~~
|
||||
# code rule generation
|
||||
# generating 'ifcopenshell.express.rules.IFC2X3_TC1' in ifcopenshell-python.ifcopenshell.express.rules.
|
||||
# rule_compiler in ifcopenshell-python.ifcopenshell.express.
|
||||
>>> python -m rule_compiler IFC2X3_TC1.exp
|
||||
~~~
|
||||
|
||||
## Programmatic usage
|
||||
|
||||
~~~py
|
||||
import ifcopenshell
|
||||
import ifcopenshell.express
|
||||
schema = ifcopenshell.express.parse('IFC.exp')
|
||||
ifcopenshell.register_schema(schema)
|
||||
f = ifcopenshell.file(schema=schema.schema.name())
|
||||
f.createIfcProject(ifcopenshell.guid.new())
|
||||
~~~
|
||||
@@ -0,0 +1,43 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import schema_class
|
||||
|
||||
d = os.path.abspath(os.path.dirname(__file__))
|
||||
sys.path.append(d)
|
||||
|
||||
exp_parser_fn = os.path.join(d, "express_parser.py")
|
||||
|
||||
if not os.path.exists(exp_parser_fn):
|
||||
with open(exp_parser_fn, "w") as f:
|
||||
subprocess.call([sys.executable, "bootstrap.py"], cwd=d, stdout=f)
|
||||
|
||||
|
||||
def parse(fn: str) -> schema_class.SchemaClass:
|
||||
import express_parser
|
||||
import schema_class
|
||||
|
||||
mapping = express_parser.parse(fn)
|
||||
return schema_class.SchemaClass(mapping, schema_class.LateBoundSchemaInstantiator).code
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,259 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import string
|
||||
import operator
|
||||
import itertools
|
||||
|
||||
from pyparsing import *
|
||||
|
||||
try:
|
||||
from functools import reduce
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
class Expression:
|
||||
def __init__(self, contents):
|
||||
self.contents = contents[0]
|
||||
|
||||
def __repr__(self):
|
||||
if self.op is None:
|
||||
return repr(self.contents)
|
||||
c = [isinstance(c, str) and c or str(c) for c in self.contents]
|
||||
if "%s" in self.op:
|
||||
return self.op % (" ".join(c))
|
||||
else:
|
||||
return "(%s)" % (" %s " % self.op).join(c)
|
||||
|
||||
def __iter__(self):
|
||||
return self.contents.__iter__()
|
||||
|
||||
|
||||
class Union(Expression):
|
||||
op = "|"
|
||||
|
||||
|
||||
class Concat(Expression):
|
||||
op = "+"
|
||||
|
||||
|
||||
class Optional(Expression):
|
||||
op = "Optional(%s)"
|
||||
|
||||
|
||||
class Repeated(Expression):
|
||||
op = "ZeroOrMore(%s)"
|
||||
|
||||
|
||||
class Term(Expression):
|
||||
op = None
|
||||
|
||||
|
||||
class Keyword:
|
||||
def __init__(self, contents):
|
||||
self.contents = contents[0]
|
||||
|
||||
def __repr__(self):
|
||||
return self.contents
|
||||
|
||||
|
||||
class Terminal:
|
||||
def __init__(self, contents):
|
||||
self.contents = contents[0]
|
||||
s = self.contents
|
||||
self.is_keyword = len(s) >= 4 and s[0 :: len(s) - 1] == '""' and all(c in alphanums + "_" for c in s[1:-1])
|
||||
|
||||
def __repr__(self):
|
||||
ty = "CaselessKeyword" if self.is_keyword else "CaselessLiteral"
|
||||
return "%s(%s)" % (ty, self.contents)
|
||||
|
||||
|
||||
LPAREN = Suppress("(")
|
||||
RPAREN = Suppress(")")
|
||||
LBRACK = Suppress("[")
|
||||
RBRACK = Suppress("]")
|
||||
LBRACE = Suppress("{")
|
||||
RBRACE = Suppress("}")
|
||||
EQUALS = Suppress("=")
|
||||
VBAR = Suppress("|")
|
||||
PERIOD = Suppress(".")
|
||||
HASH = Suppress("#")
|
||||
|
||||
identifier = Word(alphanums + "_")
|
||||
keyword = Word(alphanums + "_").setParseAction(Keyword)
|
||||
expression = Forward()
|
||||
optional = Group(LBRACK + expression + RBRACK).setParseAction(Optional)
|
||||
repeated = Group(LBRACE + expression + RBRACE).setParseAction(Repeated)
|
||||
terminal = quotedString.setParseAction(Terminal)
|
||||
term = (keyword | terminal | optional | repeated | (LPAREN + expression + RPAREN)).setParseAction(Term)
|
||||
concat = Group(term + OneOrMore(term)).setParseAction(Concat)
|
||||
factor = concat | term
|
||||
union = Group(factor + OneOrMore(VBAR + factor)).setParseAction(Union)
|
||||
rule = identifier + EQUALS + expression + PERIOD
|
||||
|
||||
expression << (union | factor)
|
||||
|
||||
grammar = OneOrMore(Group(rule))
|
||||
grammar.ignore(HASH + restOfLine)
|
||||
|
||||
express = grammar.parseFile(os.path.join(os.path.dirname(__file__), "express.bnf"))
|
||||
|
||||
|
||||
def find_bytype(expr, ty, li=None):
|
||||
if li is None:
|
||||
li = []
|
||||
if isinstance(expr, Term):
|
||||
expr = expr.contents
|
||||
if isinstance(expr, ty):
|
||||
li.append(expr)
|
||||
return set(li)
|
||||
elif isinstance(expr, Expression):
|
||||
for term in expr:
|
||||
find_bytype(term, ty, li)
|
||||
return set(li)
|
||||
|
||||
|
||||
actions = {
|
||||
"type_decl": "TypeDeclaration",
|
||||
"entity_decl": "EntityDeclaration",
|
||||
"enumeration_type": "EnumerationType",
|
||||
"aggregation_types": "AggregationType",
|
||||
"general_aggregation_types": "AggregationType",
|
||||
"select_type": "SelectType",
|
||||
"binary_type": "BinaryType",
|
||||
"subtype_declaration": "SubTypeExpression",
|
||||
"supertype_constraint": "SuperTypeExpression",
|
||||
"derive_clause": "AttributeList",
|
||||
"inverse_clause": "AttributeList",
|
||||
"inverse_attr": "InverseAttribute",
|
||||
"bound_spec": "BoundSpecification",
|
||||
"explicit_attr": "ExplicitAttribute",
|
||||
"width_spec": "WidthSpec",
|
||||
"string_type": "StringType",
|
||||
"named_types": "NamedType",
|
||||
"simple_types": "SimpleType",
|
||||
"function_decl": "FunctionDeclaration",
|
||||
"rule_decl": "RuleDeclaration",
|
||||
}
|
||||
|
||||
to_emit = set(id for id, expr in express)
|
||||
emitted = set()
|
||||
to_combine = set(["simple_id"])
|
||||
statements = []
|
||||
|
||||
terminals = reduce(lambda x, y: x | y, (find_bytype(e, Terminal) for id, e in express))
|
||||
keywords = list(filter(operator.attrgetter("is_keyword"), terminals))
|
||||
negated_keywords = map(lambda s: "~%s" % s, keywords)
|
||||
no_action = {
|
||||
"letter",
|
||||
"digit",
|
||||
"digits",
|
||||
"real_literal",
|
||||
"integer_literal",
|
||||
"string_literal",
|
||||
"simple_string_literal",
|
||||
"letter",
|
||||
"not_quote",
|
||||
"not_paren_star_quote_special",
|
||||
}
|
||||
|
||||
while True:
|
||||
emitted_in_loop = set()
|
||||
for id, expr in express:
|
||||
kws = map(repr, find_bytype(expr, Keyword))
|
||||
found = [k in emitted for k in kws]
|
||||
if id in to_emit and all(found):
|
||||
emitted_in_loop.add(id)
|
||||
emitted.add(id)
|
||||
stmt = "(%s)" % expr
|
||||
if id in to_combine:
|
||||
stmt = " + ".join(itertools.chain(negated_keywords, ("originalTextFor(Combine%s)" % stmt,)))
|
||||
if id not in no_action and not isinstance(expr.contents, Keyword) and not id in to_combine:
|
||||
node_type = "ListNode" if "ZeroOrMore" in stmt else "Node"
|
||||
action = actions.get(id, 'lambda s, loc, t: %s(s, loc, t, rule="%s")' % (node_type, id))
|
||||
stmt = "%s.setParseAction(%s)" % (stmt, action)
|
||||
statements.append('%s = %s("%s")' % (id, stmt, id))
|
||||
to_emit -= emitted_in_loop
|
||||
if not emitted_in_loop:
|
||||
break
|
||||
|
||||
for id in to_emit:
|
||||
statements.append('%s = Forward()("%s")' % (id, id))
|
||||
|
||||
for id in to_emit:
|
||||
expr = [e for k, e in express if k == id][0]
|
||||
stmt = "(%s)" % expr
|
||||
if id in to_combine:
|
||||
stmt = "Suppress%s" % stmt
|
||||
if id not in no_action and not isinstance(expr.contents, Keyword):
|
||||
children = list(
|
||||
map(operator.attrgetter("contents"), reduce(lambda x, y: x | y, (find_bytype(e, Keyword) for e in [expr])))
|
||||
)
|
||||
has_duplicates = len(children) > len(set(children))
|
||||
node_type = "ListNode" if ("ZeroOrMore" in stmt or has_duplicates) else "Node"
|
||||
action = ".setParseAction(%s)" % (
|
||||
actions[id] if id in actions else 'lambda s, loc, t: %s(s, loc, t, rule="%s")' % (node_type, id)
|
||||
)
|
||||
stmt = "(%s)%s" % (stmt, action)
|
||||
statements.append("%s << %s" % (id, stmt))
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(r"""
|
||||
# This file is generated by IfcOpenShell ifcexpressparser bootstrap.py
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
import pickle
|
||||
|
||||
import schema
|
||||
import mapping
|
||||
|
||||
from pyparsing import *
|
||||
from nodes import *
|
||||
|
||||
def parse(fn: str) -> mapping.Mapping:
|
||||
cache_file = fn + ".cache.dat"
|
||||
if os.path.exists(cache_file) and os.path.getmtime(cache_file) >= os.path.getmtime(fn):
|
||||
with open(cache_file, "rb") as f:
|
||||
m = pickle.load(f)
|
||||
else:
|
||||
%s
|
||||
|
||||
syntax.ignore("--" + restOfLine)
|
||||
syntax.ignore(Regex(r"\((?:\*(?:[^*]*\*+)+?\))"))
|
||||
ast = syntax.parseFile(fn)
|
||||
s = schema.Schema(ast)
|
||||
m = mapping.Mapping(s)
|
||||
|
||||
with open(cache_file, "wb") as f:
|
||||
pickle.dump(m, f, protocol=0)
|
||||
return m
|
||||
|
||||
if __name__ == "__main__":
|
||||
m = parse(sys.argv[1])
|
||||
import importlib
|
||||
for output in sys.argv[2:]:
|
||||
mdl = importlib.import_module(output)
|
||||
mdl.Generator(m).emit()
|
||||
sys.stdout.write(m.schema.name)
|
||||
""" % ("\n ".join(statements)))
|
||||
@@ -0,0 +1,16 @@
|
||||
import sys, fileinput
|
||||
|
||||
if sys.platform == "win32" and not hasattr(sys.stdout, "buffer"):
|
||||
import os, msvcrt
|
||||
|
||||
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
||||
|
||||
files = sys.argv[1:]
|
||||
if files[0] == "-o":
|
||||
b = open(files[1], "wb")
|
||||
files = files[2:]
|
||||
else:
|
||||
b = getattr(sys.stdout, "buffer", sys.stdout)
|
||||
|
||||
for line in fileinput.input(files=files, mode="rb"):
|
||||
b.write(line)
|
||||
@@ -0,0 +1,50 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import itertools
|
||||
import functools
|
||||
|
||||
|
||||
def indent(n, s):
|
||||
if isinstance(s, str):
|
||||
strs = [s]
|
||||
else:
|
||||
strs = s
|
||||
splitted = itertools.chain.from_iterable(map(functools.partial(str.split, sep="\n"), map(str, strs)))
|
||||
return "\n".join(" " * n + l for l in splitted)
|
||||
|
||||
|
||||
class Base:
|
||||
"""
|
||||
A base class for all code generation classes. Currently only working around
|
||||
some python 2/3 incompatibilities in terms of unicode file handling.
|
||||
"""
|
||||
|
||||
def emit(self):
|
||||
import platform
|
||||
|
||||
if tuple(map(int, platform.python_version_tuple())) < (2, 8):
|
||||
from io import open as unicode_open
|
||||
|
||||
unicode_type = unicode
|
||||
else:
|
||||
unicode_open = open
|
||||
unicode_type = lambda x, *args, **kwargs: x
|
||||
f = unicode_open(self.file_name, "w", encoding="utf-8")
|
||||
f.write(unicode_type(repr(self), encoding="utf-8", errors="ignore"))
|
||||
f.close()
|
||||
@@ -0,0 +1,70 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import operator
|
||||
|
||||
import nodes
|
||||
import codegen
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class Definitions(codegen.Base):
|
||||
def __init__(self, mapping):
|
||||
|
||||
schema_name = mapping.schema.name
|
||||
self.schema_name = schema_name_title = schema_name.capitalize()
|
||||
|
||||
statements = [""]
|
||||
|
||||
def write_entity(schema_name, name, type):
|
||||
|
||||
attribute_names = list(map(lambda t: (t.name, t.optional), type.attributes))
|
||||
for attr, is_optional in attribute_names:
|
||||
statements.append("#define SCHEMA_%(name)s_HAS_%(attr)s" % locals())
|
||||
if is_optional:
|
||||
statements.append("#define SCHEMA_%(name)s_%(attr)s_IS_OPTIONAL" % locals())
|
||||
inverse_attribute_names = list(map(operator.attrgetter("name"), type.inverse))
|
||||
for attr in inverse_attribute_names:
|
||||
statements.append("#define SCHEMA_%(name)s_HAS_%(attr)s" % locals())
|
||||
|
||||
def write(name):
|
||||
statements.append("#define SCHEMA_HAS_%(name)s" % locals())
|
||||
fn = None
|
||||
if mapping.schema.is_entity(name):
|
||||
fn = write_entity
|
||||
|
||||
if fn is not None:
|
||||
decl = mapping.schema[name]
|
||||
if isinstance(decl, nodes.TypeDeclaration):
|
||||
decl = decl.type.type
|
||||
fn(schema_name, name, decl) is not False
|
||||
|
||||
for name in mapping.schema:
|
||||
write(name)
|
||||
|
||||
self.str = "\n".join(statements) + "\n"
|
||||
|
||||
self.file_name = "%s-definitions.h" % self.schema_name
|
||||
|
||||
def __repr__(self):
|
||||
return self.str
|
||||
|
||||
|
||||
Generator = Definitions
|
||||
@@ -0,0 +1,88 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
###############################################################################
|
||||
# #
|
||||
# This files uses the documentation files from buildingSMART to generate #
|
||||
# descriptions from EXPRESS names that are suitable for comments in the C++ #
|
||||
# code. The .csv files used by this file are generated from the MS Office #
|
||||
# Access database, which in turn has been generated from the IFC baseline #
|
||||
# documentation by the IFCDOC utility provided by buildingSMART. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import re
|
||||
import os
|
||||
import csv
|
||||
|
||||
from schema import OrderedCaseInsensitiveDict
|
||||
|
||||
try:
|
||||
from html.entities import entitydefs
|
||||
except:
|
||||
from htmlentitydefs import entitydefs
|
||||
|
||||
make_absolute = lambda fn: os.path.join(os.path.dirname(os.path.realpath(__file__)), fn)
|
||||
|
||||
name_to_oid = OrderedCaseInsensitiveDict()
|
||||
oid_to_desc = {}
|
||||
oid_to_name = {}
|
||||
oid_to_pid = {}
|
||||
regices = list(
|
||||
zip(
|
||||
[re.compile(s, re.M) for s in [r'<[\w\n=" \-/\.;_\t:%#,\?\(\)]+>', r"(\n[\t ]*){2,}", r"^[\t ]+"]],
|
||||
["", "\n\n", " "],
|
||||
)
|
||||
)
|
||||
|
||||
definition_files = ["DocEntity.csv", "DocEnumeration.csv", "DocDefined.csv", "DocSelect.csv"]
|
||||
definition_files = map(make_absolute, definition_files)
|
||||
for fn in definition_files:
|
||||
with open(fn, encoding="utf8", errors="ignore") as f:
|
||||
for oid, name, desc in csv.reader(f, delimiter=";", quotechar='"'):
|
||||
name_to_oid[name] = oid
|
||||
oid_to_name[oid] = name
|
||||
oid_to_desc[oid] = desc
|
||||
|
||||
with open(make_absolute("DocEntityAttributes.csv")) as f:
|
||||
for pid, x, oid in csv.reader(f, delimiter=";", quotechar='"'):
|
||||
oid_to_pid[oid] = pid
|
||||
|
||||
with open(make_absolute("DocAttribute.csv")) as f:
|
||||
for oid, name, desc in csv.reader(f, delimiter=";", quotechar='"'):
|
||||
pid = oid_to_pid[oid]
|
||||
pname = oid_to_name[pid]
|
||||
name_to_oid[".".join((pname, name))] = oid
|
||||
oid_to_desc[oid] = desc
|
||||
|
||||
|
||||
def description(item):
|
||||
global name_to_oid, oid_to_desc, oid_to_name, oid_to_pid
|
||||
oid = name_to_oid.get(item, 0)
|
||||
desc = oid_to_desc.get(oid, None)
|
||||
if desc:
|
||||
for a, b in entitydefs.items():
|
||||
desc = desc.replace("&%s;" % a, b)
|
||||
desc = desc.replace("\r", "")
|
||||
for r, s in regices:
|
||||
desc = r.sub(s, desc)
|
||||
desc = desc.strip()
|
||||
return desc.split("\n")
|
||||
else:
|
||||
return []
|
||||
@@ -0,0 +1,342 @@
|
||||
ABS = "abs" .
|
||||
ABSTRACT = "abstract" .
|
||||
ACOS = "acos" .
|
||||
AGGREGATE = "aggregate" .
|
||||
ALIAS = "alias" .
|
||||
AND = "and" .
|
||||
ANDOR = "andor" .
|
||||
ARRAY = "array" .
|
||||
AS = "as" .
|
||||
ASIN = "asin" .
|
||||
ATAN = "atan" .
|
||||
BAG = "bag" .
|
||||
BASED_ON = "based_on" .
|
||||
BEGIN = "begin" .
|
||||
BINARY = "binary" .
|
||||
BLENGTH = "blength" .
|
||||
BOOLEAN = "boolean" .
|
||||
BY = "by" .
|
||||
CASE = "case" .
|
||||
CONSTANT = "constant" .
|
||||
CONST_E = "const_e" .
|
||||
COS = "cos" .
|
||||
DERIVE = "derive" .
|
||||
DIV = "div" .
|
||||
ELSE = "else" .
|
||||
END = "end" .
|
||||
END_ALIAS = "end_alias" .
|
||||
END_CASE = "end_case" .
|
||||
END_CONSTANT = "end_constant" .
|
||||
END_ENTITY = "end_entity" .
|
||||
END_FUNCTION = "end_function" .
|
||||
END_IF = "end_if" .
|
||||
END_LOCAL = "end_local" .
|
||||
END_PROCEDURE = "end_procedure" .
|
||||
END_REPEAT = "end_repeat" .
|
||||
END_RULE = "end_rule" .
|
||||
END_SCHEMA = "end_schema" .
|
||||
END_SUBTYPE_CONSTRAINT = "end_subtype_constraint" .
|
||||
END_TYPE = "end_type" .
|
||||
ENTITY = "entity" .
|
||||
ENUMERATION = "enumeration" .
|
||||
ESCAPE = "escape" .
|
||||
EXISTS = "exists" .
|
||||
EXTENSIBLE = "extensible" .
|
||||
EXP = "exp" .
|
||||
FALSE = "false" .
|
||||
FIXED = "fixed" .
|
||||
FOR = "for" .
|
||||
FORMAT = "format" .
|
||||
FROM = "from" .
|
||||
FUNCTION = "function" .
|
||||
GENERIC = "generic" .
|
||||
GENERIC_ENTITY = "generic_entity" .
|
||||
HIBOUND = "hibound" .
|
||||
HIINDEX = "hiindex" .
|
||||
IF = "if" .
|
||||
IN = "in" .
|
||||
INSERT = "insert" .
|
||||
INTEGER = "integer" .
|
||||
INVERSE = "inverse" .
|
||||
LENGTH = "length" .
|
||||
LIKE = "like" .
|
||||
LIST = "list" .
|
||||
LOBOUND = "lobound" .
|
||||
LOCAL = "local" .
|
||||
LOG = "log" .
|
||||
LOG10 = "log10" .
|
||||
LOG2 = "log2" .
|
||||
LOGICAL = "logical" .
|
||||
LOINDEX = "loindex" .
|
||||
MOD = "mod" .
|
||||
NOT = "not" .
|
||||
NUMBER = "number" .
|
||||
NVL = "nvl" .
|
||||
ODD = "odd" .
|
||||
OF = "of" .
|
||||
ONEOF = "oneof" .
|
||||
OPTIONAL = "optional" .
|
||||
OR = "or" .
|
||||
OTHERWISE = "otherwise" .
|
||||
PI = "pi" .
|
||||
PROCEDURE = "procedure" .
|
||||
QUERY = "query" .
|
||||
REAL = "real" .
|
||||
REFERENCE = "reference" .
|
||||
REMOVE = "remove" .
|
||||
RENAMED = "renamed" .
|
||||
REPEAT = "repeat" .
|
||||
RETURN = "return" .
|
||||
ROLESOF = "rolesof" .
|
||||
RULE = "rule" .
|
||||
SCHEMA = "schema" .
|
||||
SELECT = "select" .
|
||||
SELF = "self" .
|
||||
SET = "set" .
|
||||
SIN = "sin" .
|
||||
SIZEOF = "sizeof" .
|
||||
SKIP = "skip" .
|
||||
SQRT = "sqrt" .
|
||||
STRING = "string" .
|
||||
SUBTYPE = "subtype" .
|
||||
SUBTYPE_CONSTRAINT = "subtype_constraint" .
|
||||
SUPERTYPE = "supertype" .
|
||||
TAN = "tan" .
|
||||
THEN = "then" .
|
||||
TO = "to" .
|
||||
TOTAL_OVER = "total_over" .
|
||||
TRUE = "true" .
|
||||
TYPE = "type" .
|
||||
TYPEOF = "typeof" .
|
||||
UNIQUE = "unique" .
|
||||
UNKNOWN = "unknown" .
|
||||
UNTIL = "until" .
|
||||
USE = "use" .
|
||||
USEDIN = "usedin" .
|
||||
VALUE = "value" .
|
||||
VALUE_IN = "value_in" .
|
||||
VALUE_UNIQUE = "value_unique" .
|
||||
VAR = "var" .
|
||||
WHERE = "where" .
|
||||
WHILE = "while" .
|
||||
WITH = "with" .
|
||||
XOR = "xor" .
|
||||
bit = "0" | "1" .
|
||||
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
|
||||
digits = digit { digit } .
|
||||
encoded_character = octet octet octet octet .
|
||||
hex_digit = digit | "a" | "b" | "c" | "d" | "e" | "f" .
|
||||
letter = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" .
|
||||
lparen_then_not_lparen_star = "(" { "(" } not_lparen_star { not_lparen_star } .
|
||||
not_lparen_star = not_paren_star | ")" .
|
||||
not_paren_star = letter | digit | not_paren_star_special .
|
||||
not_paren_star_quote_special = "!" | "#" | "$" | "%" | "&" | "+" | "," | "-" | "." | "/" | ":" | ";" | "<" | "=" | ">" | "?" | "@" | "[" | "\\" | "]" | "^" | "_" | "{" | "|" | "}" | "~" .
|
||||
not_paren_star_special = not_paren_star_quote_special | "\"\"" .
|
||||
not_quote = not_paren_star_quote_special | letter | digit | "(" | ")" | "*" .
|
||||
not_rparen_star = not_paren_star | "(" .
|
||||
octet = hex_digit hex_digit .
|
||||
special = not_paren_star_quote_special | "(" | ")" | "*" | "\"\"" .
|
||||
not_rparen_star_then_rparen = not_rparen_star { not_rparen_star } ")" { ")" } .
|
||||
binary_literal = "%" bit { bit } .
|
||||
encoded_string_literal = "\"" encoded_character { encoded_character } "\"" .
|
||||
integer_literal = digits .
|
||||
real_literal = ( digits "." [ digits ] [ "e" [ sign ] digits ] ) | integer_literal .
|
||||
simple_id = letter { letter | digit | "_" } .
|
||||
simple_string_literal = "'" { ( "'" "'" ) | not_quote } "'" .
|
||||
embedded_remark = "(*" [ remark_tag ] { ( not_paren_star { not_paren_star } ) | lparen_then_not_lparen_star | ( "*" { "*" } ) | not_rparen_star_then_rparen | embedded_remark } "*)" .
|
||||
remark = embedded_remark | tail_remark .
|
||||
remark_tag = "\"" remark_ref { "." remark_ref } "\"" .
|
||||
remark_ref = attribute_ref | constant_ref | entity_ref | enumeration_ref | function_ref | parameter_ref | procedure_ref | rule_label_ref | rule_ref | schema_ref | subtype_constraint_ref | type_label_ref | type_ref | variable_ref .
|
||||
tail_remark = "--" [ remark_tag ] .
|
||||
attribute_ref = attribute_id .
|
||||
constant_ref = constant_id .
|
||||
entity_ref = entity_id .
|
||||
enumeration_ref = enumeration_id .
|
||||
function_ref = function_id .
|
||||
parameter_ref = parameter_id .
|
||||
procedure_ref = procedure_id .
|
||||
rule_label_ref = rule_label_id .
|
||||
rule_ref = rule_id .
|
||||
schema_ref = schema_id .
|
||||
subtype_constraint_ref = subtype_constraint_id .
|
||||
type_label_ref = type_label_id .
|
||||
type_ref = type_id .
|
||||
variable_ref = variable_id .
|
||||
abstract_entity_declaration = ABSTRACT .
|
||||
abstract_supertype = ABSTRACT SUPERTYPE ";" .
|
||||
abstract_supertype_declaration = ABSTRACT SUPERTYPE [ subtype_constraint ] .
|
||||
actual_parameter_list = "(" [ parameter ] { "," parameter } ")" .
|
||||
add_like_op = "+" | "-" | OR | XOR .
|
||||
aggregate_initializer = "[" [ element { "," element } ] "]" .
|
||||
aggregate_source = simple_expression .
|
||||
aggregate_type = AGGREGATE [ ":" type_label ] OF parameter_type .
|
||||
aggregation_types = array_type | bag_type | list_type | set_type .
|
||||
algorithm_head = { declaration } [ constant_decl ] [ local_decl ] .
|
||||
alias_stmt = ALIAS variable_id FOR general_ref { qualifier } ";" stmt { stmt } END_ALIAS ";" .
|
||||
array_type = ARRAY bound_spec OF [ OPTIONAL ] [ UNIQUE ] instantiable_type .
|
||||
assignment_stmt = general_ref { qualifier } ":=" expression ";" .
|
||||
attribute_decl = redeclared_attribute | attribute_id .
|
||||
attribute_id = simple_id .
|
||||
attribute_qualifier = "." attribute_ref .
|
||||
bag_type = BAG [ bound_spec ] OF instantiable_type .
|
||||
binary_type = BINARY [ width_spec ] .
|
||||
boolean_type = BOOLEAN .
|
||||
bound_1 = numeric_expression .
|
||||
bound_2 = numeric_expression .
|
||||
bound_spec = "[" bound_1 ":" bound_2 "]" .
|
||||
built_in_constant = CONST_E | PI | SELF | "?" .
|
||||
built_in_function = ABS | ACOS | ASIN | ATAN | BLENGTH | COS | EXISTS | EXP | FORMAT | HIBOUND | HIINDEX | LENGTH | LOBOUND | LOINDEX | LOG | LOG2 | LOG10 | NVL | ODD | ROLESOF | SIN | SIZEOF | SQRT | TAN | TYPEOF | USEDIN | VALUE | VALUE_IN | VALUE_UNIQUE .
|
||||
built_in_procedure = INSERT | REMOVE .
|
||||
case_action = case_label { "," case_label } ":" stmt .
|
||||
case_label = expression .
|
||||
case_stmt = CASE selector OF { case_action } [ OTHERWISE ":" stmt ] END_CASE ";" .
|
||||
compound_stmt = BEGIN stmt { stmt } END ";" .
|
||||
concrete_types = aggregation_types | simple_types | type_ref .
|
||||
constant_body = constant_id ":" instantiable_type ":=" expression ";" .
|
||||
constant_decl = CONSTANT constant_body { constant_body } END_CONSTANT ";" .
|
||||
constant_factor = built_in_constant | constant_ref .
|
||||
constant_id = simple_id .
|
||||
constructed_types = enumeration_type | select_type .
|
||||
declaration = entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl .
|
||||
derived_attr = attribute_decl ":" parameter_type ":=" expression ";" .
|
||||
derive_clause = DERIVE derived_attr { derived_attr } .
|
||||
domain_rule = [ rule_label_id ":" ] expression .
|
||||
element = expression [ ":" repetition ] .
|
||||
entity_body = { explicit_attr } [ derive_clause ] [ inverse_clause ] [ unique_clause ] [ where_clause ] .
|
||||
entity_constructor = entity_ref "(" [ expression { "," expression } ] ")" .
|
||||
entity_decl = entity_head entity_body END_ENTITY ";" .
|
||||
entity_head = ENTITY entity_id subsuper ";" .
|
||||
entity_id = simple_id .
|
||||
enumeration_extension = BASED_ON type_ref [ WITH enumeration_items ] .
|
||||
enumeration_id = simple_id .
|
||||
enumeration_items = "(" enumeration_id { "," enumeration_id } ")" .
|
||||
enumeration_reference = [ type_ref "." ] enumeration_ref .
|
||||
enumeration_type = [ EXTENSIBLE ] ENUMERATION [ ( OF enumeration_items ) | enumeration_extension ] .
|
||||
escape_stmt = ESCAPE ";" .
|
||||
explicit_attr = attribute_decl { "," attribute_decl } ":" [ OPTIONAL ] parameter_type ";" .
|
||||
expression = simple_expression [ rel_op_extended simple_expression ] .
|
||||
factor = simple_factor [ "**" simple_factor ] .
|
||||
formal_parameter = parameter_id { "," parameter_id } ":" parameter_type .
|
||||
function_call = ( built_in_function | function_ref ) actual_parameter_list .
|
||||
function_decl = function_head algorithm_head stmt { stmt } END_FUNCTION ";" .
|
||||
function_head = FUNCTION function_id [ "(" formal_parameter { ";" formal_parameter } ")" ] ":" parameter_type ";" .
|
||||
function_id = simple_id .
|
||||
generalized_types = aggregate_type | general_aggregation_types | generic_entity_type | generic_type .
|
||||
general_aggregation_types = general_array_type | general_bag_type | general_list_type | general_set_type .
|
||||
general_array_type = ARRAY [ bound_spec ] OF [ OPTIONAL ] [ UNIQUE ] parameter_type .
|
||||
general_bag_type = BAG [ bound_spec ] OF parameter_type .
|
||||
general_list_type = LIST [ bound_spec ] OF [ UNIQUE ] parameter_type .
|
||||
general_ref = parameter_ref | variable_ref .
|
||||
general_set_type = SET [ bound_spec ] OF parameter_type .
|
||||
generic_entity_type = GENERIC_ENTITY [ ":" type_label ] .
|
||||
generic_type = GENERIC [ ":" type_label ] .
|
||||
group_qualifier = "\\" entity_ref .
|
||||
if_stmt = IF logical_expression THEN stmt { stmt } [ ELSE stmt { stmt } ] END_IF ";" .
|
||||
increment = numeric_expression .
|
||||
increment_control = variable_id ":=" bound_1 TO bound_2 [ BY increment ] .
|
||||
index = numeric_expression .
|
||||
index_1 = index .
|
||||
index_2 = index .
|
||||
index_qualifier = "[" index_1 [ ":" index_2 ] "]" .
|
||||
instantiable_type = concrete_types | entity_ref .
|
||||
integer_type = INTEGER .
|
||||
interface_specification = reference_clause | use_clause .
|
||||
interval = "{" interval_low interval_op interval_item interval_op interval_high "}" .
|
||||
interval_high = simple_expression .
|
||||
interval_item = simple_expression .
|
||||
interval_low = simple_expression .
|
||||
interval_op = "<=" | "<" .
|
||||
inverse_attr = attribute_decl ":" [ ( SET | BAG ) [ bound_spec ] OF ] entity_ref FOR [ entity_ref "." ] attribute_ref ";" .
|
||||
inverse_clause = INVERSE inverse_attr { inverse_attr } .
|
||||
list_type = LIST [ bound_spec ] OF [ UNIQUE ] instantiable_type .
|
||||
literal = binary_literal | logical_literal | real_literal | string_literal .
|
||||
local_decl = LOCAL local_variable { local_variable } END_LOCAL ";" .
|
||||
local_variable = variable_id { "," variable_id } ":" parameter_type [ ":=" expression ] ";" .
|
||||
logical_expression = expression .
|
||||
logical_literal = FALSE | TRUE | UNKNOWN .
|
||||
logical_type = LOGICAL .
|
||||
multiplication_like_op = "*" | "/" | DIV | MOD | AND | "||" .
|
||||
named_types = entity_ref | type_ref .
|
||||
named_type_or_rename = named_types [ AS ( entity_id | type_id ) ] .
|
||||
null_stmt = ";" .
|
||||
number_type = NUMBER .
|
||||
numeric_expression = simple_expression .
|
||||
one_of = ONEOF "(" supertype_expression { "," supertype_expression } ")" .
|
||||
parameter = expression .
|
||||
parameter_id = simple_id .
|
||||
parameter_type = generalized_types | simple_types | named_types .
|
||||
population = entity_ref .
|
||||
precision_spec = numeric_expression .
|
||||
primary = literal | ( qualifiable_factor { qualifier } ) .
|
||||
procedure_call_stmt = ( built_in_procedure | procedure_ref ) actual_parameter_list ";" .
|
||||
procedure_decl = procedure_head algorithm_head { stmt } END_PROCEDURE ";" .
|
||||
procedure_head = PROCEDURE procedure_id [ "(" [ VAR ] formal_parameter { ";" [ VAR ] formal_parameter } ")" ] ";" .
|
||||
procedure_id = simple_id .
|
||||
qualifiable_factor = function_call | attribute_ref | constant_factor | general_ref | population .
|
||||
qualified_attribute = SELF group_qualifier attribute_qualifier .
|
||||
qualifier = attribute_qualifier | group_qualifier | index_qualifier .
|
||||
query_expression = QUERY "(" variable_id "<*" aggregate_source "|" logical_expression ")" .
|
||||
real_type = REAL [ "(" precision_spec ")" ] .
|
||||
redeclared_attribute = qualified_attribute [ RENAMED attribute_id ] .
|
||||
referenced_attribute = attribute_ref | qualified_attribute .
|
||||
reference_clause = REFERENCE FROM schema_ref [ "(" resource_or_rename { "," resource_or_rename } ")" ] ";" .
|
||||
rel_op = "<=" | ">=" | "<>" | "=" | ":<>:" | ":=:" | "<" | ">" .
|
||||
rel_op_extended = rel_op | IN | LIKE .
|
||||
rename_id = constant_id | entity_id | function_id | procedure_id | type_id .
|
||||
repeat_control = [ increment_control ] [ while_control ] [ until_control ] .
|
||||
repeat_stmt = REPEAT repeat_control ";" stmt { stmt } END_REPEAT ";" .
|
||||
repetition = numeric_expression .
|
||||
resource_or_rename = resource_ref [ AS rename_id ] .
|
||||
resource_ref = constant_ref | entity_ref | function_ref | procedure_ref | type_ref .
|
||||
return_stmt = RETURN [ "(" expression ")" ] ";" .
|
||||
rule_decl = rule_head algorithm_head { stmt } where_clause END_RULE ";" .
|
||||
rule_head = RULE rule_id FOR "(" entity_ref { "," entity_ref } ")" ";" .
|
||||
rule_id = simple_id .
|
||||
rule_label_id = simple_id .
|
||||
schema_body = { interface_specification } [ constant_decl ] { declaration | rule_decl } .
|
||||
schema_decl = SCHEMA schema_id [ schema_version_id ] ";" schema_body END_SCHEMA ";" .
|
||||
schema_id = simple_id .
|
||||
schema_version_id = string_literal .
|
||||
selector = expression .
|
||||
select_extension = BASED_ON type_ref [ WITH select_list ] .
|
||||
select_list = "(" named_types { "," named_types } ")" .
|
||||
select_type = [ EXTENSIBLE [ GENERIC_ENTITY ] ] SELECT [ select_list | select_extension ] .
|
||||
set_type = SET [ bound_spec ] OF instantiable_type .
|
||||
sign = "+" | "-" .
|
||||
simple_expression = term { add_like_op term } .
|
||||
simple_factor = aggregate_initializer | interval | query_expression | ( [ unary_op ] ( "(" expression ")" | primary ) ) | entity_constructor | enumeration_reference .
|
||||
simple_types = binary_type | boolean_type | integer_type | logical_type | number_type | real_type | string_type .
|
||||
skip_stmt = SKIP ";" .
|
||||
stmt = alias_stmt | assignment_stmt | case_stmt | compound_stmt | escape_stmt | if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt | skip_stmt .
|
||||
string_literal = simple_string_literal | encoded_string_literal .
|
||||
string_type = STRING [ width_spec ] .
|
||||
subsuper = [ supertype_constraint ] [ subtype_declaration ] .
|
||||
subtype_constraint = OF "(" supertype_expression ")" .
|
||||
subtype_constraint_body = [ abstract_supertype ] [ total_over ] [ supertype_expression ";" ] .
|
||||
subtype_constraint_decl = subtype_constraint_head subtype_constraint_body END_SUBTYPE_CONSTRAINT ";" .
|
||||
subtype_constraint_head = SUBTYPE_CONSTRAINT subtype_constraint_id FOR entity_ref ";" .
|
||||
subtype_constraint_id = simple_id .
|
||||
subtype_declaration = SUBTYPE OF "(" entity_ref { "," entity_ref } ")" .
|
||||
supertype_constraint = abstract_supertype_declaration | abstract_entity_declaration | supertype_rule .
|
||||
supertype_expression = supertype_factor { ANDOR supertype_factor } .
|
||||
supertype_factor = supertype_term { AND supertype_term } .
|
||||
supertype_rule = SUPERTYPE subtype_constraint .
|
||||
supertype_term = one_of | "(" supertype_expression ")" | entity_ref .
|
||||
syntax = schema_decl { schema_decl } .
|
||||
term = factor { multiplication_like_op factor } .
|
||||
total_over = TOTAL_OVER "(" entity_ref { "," entity_ref } ")" ";" .
|
||||
type_decl = TYPE type_id "=" underlying_type ";" [ where_clause ] END_TYPE ";" .
|
||||
type_id = simple_id .
|
||||
type_label = type_label_id | type_label_ref .
|
||||
type_label_id = simple_id .
|
||||
unary_op = "+" | "-" | NOT .
|
||||
underlying_type = constructed_types | concrete_types .
|
||||
unique_clause = UNIQUE unique_rule ";" { unique_rule ";" } .
|
||||
unique_rule = [ rule_label_id ":" ] referenced_attribute { "," referenced_attribute } .
|
||||
until_control = UNTIL logical_expression .
|
||||
use_clause = USE FROM schema_ref [ "(" named_type_or_rename { "," named_type_or_rename } ")" ] ";" .
|
||||
variable_id = simple_id .
|
||||
where_clause = WHERE domain_rule ";" { domain_rule ";" } .
|
||||
while_control = WHILE logical_expression .
|
||||
width = numeric_expression .
|
||||
width_spec = "(" width ")" [ FIXED ] .
|
||||
@@ -0,0 +1,490 @@
|
||||
|
||||
# This file is generated by IfcOpenShell ifcexpressparser bootstrap.py
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
import pickle
|
||||
|
||||
import schema
|
||||
import mapping
|
||||
|
||||
from pyparsing import *
|
||||
from nodes import *
|
||||
|
||||
def parse(fn: str) -> mapping.Mapping:
|
||||
cache_file = fn + ".cache.dat"
|
||||
if os.path.exists(cache_file) and os.path.getmtime(cache_file) >= os.path.getmtime(fn):
|
||||
with open(cache_file, "rb") as f:
|
||||
m = pickle.load(f)
|
||||
else:
|
||||
ABS = (CaselessKeyword("abs")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ABS"))("ABS")
|
||||
ABSTRACT = (CaselessKeyword("abstract")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ABSTRACT"))("ABSTRACT")
|
||||
ACOS = (CaselessKeyword("acos")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ACOS"))("ACOS")
|
||||
AGGREGATE = (CaselessKeyword("aggregate")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="AGGREGATE"))("AGGREGATE")
|
||||
ALIAS = (CaselessKeyword("alias")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ALIAS"))("ALIAS")
|
||||
AND = (CaselessKeyword("and")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="AND"))("AND")
|
||||
ANDOR = (CaselessKeyword("andor")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ANDOR"))("ANDOR")
|
||||
ARRAY = (CaselessKeyword("array")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ARRAY"))("ARRAY")
|
||||
AS = (CaselessKeyword("as")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="AS"))("AS")
|
||||
ASIN = (CaselessKeyword("asin")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ASIN"))("ASIN")
|
||||
ATAN = (CaselessKeyword("atan")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ATAN"))("ATAN")
|
||||
BAG = (CaselessKeyword("bag")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="BAG"))("BAG")
|
||||
BASED_ON = (CaselessKeyword("based_on")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="BASED_ON"))("BASED_ON")
|
||||
BEGIN = (CaselessKeyword("begin")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="BEGIN"))("BEGIN")
|
||||
BINARY = (CaselessKeyword("binary")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="BINARY"))("BINARY")
|
||||
BLENGTH = (CaselessKeyword("blength")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="BLENGTH"))("BLENGTH")
|
||||
BOOLEAN = (CaselessKeyword("boolean")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="BOOLEAN"))("BOOLEAN")
|
||||
BY = (CaselessKeyword("by")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="BY"))("BY")
|
||||
CASE = (CaselessKeyword("case")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="CASE"))("CASE")
|
||||
CONSTANT = (CaselessKeyword("constant")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="CONSTANT"))("CONSTANT")
|
||||
CONST_E = (CaselessKeyword("const_e")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="CONST_E"))("CONST_E")
|
||||
COS = (CaselessKeyword("cos")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="COS"))("COS")
|
||||
DERIVE = (CaselessKeyword("derive")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="DERIVE"))("DERIVE")
|
||||
DIV = (CaselessKeyword("div")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="DIV"))("DIV")
|
||||
ELSE = (CaselessKeyword("else")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ELSE"))("ELSE")
|
||||
END = (CaselessKeyword("end")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END"))("END")
|
||||
END_ALIAS = (CaselessKeyword("end_alias")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_ALIAS"))("END_ALIAS")
|
||||
END_CASE = (CaselessKeyword("end_case")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_CASE"))("END_CASE")
|
||||
END_CONSTANT = (CaselessKeyword("end_constant")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_CONSTANT"))("END_CONSTANT")
|
||||
END_ENTITY = (CaselessKeyword("end_entity")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_ENTITY"))("END_ENTITY")
|
||||
END_FUNCTION = (CaselessKeyword("end_function")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_FUNCTION"))("END_FUNCTION")
|
||||
END_IF = (CaselessKeyword("end_if")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_IF"))("END_IF")
|
||||
END_LOCAL = (CaselessKeyword("end_local")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_LOCAL"))("END_LOCAL")
|
||||
END_PROCEDURE = (CaselessKeyword("end_procedure")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_PROCEDURE"))("END_PROCEDURE")
|
||||
END_REPEAT = (CaselessKeyword("end_repeat")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_REPEAT"))("END_REPEAT")
|
||||
END_RULE = (CaselessKeyword("end_rule")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_RULE"))("END_RULE")
|
||||
END_SCHEMA = (CaselessKeyword("end_schema")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_SCHEMA"))("END_SCHEMA")
|
||||
END_SUBTYPE_CONSTRAINT = (CaselessKeyword("end_subtype_constraint")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_SUBTYPE_CONSTRAINT"))("END_SUBTYPE_CONSTRAINT")
|
||||
END_TYPE = (CaselessKeyword("end_type")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="END_TYPE"))("END_TYPE")
|
||||
ENTITY = (CaselessKeyword("entity")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ENTITY"))("ENTITY")
|
||||
ENUMERATION = (CaselessKeyword("enumeration")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ENUMERATION"))("ENUMERATION")
|
||||
ESCAPE = (CaselessKeyword("escape")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ESCAPE"))("ESCAPE")
|
||||
EXISTS = (CaselessKeyword("exists")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="EXISTS"))("EXISTS")
|
||||
EXTENSIBLE = (CaselessKeyword("extensible")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="EXTENSIBLE"))("EXTENSIBLE")
|
||||
EXP = (CaselessKeyword("exp")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="EXP"))("EXP")
|
||||
FALSE = (CaselessKeyword("false")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="FALSE"))("FALSE")
|
||||
FIXED = (CaselessKeyword("fixed")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="FIXED"))("FIXED")
|
||||
FOR = (CaselessKeyword("for")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="FOR"))("FOR")
|
||||
FORMAT = (CaselessKeyword("format")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="FORMAT"))("FORMAT")
|
||||
FROM = (CaselessKeyword("from")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="FROM"))("FROM")
|
||||
FUNCTION = (CaselessKeyword("function")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="FUNCTION"))("FUNCTION")
|
||||
GENERIC = (CaselessKeyword("generic")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="GENERIC"))("GENERIC")
|
||||
GENERIC_ENTITY = (CaselessKeyword("generic_entity")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="GENERIC_ENTITY"))("GENERIC_ENTITY")
|
||||
HIBOUND = (CaselessKeyword("hibound")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="HIBOUND"))("HIBOUND")
|
||||
HIINDEX = (CaselessKeyword("hiindex")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="HIINDEX"))("HIINDEX")
|
||||
IF = (CaselessKeyword("if")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="IF"))("IF")
|
||||
IN = (CaselessKeyword("in")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="IN"))("IN")
|
||||
INSERT = (CaselessKeyword("insert")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="INSERT"))("INSERT")
|
||||
INTEGER = (CaselessKeyword("integer")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="INTEGER"))("INTEGER")
|
||||
INVERSE = (CaselessKeyword("inverse")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="INVERSE"))("INVERSE")
|
||||
LENGTH = (CaselessKeyword("length")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LENGTH"))("LENGTH")
|
||||
LIKE = (CaselessKeyword("like")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LIKE"))("LIKE")
|
||||
LIST = (CaselessKeyword("list")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LIST"))("LIST")
|
||||
LOBOUND = (CaselessKeyword("lobound")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LOBOUND"))("LOBOUND")
|
||||
LOCAL = (CaselessKeyword("local")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LOCAL"))("LOCAL")
|
||||
LOG = (CaselessKeyword("log")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LOG"))("LOG")
|
||||
LOG10 = (CaselessKeyword("log10")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LOG10"))("LOG10")
|
||||
LOG2 = (CaselessKeyword("log2")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LOG2"))("LOG2")
|
||||
LOGICAL = (CaselessKeyword("logical")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LOGICAL"))("LOGICAL")
|
||||
LOINDEX = (CaselessKeyword("loindex")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="LOINDEX"))("LOINDEX")
|
||||
MOD = (CaselessKeyword("mod")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="MOD"))("MOD")
|
||||
NOT = (CaselessKeyword("not")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="NOT"))("NOT")
|
||||
NUMBER = (CaselessKeyword("number")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="NUMBER"))("NUMBER")
|
||||
NVL = (CaselessKeyword("nvl")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="NVL"))("NVL")
|
||||
ODD = (CaselessKeyword("odd")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ODD"))("ODD")
|
||||
OF = (CaselessKeyword("of")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="OF"))("OF")
|
||||
ONEOF = (CaselessKeyword("oneof")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ONEOF"))("ONEOF")
|
||||
OPTIONAL = (CaselessKeyword("optional")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="OPTIONAL"))("OPTIONAL")
|
||||
OR = (CaselessKeyword("or")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="OR"))("OR")
|
||||
OTHERWISE = (CaselessKeyword("otherwise")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="OTHERWISE"))("OTHERWISE")
|
||||
PI = (CaselessKeyword("pi")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="PI"))("PI")
|
||||
PROCEDURE = (CaselessKeyword("procedure")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="PROCEDURE"))("PROCEDURE")
|
||||
QUERY = (CaselessKeyword("query")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="QUERY"))("QUERY")
|
||||
REAL = (CaselessKeyword("real")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="REAL"))("REAL")
|
||||
REFERENCE = (CaselessKeyword("reference")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="REFERENCE"))("REFERENCE")
|
||||
REMOVE = (CaselessKeyword("remove")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="REMOVE"))("REMOVE")
|
||||
RENAMED = (CaselessKeyword("renamed")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="RENAMED"))("RENAMED")
|
||||
REPEAT = (CaselessKeyword("repeat")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="REPEAT"))("REPEAT")
|
||||
RETURN = (CaselessKeyword("return")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="RETURN"))("RETURN")
|
||||
ROLESOF = (CaselessKeyword("rolesof")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="ROLESOF"))("ROLESOF")
|
||||
RULE = (CaselessKeyword("rule")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="RULE"))("RULE")
|
||||
SCHEMA = (CaselessKeyword("schema")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SCHEMA"))("SCHEMA")
|
||||
SELECT = (CaselessKeyword("select")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SELECT"))("SELECT")
|
||||
SELF = (CaselessKeyword("self")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SELF"))("SELF")
|
||||
SET = (CaselessKeyword("set")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SET"))("SET")
|
||||
SIN = (CaselessKeyword("sin")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SIN"))("SIN")
|
||||
SIZEOF = (CaselessKeyword("sizeof")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SIZEOF"))("SIZEOF")
|
||||
SKIP = (CaselessKeyword("skip")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SKIP"))("SKIP")
|
||||
SQRT = (CaselessKeyword("sqrt")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SQRT"))("SQRT")
|
||||
STRING = (CaselessKeyword("string")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="STRING"))("STRING")
|
||||
SUBTYPE = (CaselessKeyword("subtype")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SUBTYPE"))("SUBTYPE")
|
||||
SUBTYPE_CONSTRAINT = (CaselessKeyword("subtype_constraint")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SUBTYPE_CONSTRAINT"))("SUBTYPE_CONSTRAINT")
|
||||
SUPERTYPE = (CaselessKeyword("supertype")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="SUPERTYPE"))("SUPERTYPE")
|
||||
TAN = (CaselessKeyword("tan")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="TAN"))("TAN")
|
||||
THEN = (CaselessKeyword("then")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="THEN"))("THEN")
|
||||
TO = (CaselessKeyword("to")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="TO"))("TO")
|
||||
TOTAL_OVER = (CaselessKeyword("total_over")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="TOTAL_OVER"))("TOTAL_OVER")
|
||||
TRUE = (CaselessKeyword("true")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="TRUE"))("TRUE")
|
||||
TYPE = (CaselessKeyword("type")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="TYPE"))("TYPE")
|
||||
TYPEOF = (CaselessKeyword("typeof")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="TYPEOF"))("TYPEOF")
|
||||
UNIQUE = (CaselessKeyword("unique")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="UNIQUE"))("UNIQUE")
|
||||
UNKNOWN = (CaselessKeyword("unknown")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="UNKNOWN"))("UNKNOWN")
|
||||
UNTIL = (CaselessKeyword("until")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="UNTIL"))("UNTIL")
|
||||
USE = (CaselessKeyword("use")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="USE"))("USE")
|
||||
USEDIN = (CaselessKeyword("usedin")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="USEDIN"))("USEDIN")
|
||||
VALUE = (CaselessKeyword("value")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="VALUE"))("VALUE")
|
||||
VALUE_IN = (CaselessKeyword("value_in")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="VALUE_IN"))("VALUE_IN")
|
||||
VALUE_UNIQUE = (CaselessKeyword("value_unique")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="VALUE_UNIQUE"))("VALUE_UNIQUE")
|
||||
VAR = (CaselessKeyword("var")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="VAR"))("VAR")
|
||||
WHERE = (CaselessKeyword("where")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="WHERE"))("WHERE")
|
||||
WHILE = (CaselessKeyword("while")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="WHILE"))("WHILE")
|
||||
WITH = (CaselessKeyword("with")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="WITH"))("WITH")
|
||||
XOR = (CaselessKeyword("xor")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="XOR"))("XOR")
|
||||
bit = ((CaselessLiteral("0") | CaselessLiteral("1"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="bit"))("bit")
|
||||
digit = ((CaselessLiteral("0") | CaselessLiteral("1") | CaselessLiteral("2") | CaselessLiteral("3") | CaselessLiteral("4") | CaselessLiteral("5") | CaselessLiteral("6") | CaselessLiteral("7") | CaselessLiteral("8") | CaselessLiteral("9")))("digit")
|
||||
digits = ((digit + ZeroOrMore(digit)))("digits")
|
||||
hex_digit = ((digit | CaselessLiteral("a") | CaselessLiteral("b") | CaselessLiteral("c") | CaselessLiteral("d") | CaselessLiteral("e") | CaselessLiteral("f"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="hex_digit"))("hex_digit")
|
||||
letter = ((CaselessLiteral("a") | CaselessLiteral("b") | CaselessLiteral("c") | CaselessLiteral("d") | CaselessLiteral("e") | CaselessLiteral("f") | CaselessLiteral("g") | CaselessLiteral("h") | CaselessLiteral("i") | CaselessLiteral("j") | CaselessLiteral("k") | CaselessLiteral("l") | CaselessLiteral("m") | CaselessLiteral("n") | CaselessLiteral("o") | CaselessLiteral("p") | CaselessLiteral("q") | CaselessLiteral("r") | CaselessLiteral("s") | CaselessLiteral("t") | CaselessLiteral("u") | CaselessLiteral("v") | CaselessLiteral("w") | CaselessLiteral("x") | CaselessLiteral("y") | CaselessLiteral("z")))("letter")
|
||||
not_paren_star_quote_special = ((CaselessLiteral("!") | CaselessLiteral("#") | CaselessLiteral("$") | CaselessLiteral("%") | CaselessLiteral("&") | CaselessLiteral("+") | CaselessLiteral(",") | CaselessLiteral("-") | CaselessLiteral(".") | CaselessLiteral("/") | CaselessLiteral(":") | CaselessLiteral(";") | CaselessLiteral("<") | CaselessLiteral("=") | CaselessLiteral(">") | CaselessLiteral("?") | CaselessLiteral("@") | CaselessLiteral("[") | CaselessLiteral("\\") | CaselessLiteral("]") | CaselessLiteral("^") | CaselessLiteral("_") | CaselessLiteral("{") | CaselessLiteral("|") | CaselessLiteral("}") | CaselessLiteral("~")))("not_paren_star_quote_special")
|
||||
not_paren_star_special = ((not_paren_star_quote_special | CaselessLiteral("\"\""))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="not_paren_star_special"))("not_paren_star_special")
|
||||
not_quote = ((not_paren_star_quote_special | letter | digit | CaselessLiteral("(") | CaselessLiteral(")") | CaselessLiteral("*")))("not_quote")
|
||||
octet = ((hex_digit + hex_digit)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="octet"))("octet")
|
||||
special = ((not_paren_star_quote_special | CaselessLiteral("(") | CaselessLiteral(")") | CaselessLiteral("*") | CaselessLiteral("\"\""))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="special"))("special")
|
||||
binary_literal = ((CaselessLiteral("%") + bit + ZeroOrMore(bit))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="binary_literal"))("binary_literal")
|
||||
integer_literal = (digits)("integer_literal")
|
||||
simple_id = ~CaselessKeyword("generic") + ~CaselessKeyword("value") + ~CaselessKeyword("case") + ~CaselessKeyword("for") + ~CaselessKeyword("sin") + ~CaselessKeyword("value_unique") + ~CaselessKeyword("extensible") + ~CaselessKeyword("tan") + ~CaselessKeyword("local") + ~CaselessKeyword("string") + ~CaselessKeyword("procedure") + ~CaselessKeyword("derive") + ~CaselessKeyword("end_if") + ~CaselessKeyword("supertype") + ~CaselessKeyword("entity") + ~CaselessKeyword("oneof") + ~CaselessKeyword("constant") + ~CaselessKeyword("end_case") + ~CaselessKeyword("end_alias") + ~CaselessKeyword("unknown") + ~CaselessKeyword("total_over") + ~CaselessKeyword("div") + ~CaselessKeyword("type") + ~CaselessKeyword("true") + ~CaselessKeyword("end_repeat") + ~CaselessKeyword("unique") + ~CaselessKeyword("end_rule") + ~CaselessKeyword("number") + ~CaselessKeyword("end_function") + ~CaselessKeyword("where") + ~CaselessKeyword("self") + ~CaselessKeyword("usedin") + ~CaselessKeyword("end_type") + ~CaselessKeyword("logical") + ~CaselessKeyword("generic_entity") + ~CaselessKeyword("end_schema") + ~CaselessKeyword("xor") + ~CaselessKeyword("until") + ~CaselessKeyword("to") + ~CaselessKeyword("in") + ~CaselessKeyword("inverse") + ~CaselessKeyword("enumeration") + ~CaselessKeyword("var") + ~CaselessKeyword("value_in") + ~CaselessKeyword("const_e") + ~CaselessKeyword("use") + ~CaselessKeyword("exists") + ~CaselessKeyword("exp") + ~CaselessKeyword("while") + ~CaselessKeyword("if") + ~CaselessKeyword("fixed") + ~CaselessKeyword("subtype") + ~CaselessKeyword("format") + ~CaselessKeyword("as") + ~CaselessKeyword("and") + ~CaselessKeyword("rule") + ~CaselessKeyword("function") + ~CaselessKeyword("lobound") + ~CaselessKeyword("length") + ~CaselessKeyword("hiindex") + ~CaselessKeyword("log2") + ~CaselessKeyword("reference") + ~CaselessKeyword("skip") + ~CaselessKeyword("with") + ~CaselessKeyword("integer") + ~CaselessKeyword("sqrt") + ~CaselessKeyword("insert") + ~CaselessKeyword("nvl") + ~CaselessKeyword("log") + ~CaselessKeyword("boolean") + ~CaselessKeyword("from") + ~CaselessKeyword("rolesof") + ~CaselessKeyword("hibound") + ~CaselessKeyword("abs") + ~CaselessKeyword("like") + ~CaselessKeyword("pi") + ~CaselessKeyword("alias") + ~CaselessKeyword("not") + ~CaselessKeyword("repeat") + ~CaselessKeyword("based_on") + ~CaselessKeyword("subtype_constraint") + ~CaselessKeyword("asin") + ~CaselessKeyword("optional") + ~CaselessKeyword("list") + ~CaselessKeyword("abstract") + ~CaselessKeyword("mod") + ~CaselessKeyword("false") + ~CaselessKeyword("log10") + ~CaselessKeyword("loindex") + ~CaselessKeyword("aggregate") + ~CaselessKeyword("end_constant") + ~CaselessKeyword("end") + ~CaselessKeyword("sizeof") + ~CaselessKeyword("remove") + ~CaselessKeyword("acos") + ~CaselessKeyword("set") + ~CaselessKeyword("renamed") + ~CaselessKeyword("end_local") + ~CaselessKeyword("of") + ~CaselessKeyword("escape") + ~CaselessKeyword("begin") + ~CaselessKeyword("select") + ~CaselessKeyword("end_procedure") + ~CaselessKeyword("else") + ~CaselessKeyword("end_subtype_constraint") + ~CaselessKeyword("cos") + ~CaselessKeyword("real") + ~CaselessKeyword("query") + ~CaselessKeyword("odd") + ~CaselessKeyword("andor") + ~CaselessKeyword("return") + ~CaselessKeyword("then") + ~CaselessKeyword("end_entity") + ~CaselessKeyword("array") + ~CaselessKeyword("blength") + ~CaselessKeyword("or") + ~CaselessKeyword("typeof") + ~CaselessKeyword("binary") + ~CaselessKeyword("atan") + ~CaselessKeyword("by") + ~CaselessKeyword("otherwise") + ~CaselessKeyword("bag") + ~CaselessKeyword("schema") + originalTextFor(Combine((letter + ZeroOrMore((letter | digit | CaselessLiteral("_"))))))("simple_id")
|
||||
simple_string_literal = ((CaselessLiteral("'") + ZeroOrMore(((CaselessLiteral("'") + CaselessLiteral("'")) | not_quote)) + CaselessLiteral("'")))("simple_string_literal")
|
||||
abstract_entity_declaration = (ABSTRACT)("abstract_entity_declaration")
|
||||
abstract_supertype = ((ABSTRACT + SUPERTYPE + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype"))("abstract_supertype")
|
||||
add_like_op = ((CaselessLiteral("+") | CaselessLiteral("-") | OR | XOR)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="add_like_op"))("add_like_op")
|
||||
attribute_id = (simple_id)("attribute_id")
|
||||
boolean_type = (BOOLEAN)("boolean_type")
|
||||
built_in_constant = ((CONST_E | PI | SELF | CaselessLiteral("?"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="built_in_constant"))("built_in_constant")
|
||||
built_in_function = ((ABS | ACOS | ASIN | ATAN | BLENGTH | COS | EXISTS | EXP | FORMAT | HIBOUND | HIINDEX | LENGTH | LOBOUND | LOINDEX | LOG | LOG2 | LOG10 | NVL | ODD | ROLESOF | SIN | SIZEOF | SQRT | TAN | TYPEOF | USEDIN | VALUE | VALUE_IN | VALUE_UNIQUE)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="built_in_function"))("built_in_function")
|
||||
built_in_procedure = ((INSERT | REMOVE)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="built_in_procedure"))("built_in_procedure")
|
||||
constant_id = (simple_id)("constant_id")
|
||||
entity_id = (simple_id)("entity_id")
|
||||
enumeration_id = (simple_id)("enumeration_id")
|
||||
enumeration_items = ((CaselessLiteral("(") + enumeration_id + ZeroOrMore((CaselessLiteral(",") + enumeration_id)) + CaselessLiteral(")"))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="enumeration_items"))("enumeration_items")
|
||||
escape_stmt = ((ESCAPE + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="escape_stmt"))("escape_stmt")
|
||||
function_id = (simple_id)("function_id")
|
||||
integer_type = (INTEGER)("integer_type")
|
||||
interval_op = ((CaselessLiteral("<=") | CaselessLiteral("<"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="interval_op"))("interval_op")
|
||||
logical_literal = ((FALSE | TRUE | UNKNOWN)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="logical_literal"))("logical_literal")
|
||||
logical_type = (LOGICAL)("logical_type")
|
||||
multiplication_like_op = ((CaselessLiteral("*") | CaselessLiteral("/") | DIV | MOD | AND | CaselessLiteral("||"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="multiplication_like_op"))("multiplication_like_op")
|
||||
null_stmt = (CaselessLiteral(";")).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="null_stmt"))("null_stmt")
|
||||
number_type = (NUMBER)("number_type")
|
||||
parameter_id = (simple_id)("parameter_id")
|
||||
procedure_id = (simple_id)("procedure_id")
|
||||
rel_op = ((CaselessLiteral("<=") | CaselessLiteral(">=") | CaselessLiteral("<>") | CaselessLiteral("=") | CaselessLiteral(":<>:") | CaselessLiteral(":=:") | CaselessLiteral("<") | CaselessLiteral(">"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="rel_op"))("rel_op")
|
||||
rel_op_extended = ((rel_op | IN | LIKE)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="rel_op_extended"))("rel_op_extended")
|
||||
rule_id = (simple_id)("rule_id")
|
||||
rule_label_id = (simple_id)("rule_label_id")
|
||||
schema_id = (simple_id)("schema_id")
|
||||
sign = ((CaselessLiteral("+") | CaselessLiteral("-"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="sign"))("sign")
|
||||
skip_stmt = ((SKIP + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="skip_stmt"))("skip_stmt")
|
||||
subtype_constraint_id = (simple_id)("subtype_constraint_id")
|
||||
type_id = (simple_id)("type_id")
|
||||
type_label_id = (simple_id)("type_label_id")
|
||||
unary_op = ((CaselessLiteral("+") | CaselessLiteral("-") | NOT)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="unary_op"))("unary_op")
|
||||
variable_id = (simple_id)("variable_id")
|
||||
encoded_character = ((octet + octet + octet + octet)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="encoded_character"))("encoded_character")
|
||||
not_paren_star = ((letter | digit | not_paren_star_special)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="not_paren_star"))("not_paren_star")
|
||||
not_rparen_star = ((not_paren_star | CaselessLiteral("("))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="not_rparen_star"))("not_rparen_star")
|
||||
not_rparen_star_then_rparen = ((not_rparen_star + ZeroOrMore(not_rparen_star) + CaselessLiteral(")") + ZeroOrMore(CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="not_rparen_star_then_rparen"))("not_rparen_star_then_rparen")
|
||||
encoded_string_literal = ((CaselessLiteral("\"") + encoded_character + ZeroOrMore(encoded_character) + CaselessLiteral("\""))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="encoded_string_literal"))("encoded_string_literal")
|
||||
real_literal = (((digits + CaselessLiteral(".") + Optional(digits) + Optional((CaselessLiteral("e") + Optional(sign) + digits))) | integer_literal))("real_literal")
|
||||
attribute_ref = (attribute_id)("attribute_ref")
|
||||
constant_ref = (constant_id)("constant_ref")
|
||||
entity_ref = (entity_id)("entity_ref")
|
||||
enumeration_ref = (enumeration_id)("enumeration_ref")
|
||||
function_ref = (function_id)("function_ref")
|
||||
parameter_ref = (parameter_id)("parameter_ref")
|
||||
procedure_ref = (procedure_id)("procedure_ref")
|
||||
rule_label_ref = (rule_label_id)("rule_label_ref")
|
||||
rule_ref = (rule_id)("rule_ref")
|
||||
schema_ref = (schema_id)("schema_ref")
|
||||
subtype_constraint_ref = (subtype_constraint_id)("subtype_constraint_ref")
|
||||
type_label_ref = (type_label_id)("type_label_ref")
|
||||
type_ref = (type_id)("type_ref")
|
||||
variable_ref = (variable_id)("variable_ref")
|
||||
attribute_qualifier = ((CaselessLiteral(".") + attribute_ref)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="attribute_qualifier"))("attribute_qualifier")
|
||||
constant_factor = ((built_in_constant | constant_ref)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constant_factor"))("constant_factor")
|
||||
enumeration_extension = ((BASED_ON + type_ref + Optional((WITH + enumeration_items)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="enumeration_extension"))("enumeration_extension")
|
||||
enumeration_reference = ((Optional((type_ref + CaselessLiteral("."))) + enumeration_ref)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="enumeration_reference"))("enumeration_reference")
|
||||
enumeration_type = ((Optional(EXTENSIBLE) + ENUMERATION + Optional(((OF + enumeration_items) | enumeration_extension)))).setParseAction(EnumerationType)("enumeration_type")
|
||||
general_ref = ((parameter_ref | variable_ref)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_ref"))("general_ref")
|
||||
group_qualifier = ((CaselessLiteral("\\") + entity_ref)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="group_qualifier"))("group_qualifier")
|
||||
named_types = ((entity_ref | type_ref)).setParseAction(NamedType)("named_types")
|
||||
named_type_or_rename = ((named_types + Optional((AS + (entity_id | type_id))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="named_type_or_rename"))("named_type_or_rename")
|
||||
population = (entity_ref)("population")
|
||||
qualified_attribute = ((SELF + group_qualifier + attribute_qualifier)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualified_attribute"))("qualified_attribute")
|
||||
redeclared_attribute = ((qualified_attribute + Optional((RENAMED + attribute_id)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="redeclared_attribute"))("redeclared_attribute")
|
||||
referenced_attribute = ((attribute_ref | qualified_attribute)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="referenced_attribute"))("referenced_attribute")
|
||||
rename_id = ((constant_id | entity_id | function_id | procedure_id | type_id)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="rename_id"))("rename_id")
|
||||
resource_ref = ((constant_ref | entity_ref | function_ref | procedure_ref | type_ref)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="resource_ref"))("resource_ref")
|
||||
rule_head = ((RULE + rule_id + FOR + CaselessLiteral("(") + entity_ref + ZeroOrMore((CaselessLiteral(",") + entity_ref)) + CaselessLiteral(")") + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="rule_head"))("rule_head")
|
||||
select_list = ((CaselessLiteral("(") + named_types + ZeroOrMore((CaselessLiteral(",") + named_types)) + CaselessLiteral(")"))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="select_list"))("select_list")
|
||||
string_literal = ((simple_string_literal | encoded_string_literal))("string_literal")
|
||||
subtype_constraint_head = ((SUBTYPE_CONSTRAINT + subtype_constraint_id + FOR + entity_ref + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_head"))("subtype_constraint_head")
|
||||
subtype_declaration = ((SUBTYPE + OF + CaselessLiteral("(") + entity_ref + ZeroOrMore((CaselessLiteral(",") + entity_ref)) + CaselessLiteral(")"))).setParseAction(SubTypeExpression)("subtype_declaration")
|
||||
total_over = ((TOTAL_OVER + CaselessLiteral("(") + entity_ref + ZeroOrMore((CaselessLiteral(",") + entity_ref)) + CaselessLiteral(")") + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="total_over"))("total_over")
|
||||
type_label = ((type_label_id | type_label_ref)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="type_label"))("type_label")
|
||||
unique_rule = ((Optional((rule_label_id + CaselessLiteral(":"))) + referenced_attribute + ZeroOrMore((CaselessLiteral(",") + referenced_attribute)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="unique_rule"))("unique_rule")
|
||||
use_clause = ((USE + FROM + schema_ref + Optional((CaselessLiteral("(") + named_type_or_rename + ZeroOrMore((CaselessLiteral(",") + named_type_or_rename)) + CaselessLiteral(")"))) + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="use_clause"))("use_clause")
|
||||
not_lparen_star = ((not_paren_star | CaselessLiteral(")"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="not_lparen_star"))("not_lparen_star")
|
||||
remark_ref = ((attribute_ref | constant_ref | entity_ref | enumeration_ref | function_ref | parameter_ref | procedure_ref | rule_label_ref | rule_ref | schema_ref | subtype_constraint_ref | type_label_ref | type_ref | variable_ref)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="remark_ref"))("remark_ref")
|
||||
attribute_decl = ((redeclared_attribute | attribute_id)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="attribute_decl"))("attribute_decl")
|
||||
generic_entity_type = ((GENERIC_ENTITY + Optional((CaselessLiteral(":") + type_label)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generic_entity_type"))("generic_entity_type")
|
||||
generic_type = ((GENERIC + Optional((CaselessLiteral(":") + type_label)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generic_type"))("generic_type")
|
||||
literal = ((binary_literal | logical_literal | real_literal | string_literal)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="literal"))("literal")
|
||||
resource_or_rename = ((resource_ref + Optional((AS + rename_id)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="resource_or_rename"))("resource_or_rename")
|
||||
schema_version_id = (string_literal)("schema_version_id")
|
||||
select_extension = ((BASED_ON + type_ref + Optional((WITH + select_list)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="select_extension"))("select_extension")
|
||||
select_type = ((Optional((EXTENSIBLE + Optional(GENERIC_ENTITY))) + SELECT + Optional((select_list | select_extension)))).setParseAction(SelectType)("select_type")
|
||||
unique_clause = ((UNIQUE + unique_rule + CaselessLiteral(";") + ZeroOrMore((unique_rule + CaselessLiteral(";"))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="unique_clause"))("unique_clause")
|
||||
lparen_then_not_lparen_star = ((CaselessLiteral("(") + ZeroOrMore(CaselessLiteral("(")) + not_lparen_star + ZeroOrMore(not_lparen_star))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="lparen_then_not_lparen_star"))("lparen_then_not_lparen_star")
|
||||
remark_tag = ((CaselessLiteral("\"") + remark_ref + ZeroOrMore((CaselessLiteral(".") + remark_ref)) + CaselessLiteral("\""))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="remark_tag"))("remark_tag")
|
||||
tail_remark = ((CaselessLiteral("--") + Optional(remark_tag))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="tail_remark"))("tail_remark")
|
||||
constructed_types = ((enumeration_type | select_type)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constructed_types"))("constructed_types")
|
||||
reference_clause = ((REFERENCE + FROM + schema_ref + Optional((CaselessLiteral("(") + resource_or_rename + ZeroOrMore((CaselessLiteral(",") + resource_or_rename)) + CaselessLiteral(")"))) + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="reference_clause"))("reference_clause")
|
||||
interface_specification = ((reference_clause | use_clause)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="interface_specification"))("interface_specification")
|
||||
supertype_factor = Forward()("supertype_factor")
|
||||
interval_item = Forward()("interval_item")
|
||||
subtype_constraint = Forward()("subtype_constraint")
|
||||
repeat_stmt = Forward()("repeat_stmt")
|
||||
subsuper = Forward()("subsuper")
|
||||
increment = Forward()("increment")
|
||||
remark = Forward()("remark")
|
||||
increment_control = Forward()("increment_control")
|
||||
local_variable = Forward()("local_variable")
|
||||
until_control = Forward()("until_control")
|
||||
while_control = Forward()("while_control")
|
||||
parameter = Forward()("parameter")
|
||||
width = Forward()("width")
|
||||
string_type = Forward()("string_type")
|
||||
array_type = Forward()("array_type")
|
||||
if_stmt = Forward()("if_stmt")
|
||||
index = Forward()("index")
|
||||
repetition = Forward()("repetition")
|
||||
index_qualifier = Forward()("index_qualifier")
|
||||
bound_1 = Forward()("bound_1")
|
||||
procedure_decl = Forward()("procedure_decl")
|
||||
entity_constructor = Forward()("entity_constructor")
|
||||
inverse_clause = Forward()("inverse_clause")
|
||||
function_head = Forward()("function_head")
|
||||
formal_parameter = Forward()("formal_parameter")
|
||||
interval_high = Forward()("interval_high")
|
||||
entity_decl = Forward()("entity_decl")
|
||||
abstract_supertype_declaration = Forward()("abstract_supertype_declaration")
|
||||
index_1 = Forward()("index_1")
|
||||
general_aggregation_types = Forward()("general_aggregation_types")
|
||||
real_type = Forward()("real_type")
|
||||
type_decl = Forward()("type_decl")
|
||||
stmt = Forward()("stmt")
|
||||
declaration = Forward()("declaration")
|
||||
explicit_attr = Forward()("explicit_attr")
|
||||
compound_stmt = Forward()("compound_stmt")
|
||||
aggregation_types = Forward()("aggregation_types")
|
||||
simple_factor = Forward()("simple_factor")
|
||||
where_clause = Forward()("where_clause")
|
||||
entity_head = Forward()("entity_head")
|
||||
underlying_type = Forward()("underlying_type")
|
||||
subtype_constraint_decl = Forward()("subtype_constraint_decl")
|
||||
logical_expression = Forward()("logical_expression")
|
||||
case_label = Forward()("case_label")
|
||||
expression = Forward()("expression")
|
||||
general_list_type = Forward()("general_list_type")
|
||||
actual_parameter_list = Forward()("actual_parameter_list")
|
||||
width_spec = Forward()("width_spec")
|
||||
selector = Forward()("selector")
|
||||
syntax = Forward()("syntax")
|
||||
aggregate_source = Forward()("aggregate_source")
|
||||
return_stmt = Forward()("return_stmt")
|
||||
embedded_remark = Forward()("embedded_remark")
|
||||
parameter_type = Forward()("parameter_type")
|
||||
term = Forward()("term")
|
||||
derived_attr = Forward()("derived_attr")
|
||||
repeat_control = Forward()("repeat_control")
|
||||
assignment_stmt = Forward()("assignment_stmt")
|
||||
bag_type = Forward()("bag_type")
|
||||
inverse_attr = Forward()("inverse_attr")
|
||||
constant_body = Forward()("constant_body")
|
||||
precision_spec = Forward()("precision_spec")
|
||||
general_bag_type = Forward()("general_bag_type")
|
||||
qualifiable_factor = Forward()("qualifiable_factor")
|
||||
bound_2 = Forward()("bound_2")
|
||||
instantiable_type = Forward()("instantiable_type")
|
||||
general_set_type = Forward()("general_set_type")
|
||||
supertype_rule = Forward()("supertype_rule")
|
||||
factor = Forward()("factor")
|
||||
list_type = Forward()("list_type")
|
||||
one_of = Forward()("one_of")
|
||||
aggregate_type = Forward()("aggregate_type")
|
||||
entity_body = Forward()("entity_body")
|
||||
generalized_types = Forward()("generalized_types")
|
||||
case_stmt = Forward()("case_stmt")
|
||||
binary_type = Forward()("binary_type")
|
||||
local_decl = Forward()("local_decl")
|
||||
alias_stmt = Forward()("alias_stmt")
|
||||
simple_expression = Forward()("simple_expression")
|
||||
general_array_type = Forward()("general_array_type")
|
||||
interval = Forward()("interval")
|
||||
procedure_head = Forward()("procedure_head")
|
||||
function_decl = Forward()("function_decl")
|
||||
supertype_expression = Forward()("supertype_expression")
|
||||
set_type = Forward()("set_type")
|
||||
primary = Forward()("primary")
|
||||
procedure_call_stmt = Forward()("procedure_call_stmt")
|
||||
simple_types = Forward()("simple_types")
|
||||
query_expression = Forward()("query_expression")
|
||||
index_2 = Forward()("index_2")
|
||||
constant_decl = Forward()("constant_decl")
|
||||
case_action = Forward()("case_action")
|
||||
schema_body = Forward()("schema_body")
|
||||
element = Forward()("element")
|
||||
numeric_expression = Forward()("numeric_expression")
|
||||
aggregate_initializer = Forward()("aggregate_initializer")
|
||||
schema_decl = Forward()("schema_decl")
|
||||
supertype_term = Forward()("supertype_term")
|
||||
algorithm_head = Forward()("algorithm_head")
|
||||
supertype_constraint = Forward()("supertype_constraint")
|
||||
interval_low = Forward()("interval_low")
|
||||
domain_rule = Forward()("domain_rule")
|
||||
rule_decl = Forward()("rule_decl")
|
||||
concrete_types = Forward()("concrete_types")
|
||||
qualifier = Forward()("qualifier")
|
||||
subtype_constraint_body = Forward()("subtype_constraint_body")
|
||||
function_call = Forward()("function_call")
|
||||
bound_spec = Forward()("bound_spec")
|
||||
derive_clause = Forward()("derive_clause")
|
||||
supertype_factor << (((supertype_term + ZeroOrMore((AND + supertype_term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_factor"))
|
||||
interval_item << (simple_expression)
|
||||
subtype_constraint << (((OF + CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint"))
|
||||
repeat_stmt << (((REPEAT + repeat_control + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_REPEAT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="repeat_stmt"))
|
||||
subsuper << (((Optional(supertype_constraint) + Optional(subtype_declaration)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subsuper"))
|
||||
increment << (numeric_expression)
|
||||
remark << (((embedded_remark | tail_remark))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="remark"))
|
||||
increment_control << (((variable_id + CaselessLiteral(":=") + bound_1 + TO + bound_2 + Optional((BY + increment))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="increment_control"))
|
||||
local_variable << (((variable_id + ZeroOrMore((CaselessLiteral(",") + variable_id)) + CaselessLiteral(":") + parameter_type + Optional((CaselessLiteral(":=") + expression)) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_variable"))
|
||||
until_control << (((UNTIL + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="until_control"))
|
||||
while_control << (((WHILE + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="while_control"))
|
||||
parameter << (expression)
|
||||
width << (numeric_expression)
|
||||
string_type << (((STRING + Optional(width_spec)))).setParseAction(StringType)
|
||||
array_type << (((ARRAY + bound_spec + OF + Optional(OPTIONAL) + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="array_type"))
|
||||
if_stmt << (((IF + logical_expression + THEN + stmt + ZeroOrMore(stmt) + Optional((ELSE + stmt + ZeroOrMore(stmt))) + END_IF + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="if_stmt"))
|
||||
index << (numeric_expression)
|
||||
repetition << (numeric_expression)
|
||||
index_qualifier << (((CaselessLiteral("[") + index_1 + Optional((CaselessLiteral(":") + index_2)) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="index_qualifier"))
|
||||
bound_1 << (numeric_expression)
|
||||
procedure_decl << (((procedure_head + algorithm_head + ZeroOrMore(stmt) + END_PROCEDURE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_decl"))
|
||||
entity_constructor << (((entity_ref + CaselessLiteral("(") + Optional((expression + ZeroOrMore((CaselessLiteral(",") + expression)))) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_constructor"))
|
||||
inverse_clause << (((INVERSE + inverse_attr + ZeroOrMore(inverse_attr)))).setParseAction(AttributeList)
|
||||
function_head << (((FUNCTION + function_id + Optional((CaselessLiteral("(") + formal_parameter + ZeroOrMore((CaselessLiteral(";") + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(":") + parameter_type + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="function_head"))
|
||||
formal_parameter << (((parameter_id + ZeroOrMore((CaselessLiteral(",") + parameter_id)) + CaselessLiteral(":") + parameter_type))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="formal_parameter"))
|
||||
interval_high << (simple_expression)
|
||||
entity_decl << (((entity_head + entity_body + END_ENTITY + CaselessLiteral(";")))).setParseAction(EntityDeclaration)
|
||||
abstract_supertype_declaration << (((ABSTRACT + SUPERTYPE + Optional(subtype_constraint)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype_declaration"))
|
||||
index_1 << (index)
|
||||
general_aggregation_types << (((general_array_type | general_bag_type | general_list_type | general_set_type))).setParseAction(AggregationType)
|
||||
real_type << (((REAL + Optional((CaselessLiteral("(") + precision_spec + CaselessLiteral(")")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="real_type"))
|
||||
type_decl << (((TYPE + type_id + CaselessLiteral("=") + underlying_type + CaselessLiteral(";") + Optional(where_clause) + END_TYPE + CaselessLiteral(";")))).setParseAction(TypeDeclaration)
|
||||
stmt << (((alias_stmt | assignment_stmt | case_stmt | compound_stmt | escape_stmt | if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt | skip_stmt))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="stmt"))
|
||||
declaration << (((entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="declaration"))
|
||||
explicit_attr << (((attribute_decl + ZeroOrMore((CaselessLiteral(",") + attribute_decl)) + CaselessLiteral(":") + Optional(OPTIONAL) + parameter_type + CaselessLiteral(";")))).setParseAction(ExplicitAttribute)
|
||||
compound_stmt << (((BEGIN + stmt + ZeroOrMore(stmt) + END + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="compound_stmt"))
|
||||
aggregation_types << (((array_type | bag_type | list_type | set_type))).setParseAction(AggregationType)
|
||||
simple_factor << (((aggregate_initializer | interval | query_expression | (Optional(unary_op) + ((CaselessLiteral("(") + expression + CaselessLiteral(")")) | primary)) | entity_constructor | enumeration_reference))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="simple_factor"))
|
||||
where_clause << (((WHERE + domain_rule + CaselessLiteral(";") + ZeroOrMore((domain_rule + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="where_clause"))
|
||||
entity_head << (((ENTITY + entity_id + subsuper + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="entity_head"))
|
||||
underlying_type << (((constructed_types | concrete_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="underlying_type"))
|
||||
subtype_constraint_decl << (((subtype_constraint_head + subtype_constraint_body + END_SUBTYPE_CONSTRAINT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_decl"))
|
||||
logical_expression << (expression)
|
||||
case_label << (expression)
|
||||
expression << (((simple_expression + Optional((rel_op_extended + simple_expression))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="expression"))
|
||||
general_list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_list_type"))
|
||||
actual_parameter_list << (((CaselessLiteral("(") + Optional(parameter) + ZeroOrMore((CaselessLiteral(",") + parameter)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="actual_parameter_list"))
|
||||
width_spec << (((CaselessLiteral("(") + width + CaselessLiteral(")") + Optional(FIXED)))).setParseAction(WidthSpec)
|
||||
selector << (expression)
|
||||
syntax << (((schema_decl + ZeroOrMore(schema_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="syntax"))
|
||||
aggregate_source << (simple_expression)
|
||||
return_stmt << (((RETURN + Optional((CaselessLiteral("(") + expression + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="return_stmt"))
|
||||
embedded_remark << (((CaselessLiteral("(*") + Optional(remark_tag) + ZeroOrMore(((not_paren_star + ZeroOrMore(not_paren_star)) | lparen_then_not_lparen_star | (CaselessLiteral("*") + ZeroOrMore(CaselessLiteral("*"))) | not_rparen_star_then_rparen | embedded_remark)) + CaselessLiteral("*)")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="embedded_remark"))
|
||||
parameter_type << (((generalized_types | simple_types | named_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="parameter_type"))
|
||||
term << (((factor + ZeroOrMore((multiplication_like_op + factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="term"))
|
||||
derived_attr << (((attribute_decl + CaselessLiteral(":") + parameter_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="derived_attr"))
|
||||
repeat_control << (((Optional(increment_control) + Optional(while_control) + Optional(until_control)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="repeat_control"))
|
||||
assignment_stmt << (((general_ref + ZeroOrMore(qualifier) + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="assignment_stmt"))
|
||||
bag_type << (((BAG + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="bag_type"))
|
||||
inverse_attr << (((attribute_decl + CaselessLiteral(":") + Optional(((SET | BAG) + Optional(bound_spec) + OF)) + entity_ref + FOR + Optional((entity_ref + CaselessLiteral("."))) + attribute_ref + CaselessLiteral(";")))).setParseAction(InverseAttribute)
|
||||
constant_body << (((constant_id + CaselessLiteral(":") + instantiable_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constant_body"))
|
||||
precision_spec << (numeric_expression)
|
||||
general_bag_type << (((BAG + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_bag_type"))
|
||||
qualifiable_factor << (((function_call | attribute_ref | constant_factor | general_ref | population))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifiable_factor"))
|
||||
bound_2 << (numeric_expression)
|
||||
instantiable_type << (((concrete_types | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="instantiable_type"))
|
||||
general_set_type << (((SET + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_set_type"))
|
||||
supertype_rule << (((SUPERTYPE + subtype_constraint))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_rule"))
|
||||
factor << (((simple_factor + Optional((CaselessLiteral("**") + simple_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="factor"))
|
||||
list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="list_type"))
|
||||
one_of << (((ONEOF + CaselessLiteral("(") + supertype_expression + ZeroOrMore((CaselessLiteral(",") + supertype_expression)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="one_of"))
|
||||
aggregate_type << (((AGGREGATE + Optional((CaselessLiteral(":") + type_label)) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="aggregate_type"))
|
||||
entity_body << (((ZeroOrMore(explicit_attr) + Optional(derive_clause) + Optional(inverse_clause) + Optional(unique_clause) + Optional(where_clause)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_body"))
|
||||
generalized_types << (((aggregate_type | general_aggregation_types | generic_entity_type | generic_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generalized_types"))
|
||||
case_stmt << (((CASE + selector + OF + ZeroOrMore(case_action) + Optional((OTHERWISE + CaselessLiteral(":") + stmt)) + END_CASE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_stmt"))
|
||||
binary_type << (((BINARY + Optional(width_spec)))).setParseAction(BinaryType)
|
||||
local_decl << (((LOCAL + local_variable + ZeroOrMore(local_variable) + END_LOCAL + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_decl"))
|
||||
alias_stmt << (((ALIAS + variable_id + FOR + general_ref + ZeroOrMore(qualifier) + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_ALIAS + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="alias_stmt"))
|
||||
simple_expression << (((term + ZeroOrMore((add_like_op + term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="simple_expression"))
|
||||
general_array_type << (((ARRAY + Optional(bound_spec) + OF + Optional(OPTIONAL) + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_array_type"))
|
||||
interval << (((CaselessLiteral("{") + interval_low + interval_op + interval_item + interval_op + interval_high + CaselessLiteral("}")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="interval"))
|
||||
procedure_head << (((PROCEDURE + procedure_id + Optional((CaselessLiteral("(") + Optional(VAR) + formal_parameter + ZeroOrMore((CaselessLiteral(";") + Optional(VAR) + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_head"))
|
||||
function_decl << (((function_head + algorithm_head + stmt + ZeroOrMore(stmt) + END_FUNCTION + CaselessLiteral(";")))).setParseAction(FunctionDeclaration)
|
||||
supertype_expression << (((supertype_factor + ZeroOrMore((ANDOR + supertype_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_expression"))
|
||||
set_type << (((SET + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="set_type"))
|
||||
primary << (((literal | (qualifiable_factor + ZeroOrMore(qualifier))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="primary"))
|
||||
procedure_call_stmt << ((((built_in_procedure | procedure_ref) + actual_parameter_list + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="procedure_call_stmt"))
|
||||
simple_types << (((binary_type | boolean_type | integer_type | logical_type | number_type | real_type | string_type))).setParseAction(SimpleType)
|
||||
query_expression << (((QUERY + CaselessLiteral("(") + variable_id + CaselessLiteral("<*") + aggregate_source + CaselessLiteral("|") + logical_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="query_expression"))
|
||||
index_2 << (index)
|
||||
constant_decl << (((CONSTANT + constant_body + ZeroOrMore(constant_body) + END_CONSTANT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="constant_decl"))
|
||||
case_action << (((case_label + ZeroOrMore((CaselessLiteral(",") + case_label)) + CaselessLiteral(":") + stmt))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_action"))
|
||||
schema_body << (((ZeroOrMore(interface_specification) + Optional(constant_decl) + ZeroOrMore((declaration | rule_decl))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="schema_body"))
|
||||
element << (((expression + Optional((CaselessLiteral(":") + repetition))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="element"))
|
||||
numeric_expression << (simple_expression)
|
||||
aggregate_initializer << (((CaselessLiteral("[") + Optional((element + ZeroOrMore((CaselessLiteral(",") + element)))) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="aggregate_initializer"))
|
||||
schema_decl << (((SCHEMA + schema_id + Optional(schema_version_id) + CaselessLiteral(";") + schema_body + END_SCHEMA + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="schema_decl"))
|
||||
supertype_term << (((one_of | (CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")) | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_term"))
|
||||
algorithm_head << (((ZeroOrMore(declaration) + Optional(constant_decl) + Optional(local_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="algorithm_head"))
|
||||
supertype_constraint << (((abstract_supertype_declaration | abstract_entity_declaration | supertype_rule))).setParseAction(SuperTypeExpression)
|
||||
interval_low << (simple_expression)
|
||||
domain_rule << (((Optional((rule_label_id + CaselessLiteral(":"))) + expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="domain_rule"))
|
||||
rule_decl << (((rule_head + algorithm_head + ZeroOrMore(stmt) + where_clause + END_RULE + CaselessLiteral(";")))).setParseAction(RuleDeclaration)
|
||||
concrete_types << (((aggregation_types | simple_types | type_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="concrete_types"))
|
||||
qualifier << (((attribute_qualifier | group_qualifier | index_qualifier))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifier"))
|
||||
subtype_constraint_body << (((Optional(abstract_supertype) + Optional(total_over) + Optional((supertype_expression + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_body"))
|
||||
function_call << ((((built_in_function | function_ref) + actual_parameter_list))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="function_call"))
|
||||
bound_spec << (((CaselessLiteral("[") + bound_1 + CaselessLiteral(":") + bound_2 + CaselessLiteral("]")))).setParseAction(BoundSpecification)
|
||||
derive_clause << (((DERIVE + derived_attr + ZeroOrMore(derived_attr)))).setParseAction(AttributeList)
|
||||
|
||||
syntax.ignore("--" + restOfLine)
|
||||
syntax.ignore(Regex(r"\((?:\*(?:[^*]*\*+)+?\))"))
|
||||
ast = syntax.parseFile(fn)
|
||||
s = schema.Schema(ast)
|
||||
m = mapping.Mapping(s)
|
||||
|
||||
with open(cache_file, "wb") as f:
|
||||
pickle.dump(m, f, protocol=0)
|
||||
return m
|
||||
|
||||
if __name__ == "__main__":
|
||||
m = parse(sys.argv[1])
|
||||
import importlib
|
||||
for output in sys.argv[2:]:
|
||||
mdl = importlib.import_module(output)
|
||||
mdl.Generator(m).emit()
|
||||
sys.stdout.write(m.schema.name)
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import operator
|
||||
import itertools
|
||||
|
||||
import codegen
|
||||
import templates
|
||||
import documentation
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
USE_VIRTUAL_INHERITANCE = True
|
||||
|
||||
|
||||
class Header(codegen.Base):
|
||||
def __init__(self, mapping):
|
||||
declarations = []
|
||||
|
||||
case_lookup = lambda nm: [k for k in mapping.schema.keys if k.lower() == nm.lower()][0]
|
||||
case_normalize = lambda nm: nm if nm.startswith("IfcUtil::") else case_lookup(nm)
|
||||
create_supertype_statement = lambda nms: ", ".join(
|
||||
"public %s %s" % ("" if c.startswith("IfcUtil::") else "", c) for c in nms
|
||||
)
|
||||
|
||||
write = lambda str, **kwargs: declarations.append(
|
||||
str
|
||||
% dict({"documentation": templates.multi_line_comment(documentation.description(kwargs["name"]))}, **kwargs)
|
||||
)
|
||||
|
||||
forward_names = list(mapping.schema.entities.keys()) + list(mapping.schema.simpletypes.keys())
|
||||
forward_definitions = "".join(["class %s; " % n for n in forward_names])
|
||||
|
||||
select_super_types = defaultdict(list)
|
||||
|
||||
for name, type in mapping.schema.selects.items():
|
||||
for nm in type.values:
|
||||
select_super_types[str(nm).lower()].append(name)
|
||||
write(templates.select_virtual if USE_VIRTUAL_INHERITANCE else templates.select_plain, name=name)
|
||||
|
||||
def get_select_super_types(nm, bases=[]):
|
||||
x = list(select_super_types[nm.lower()])
|
||||
for y in x:
|
||||
x.extend(get_select_super_types(y))
|
||||
return sorted(set(x) - set(itertools.chain.from_iterable(map(get_select_super_types, bases))))
|
||||
|
||||
for name, type in mapping.schema.enumerations.items():
|
||||
short_name = name[:-4] if name.endswith("Enum") else name
|
||||
write(templates.enumeration, name=name, values=", ".join(["%s_%s" % (short_name, v) for v in type.values]))
|
||||
|
||||
emitted_simpletypes = set()
|
||||
while len(emitted_simpletypes) < len(mapping.schema.simpletypes):
|
||||
for name, type in mapping.schema.simpletypes.items():
|
||||
|
||||
if name.lower() in emitted_simpletypes:
|
||||
continue
|
||||
|
||||
type_str = mapping.make_type_string(mapping.flatten_type_string(type))
|
||||
attr_type = mapping.make_argument_type(type)
|
||||
superclass = mapping.simple_type_parent(name)
|
||||
|
||||
superclasses = []
|
||||
all_superclasses = []
|
||||
if superclass is not None:
|
||||
superclasses.append(superclass)
|
||||
while superclass:
|
||||
all_superclasses.append(superclass)
|
||||
superclass = mapping.simple_type_parent(superclass)
|
||||
else:
|
||||
superclasses.append("IfcUtil::IfcBaseType")
|
||||
|
||||
if USE_VIRTUAL_INHERITANCE:
|
||||
superclasses.extend(get_select_super_types(name, bases=all_superclasses))
|
||||
|
||||
is_emitted = (
|
||||
lambda nm: nm == "IfcUtil::IfcBaseType"
|
||||
or nm in mapping.schema.selects
|
||||
or nm.lower() in emitted_simpletypes
|
||||
)
|
||||
if not all(map(is_emitted, superclasses)):
|
||||
continue
|
||||
|
||||
superclasses = list(map(case_normalize, superclasses))
|
||||
|
||||
emitted_simpletypes.add(name.lower())
|
||||
|
||||
superclass_statement = create_supertype_statement(superclasses)
|
||||
|
||||
write(
|
||||
templates.simpletype, name=name, type=type_str, attr_type=attr_type, superclass=superclass_statement
|
||||
)
|
||||
|
||||
class_definitions = []
|
||||
|
||||
write = lambda str, **kwargs: class_definitions.append(
|
||||
str
|
||||
% dict({"documentation": templates.multi_line_comment(documentation.description(kwargs["name"]))}, **kwargs)
|
||||
)
|
||||
|
||||
emitted_entities = set()
|
||||
while len(emitted_entities) < len(mapping.schema.entities):
|
||||
for name, type in mapping.schema.entities.items():
|
||||
if name.lower() in emitted_entities:
|
||||
continue
|
||||
|
||||
if len(type.supertypes) == 0 or set(map(str.lower, type.supertypes)) <= emitted_entities:
|
||||
attr_lines = []
|
||||
|
||||
def write_method(attr):
|
||||
attr_lines.extend(
|
||||
["/// %s" % d for d in documentation.description(".".join((name, attr.name)))]
|
||||
)
|
||||
type_str = mapping.get_parameter_type(attr)
|
||||
if mapping.make_argument_type(attr) != "IfcUtil::Argument_UNKNOWN":
|
||||
attr_lines.append("%s %s() const;" % (type_str, attr.name))
|
||||
attr_lines.append("void set%s(%s v);" % (attr.name, type_str))
|
||||
|
||||
[write_method(attr) for attr in type.attributes]
|
||||
|
||||
inv_lines = []
|
||||
|
||||
def write_inverse(attr):
|
||||
inv_lines.append(
|
||||
templates.inverse_attr
|
||||
% {"name": attr.name, "entity": attr.entity, "attribute": attr.attribute}
|
||||
)
|
||||
|
||||
if type.inverse:
|
||||
[write_inverse(attr) for attr in type.inverse]
|
||||
|
||||
attributes = "\n".join(["%s%s" % (" " * 4, a) for a in attr_lines])
|
||||
if len(attributes):
|
||||
attributes += "\n"
|
||||
|
||||
inverse = "\n".join(["%s%s" % (" " * 4, a) for a in inv_lines])
|
||||
if len(inverse):
|
||||
inverse += "\n"
|
||||
|
||||
all_supertypes = []
|
||||
tt = type
|
||||
while len(tt.supertypes):
|
||||
all_supertypes.append(tt.supertypes[0])
|
||||
tt = mapping.schema.entities[tt.supertypes[0]]
|
||||
|
||||
supertypes = list(type.supertypes) if len(type.supertypes) else ["IfcUtil::IfcBaseEntity"]
|
||||
if USE_VIRTUAL_INHERITANCE:
|
||||
supertypes.extend(get_select_super_types(name, bases=all_supertypes))
|
||||
supertypes = list(map(case_normalize, supertypes))
|
||||
superclass = create_supertype_statement(supertypes)
|
||||
|
||||
argument_count = mapping.argument_count(type)
|
||||
|
||||
argument_start = argument_count - len(type.attributes)
|
||||
|
||||
argument_name_function_body_switch_stmt = (
|
||||
" switch (i) {%s}"
|
||||
% (
|
||||
"".join(
|
||||
[
|
||||
'case %d: return "%s"; ' % (i + argument_start, attr.name)
|
||||
for i, attr in enumerate(type.attributes)
|
||||
]
|
||||
)
|
||||
)
|
||||
if len(type.attributes)
|
||||
else ""
|
||||
)
|
||||
argument_name_function_body_tail = (
|
||||
(" return %s::getArgumentName(i); " % type.supertypes[0])
|
||||
if len(type.supertypes) == 1
|
||||
else ' (void)i; throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); '
|
||||
)
|
||||
|
||||
argument_name_function_body = (
|
||||
argument_name_function_body_switch_stmt + argument_name_function_body_tail
|
||||
)
|
||||
|
||||
derived = mapping.derived_in_supertype(type)
|
||||
attribute_names = list(map(operator.attrgetter("name"), mapping.arguments(type)))
|
||||
derived_in_supertype = set(derived) & set(attribute_names)
|
||||
derived_in_supertype_indices = sorted(attribute_names.index(nm) for nm in derived_in_supertype)
|
||||
attribute_type_cases = [
|
||||
"case %d: return IfcUtil::Argument_DERIVED; " % idx for idx in derived_in_supertype_indices
|
||||
]
|
||||
attribute_type_cases += [
|
||||
"case %d: return %s; " % (i + argument_start, mapping.make_argument_type(attr))
|
||||
for i, attr in enumerate(type.attributes)
|
||||
]
|
||||
argument_type_function_body_switch_stmt = (
|
||||
" switch (i) {%s}" % ("".join(attribute_type_cases)) if len(type.attributes) else ""
|
||||
)
|
||||
argument_type_function_body_tail = (
|
||||
(" return %s::getArgumentType(i); " % type.supertypes[0])
|
||||
if len(type.supertypes) == 1
|
||||
else ' (void)i; throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); '
|
||||
)
|
||||
|
||||
argument_type_function_body = (
|
||||
argument_type_function_body_switch_stmt + argument_type_function_body_tail
|
||||
)
|
||||
|
||||
argument_entity_function_body_switch_stmt = (
|
||||
" switch (i) {%s}"
|
||||
% (
|
||||
"".join(
|
||||
[
|
||||
"case %d: return %s; " % (i + argument_start, mapping.make_argument_entity(attr))
|
||||
for i, attr in enumerate(type.attributes)
|
||||
]
|
||||
)
|
||||
)
|
||||
if len(type.attributes)
|
||||
else ""
|
||||
)
|
||||
argument_entity_function_body_tail = (
|
||||
(" return %s::getArgumentEntity(i); " % type.supertypes[0])
|
||||
if len(type.supertypes) == 1
|
||||
else ' (void)i; throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); '
|
||||
)
|
||||
|
||||
argument_entity_function_body = (
|
||||
argument_entity_function_body_switch_stmt + argument_entity_function_body_tail
|
||||
)
|
||||
|
||||
constructor_arguments = ", ".join(
|
||||
"%(full_type)s v%(index)d_%(name)s" % a for a in mapping.get_assignable_arguments(type)
|
||||
)
|
||||
|
||||
write(templates.entity, **locals())
|
||||
emitted_entities.add(name)
|
||||
|
||||
self.str = templates.header % {
|
||||
"schema_name_upper": mapping.schema.name.upper(),
|
||||
"schema_name": mapping.schema.name.capitalize(),
|
||||
"declarations": "".join(declarations),
|
||||
"forward_definitions": forward_definitions,
|
||||
"class_definitions": "".join(class_definitions),
|
||||
}
|
||||
|
||||
self.schema_name = mapping.schema.name.capitalize()
|
||||
|
||||
self.file_name = "%s.h" % self.schema_name
|
||||
|
||||
def __repr__(self):
|
||||
return self.str
|
||||
|
||||
|
||||
Generator = Header
|
||||
@@ -0,0 +1,28 @@
|
||||
SCHEMA header_section_schema;
|
||||
|
||||
TYPE time_stamp_text = STRING(256);
|
||||
END_TYPE;
|
||||
|
||||
TYPE schema_name = STRING(1024);
|
||||
END_TYPE;
|
||||
|
||||
ENTITY file_name;
|
||||
name : STRING (256);
|
||||
time_stamp : time_stamp_text;
|
||||
author : LIST [1:?] OF STRING (256);
|
||||
organization : LIST [1:?] OF STRING (256);
|
||||
preprocessor_version : STRING (256);
|
||||
originating_system : STRING (256);
|
||||
authorisation : STRING (256);
|
||||
END_ENTITY;
|
||||
|
||||
ENTITY file_description;
|
||||
description : LIST [1:?] OF STRING (256);
|
||||
implementation_level : STRING (256);
|
||||
END_ENTITY;
|
||||
|
||||
ENTITY file_schema;
|
||||
schema_identifiers : LIST [1:?] OF UNIQUE schema_name;
|
||||
END_ENTITY;
|
||||
|
||||
END_SCHEMA;
|
||||
@@ -0,0 +1,444 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import codegen
|
||||
import templates
|
||||
|
||||
from schema import OrderedCaseInsensitiveDict
|
||||
|
||||
from header import USE_VIRTUAL_INHERITANCE
|
||||
|
||||
|
||||
class Implementation(codegen.Base):
|
||||
def __init__(self, mapping):
|
||||
enumeration_functions = []
|
||||
entity_implementations = []
|
||||
schema_entity_statements = []
|
||||
|
||||
schema_name = mapping.schema.name.capitalize()
|
||||
schema_name_upper = mapping.schema.name.upper()
|
||||
|
||||
stringify = lambda s: '"%s"' % s
|
||||
cat = lambda vs: "".join(vs)
|
||||
catc = lambda vs: ", ".join(vs)
|
||||
catnl = lambda vs: "\n".join(vs)
|
||||
cator = lambda vs: " || ".join(vs)
|
||||
nl = lambda s: "%s\n" % s if len(s) else s
|
||||
|
||||
write = lambda str, **kwargs: enumeration_functions.append(str % kwargs)
|
||||
|
||||
collections_by_type = (
|
||||
("entity", mapping.schema.entities),
|
||||
("type_declaration", mapping.schema.simpletypes),
|
||||
("select_type", mapping.schema.selects),
|
||||
("enumeration_type", mapping.schema.enumerations),
|
||||
)
|
||||
self.names = []
|
||||
for _, collection in collections_by_type:
|
||||
self.names.extend(collection.keys())
|
||||
self.names.sort(key=str.lower)
|
||||
|
||||
for name, enum in mapping.schema.enumerations.items():
|
||||
short_name = name[:-4] if name.endswith("Enum") else name
|
||||
context = locals()
|
||||
write(
|
||||
templates.enumeration_function,
|
||||
max_id=len(enum.values),
|
||||
name=name,
|
||||
schema_name=schema_name,
|
||||
schema_name_upper=schema_name_upper,
|
||||
index_in_schema=self.names.index(str(name)),
|
||||
values=catc(map(stringify, enum.values)),
|
||||
from_string_statements=catnl(
|
||||
templates.enum_from_string_stmt % dict(context, **locals()) for value in enum.values
|
||||
),
|
||||
)
|
||||
|
||||
if USE_VIRTUAL_INHERITANCE:
|
||||
for name, enum in mapping.schema.selects.items():
|
||||
write(
|
||||
templates.select_function,
|
||||
name=name,
|
||||
schema_name=schema_name,
|
||||
schema_name_upper=schema_name_upper,
|
||||
index_in_schema=self.names.index(str(name)),
|
||||
)
|
||||
|
||||
write = lambda str, **kwargs: entity_implementations.append(str % kwargs)
|
||||
|
||||
for name, type in mapping.schema.entities.items():
|
||||
parent_type_test = (
|
||||
""
|
||||
if not type.supertypes or len(type.supertypes) != 1
|
||||
else templates.parent_type_test % (type.supertypes[0])
|
||||
)
|
||||
|
||||
constructor_arguments = mapping.get_assignable_arguments(type, include_derived=True)
|
||||
constructor_arguments_str = catc(
|
||||
"%(full_type)s v%(index)d_%(name)s" % a for a in constructor_arguments if not a["is_derived"]
|
||||
)
|
||||
attributes = []
|
||||
constructor_implementations = []
|
||||
write_attr = lambda str, **kwargs: attributes.append(str % kwargs)
|
||||
for arg in constructor_arguments:
|
||||
if not arg["is_inherited"] and not arg["is_derived"]:
|
||||
|
||||
def find_template(arg):
|
||||
simple = mapping.schema.is_simpletype(arg["list_instance_type"])
|
||||
select = arg["list_instance_type"] == "IfcUtil::IfcBaseClass"
|
||||
express = (
|
||||
mapping.flatten_type_string(arg["list_instance_type"]) in mapping.express_to_cpp_typemapping
|
||||
)
|
||||
if arg["is_enum"]:
|
||||
return templates.get_attr_stmt_enum
|
||||
elif arg["is_nested"] and arg["is_templated_list"]:
|
||||
return templates.get_attr_stmt_nested_array
|
||||
elif arg["is_templated_list"] and not (select or simple or express):
|
||||
return templates.get_attr_stmt_array
|
||||
elif arg["non_optional_type"].endswith("*"):
|
||||
return templates.get_attr_stmt_entity
|
||||
else:
|
||||
return templates.get_attr_stmt
|
||||
|
||||
null_check = ""
|
||||
if arg["is_optional"]:
|
||||
attr_check = "if(get_attribute_value(%d).isNull()) { return %%s; }" % (arg["index"] - 1,)
|
||||
if "boost::optional" in arg["full_type"]:
|
||||
null_check = attr_check % "boost::none"
|
||||
else:
|
||||
null_check = attr_check % "nullptr"
|
||||
|
||||
tmpl = find_template(arg)
|
||||
write_attr(
|
||||
templates.const_function,
|
||||
class_name=name,
|
||||
name=arg["name"],
|
||||
arguments="",
|
||||
schema_name=schema_name,
|
||||
schema_name_upper=schema_name_upper,
|
||||
return_type=arg["full_type"],
|
||||
body=tmpl
|
||||
% {
|
||||
"index": arg["index"] - 1,
|
||||
"type": arg["full_type"].replace("::Value", ""),
|
||||
"non_optional_type": arg["non_optional_type"].replace("::Value", ""),
|
||||
"non_optional_type_no_pointer": arg["non_optional_type"]
|
||||
.replace("::Value", "")
|
||||
.replace("*", ""),
|
||||
"list_instance_type": arg["list_instance_type"],
|
||||
"null_check": null_check,
|
||||
},
|
||||
)
|
||||
|
||||
def find_template(arg):
|
||||
simple = mapping.schema.is_simpletype(arg["list_instance_type"])
|
||||
select = arg["list_instance_type"] == "IfcUtil::IfcBaseClass"
|
||||
express = arg["list_instance_type"] in mapping.express_to_cpp_typemapping
|
||||
if arg["is_enum"]:
|
||||
return templates.set_attr_stmt_enum
|
||||
elif arg["is_templated_list"] and not (select or simple or express):
|
||||
return templates.set_attr_stmt_array
|
||||
elif arg["full_type"].endswith("*"):
|
||||
return templates.set_attr_instance
|
||||
else:
|
||||
return templates.set_attr_stmt
|
||||
|
||||
tmpl = find_template(arg)
|
||||
write_attr(
|
||||
templates.function,
|
||||
class_name=name,
|
||||
name="set%s" % arg["name"],
|
||||
arguments="%s v" % arg["full_type"],
|
||||
return_type="void",
|
||||
schema_name=schema_name,
|
||||
schema_name_upper=schema_name_upper,
|
||||
body=tmpl
|
||||
% {
|
||||
"index": arg["index"] - 1,
|
||||
"type": arg["full_type"].replace("::Value", ""),
|
||||
"non_optional_type": arg["non_optional_type"].replace("::Value", ""),
|
||||
"star_if_optional": "*" if "boost::optional" in arg["full_type"] else "",
|
||||
"check_optional_set_begin": "if (v) {" if "boost::optional" in arg["full_type"] else "",
|
||||
"check_optional_set_else": (
|
||||
"} else {" if "boost::optional" in arg["full_type"] else "if constexpr (false)"
|
||||
),
|
||||
"check_optional_set_end": "}" if "boost::optional" in arg["full_type"] else "",
|
||||
},
|
||||
)
|
||||
|
||||
if arg["is_derived"]:
|
||||
constructor_implementations.append(templates.constructor_stmt_derived % {"index": arg["index"] - 1})
|
||||
else:
|
||||
is_optional_non_naked_ptr = arg["is_optional"] and not arg["non_optional_type"].endswith("*")
|
||||
arg_name = "v%(index)d_%(name)s" % arg
|
||||
deref_name = ("*%s" % arg_name) if is_optional_non_naked_ptr else arg_name
|
||||
|
||||
tmpl = (
|
||||
templates.constructor_stmt_array
|
||||
if arg["is_templated_list"]
|
||||
else (
|
||||
templates.constructor_stmt_enum
|
||||
if arg["is_enum"]
|
||||
else (
|
||||
templates.constructor_stmt_instance
|
||||
if arg["full_type"].endswith("*")
|
||||
else templates.constructor_stmt
|
||||
)
|
||||
)
|
||||
)
|
||||
impl = tmpl % {
|
||||
"name": deref_name,
|
||||
"index": arg["index"] - 1,
|
||||
"type": arg["non_optional_type"].replace("::Value", ""),
|
||||
}
|
||||
if is_optional_non_naked_ptr:
|
||||
impl = templates.constructor_stmt_optional % {
|
||||
"name": arg_name,
|
||||
"index": arg["index"] - 1,
|
||||
"stmt": impl,
|
||||
}
|
||||
constructor_implementations.append(impl)
|
||||
|
||||
def get_attribute_index(entity, attr_name):
|
||||
related_entity = mapping.schema.entities[entity]
|
||||
return [
|
||||
a["name"].lower() for a in mapping.get_assignable_arguments(related_entity, include_derived=True)
|
||||
].index(attr_name.lower())
|
||||
|
||||
inverse = [
|
||||
templates.const_function
|
||||
% {
|
||||
"class_name": name,
|
||||
"schema_name": schema_name,
|
||||
"schema_name_upper": schema_name_upper,
|
||||
"name": i.name,
|
||||
"arguments": "",
|
||||
"return_type": "::%s::%s::list::ptr" % (schema_name, i.entity),
|
||||
"body": templates.get_inverse
|
||||
% {
|
||||
"type": i.entity,
|
||||
"type_index": self.names.index(i.entity),
|
||||
"index": get_attribute_index(i.entity, i.attribute),
|
||||
"schema_name": schema_name,
|
||||
"schema_name_upper": schema_name_upper,
|
||||
},
|
||||
}
|
||||
for i in type.inverse
|
||||
]
|
||||
|
||||
superclass = (
|
||||
"%s(std::move(e))" % type.supertypes[0]
|
||||
if len(type.supertypes) == 1
|
||||
else "IfcUtil::IfcBaseEntity(std::move(e))"
|
||||
)
|
||||
|
||||
superclass_num_attrs = (
|
||||
"%s(IfcEntityInstanceData(in_memory_attribute_storage(%%d)))" % type.supertypes[0]
|
||||
if len(type.supertypes) == 1
|
||||
else "IfcUtil::IfcBaseEntity(IfcEntityInstanceData(in_memory_attribute_storage(%d)))"
|
||||
) % len(constructor_arguments)
|
||||
|
||||
write(
|
||||
templates.entity_implementation,
|
||||
name=name,
|
||||
parent_type_test=parent_type_test,
|
||||
constructor_arguments=constructor_arguments_str,
|
||||
constructor_implementation=cat(constructor_implementations),
|
||||
attributes=nl(catnl(attributes)),
|
||||
inverse=nl(catnl(inverse)),
|
||||
superclass=superclass,
|
||||
superclass_num_attrs=superclass_num_attrs,
|
||||
schema_name=schema_name,
|
||||
schema_name_upper=schema_name_upper,
|
||||
index_in_schema=self.names.index(str(name)),
|
||||
)
|
||||
|
||||
selectable_simple_types = sorted(
|
||||
set(sum([b.values for a, b in mapping.schema.selects.items()], []))
|
||||
& set(map(str, mapping.schema.types.keys()))
|
||||
)
|
||||
schema_entity_statements += [
|
||||
templates.schema_entity_stmt % locals() for name, type in mapping.schema.simpletypes.items()
|
||||
]
|
||||
schema_entity_statements += [
|
||||
templates.schema_entity_stmt % locals() for name, type in mapping.schema.enumerations.items()
|
||||
]
|
||||
schema_entity_statements += [
|
||||
templates.schema_entity_stmt % locals() for name, type in mapping.schema.entities.items()
|
||||
]
|
||||
|
||||
enumerable_types = sorted(
|
||||
set(
|
||||
[name for name, type in mapping.schema.types.items()]
|
||||
+ [name for name, type in mapping.schema.entities.items()]
|
||||
)
|
||||
)
|
||||
max_len = max(map(len, enumerable_types))
|
||||
type_name_strings = catc(map(stringify, enumerable_types))
|
||||
string_map_statements = [
|
||||
templates.string_map_statement
|
||||
% {"uppercase_name": name.upper(), "name": name, "padding": " " * (max_len - len(name))}
|
||||
for name in enumerable_types
|
||||
]
|
||||
|
||||
enumeration_index_by_str = OrderedCaseInsensitiveDict((j, i) for i, j in enumerate(enumerable_types))
|
||||
|
||||
def get_parent_id(s):
|
||||
e = mapping.schema.entities.get(s)
|
||||
if e and e.supertypes:
|
||||
return enumeration_index_by_str[e.supertypes[0]]
|
||||
else:
|
||||
return -1
|
||||
|
||||
parent_type_statements = ",".join(map(str, map(get_parent_id, enumerable_types)))
|
||||
|
||||
max_id = len(enumerable_types)
|
||||
|
||||
simple_type_statements = cator("v == Type::%s" % name for name in selectable_simple_types)
|
||||
|
||||
simple_type_impl = []
|
||||
for class_name, type in mapping.schema.simpletypes.items():
|
||||
type_str = mapping.make_type_string(mapping.flatten_type_string(type))
|
||||
attr_type = mapping.make_argument_type(type)
|
||||
superclass = mapping.simple_type_parent(class_name) or "IfcUtil::IfcBaseType"
|
||||
|
||||
simpletype_impl_is = (
|
||||
templates.simpletype_impl_is_with_supertype
|
||||
if superclass
|
||||
else templates.simpletype_impl_is_without_supertype
|
||||
)
|
||||
|
||||
constructor = templates.constructor_single_initlist # if superclass else templates.constructor
|
||||
|
||||
simpletype_impl_cast = (
|
||||
templates.simpletype_impl_cast_templated
|
||||
if mapping.is_templated_list(type)
|
||||
else templates.simpletype_impl_cast
|
||||
)
|
||||
|
||||
simpletype_impl_constructor = (
|
||||
templates.simpletype_impl_constructor_templated
|
||||
if mapping.is_templated_list(type)
|
||||
else templates.simpletype_impl_constructor
|
||||
)
|
||||
|
||||
def compose(params, schema_name=schema_name, schema_name_upper=schema_name_upper):
|
||||
class_name, attr_type, superclass, superclass_init, name, tmpl, return_type, args, body = params
|
||||
index_in_schema = self.names.index(str(class_name))
|
||||
underlying_type = mapping.list_instance_type(type)
|
||||
arguments = ",".join(args)
|
||||
body = body % locals()
|
||||
return tmpl % locals()
|
||||
|
||||
simple_type_impl.append(templates.simpletype_impl_comment % {"name": class_name})
|
||||
simple_type_impl.extend(
|
||||
map(
|
||||
compose,
|
||||
map(
|
||||
lambda x: (class_name, attr_type, superclass) + x,
|
||||
(
|
||||
(
|
||||
"",
|
||||
"Class",
|
||||
templates.function,
|
||||
"const IfcParse::type_declaration&",
|
||||
(),
|
||||
templates.simpletype_impl_class,
|
||||
),
|
||||
(
|
||||
"",
|
||||
"declaration",
|
||||
templates.const_function,
|
||||
"const IfcParse::type_declaration&",
|
||||
(),
|
||||
templates.simpletype_impl_declaration,
|
||||
),
|
||||
(
|
||||
"std::move(e)",
|
||||
"",
|
||||
constructor,
|
||||
"",
|
||||
("IfcEntityInstanceData&& e",),
|
||||
"",
|
||||
),
|
||||
(
|
||||
(
|
||||
"",
|
||||
"",
|
||||
constructor,
|
||||
"",
|
||||
("%s v" % type_str,),
|
||||
(
|
||||
"set_attribute_value(0, v%s);"
|
||||
% ("->generalize()" if mapping.is_templated_list(type) else "")
|
||||
),
|
||||
)
|
||||
if mapping.simple_type_parent(class_name) is None
|
||||
else ("v", "", constructor, "", ("%s v" % type_str,), "")
|
||||
),
|
||||
("", "", templates.cast_function, type_str, (), simpletype_impl_cast),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
simple_type_impl.append("")
|
||||
|
||||
"""
|
||||
external_definitions = (
|
||||
[("extern entity* %s_%%s_type;" % schema_name_upper) % n for n in mapping.schema.entities.keys()]
|
||||
+ [
|
||||
("extern type_declaration* %s_%%s_type;" % schema_name_upper) % n
|
||||
for n in mapping.schema.simpletypes.keys()
|
||||
]
|
||||
+ [
|
||||
("extern enumeration_type* %s_%%s_type;" % schema_name_upper) % n
|
||||
for n in mapping.schema.enumerations.keys()
|
||||
]
|
||||
+ [
|
||||
("extern select_type* %s_%%s_type;" % schema_name_upper) % n
|
||||
for n in mapping.schema.selects.keys()
|
||||
]
|
||||
)
|
||||
"""
|
||||
external_definitions = ["extern declaration* %s_types[%d];" % (schema_name_upper, len(self.names))]
|
||||
|
||||
self.str = templates.implementation % {
|
||||
"schema_name_upper": schema_name_upper,
|
||||
"schema_name": schema_name,
|
||||
"max_id": max_id,
|
||||
"enumeration_functions": cat(enumeration_functions),
|
||||
"schema_entity_statements": catnl(schema_entity_statements),
|
||||
"type_name_strings": type_name_strings,
|
||||
"string_map_statements": catnl(string_map_statements),
|
||||
"simple_type_statement": simple_type_statements,
|
||||
"parent_type_statements": parent_type_statements,
|
||||
"entity_implementations": catnl(entity_implementations),
|
||||
"simple_type_impl": catnl(simple_type_impl),
|
||||
"external_definitions": catnl(external_definitions),
|
||||
}
|
||||
|
||||
self.schema_name = mapping.schema.name.capitalize()
|
||||
|
||||
self.file_name = "%s.cpp" % self.schema_name
|
||||
|
||||
def __repr__(self):
|
||||
return self.str
|
||||
|
||||
|
||||
Generator = Implementation
|
||||
@@ -0,0 +1,295 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import sys
|
||||
import nodes
|
||||
import templates
|
||||
import schema
|
||||
|
||||
from header import USE_VIRTUAL_INHERITANCE
|
||||
|
||||
|
||||
class Mapping:
|
||||
|
||||
express_to_cpp_typemapping = {
|
||||
"boolean": "bool",
|
||||
"logical": "boost::logic::tribool",
|
||||
"integer": "int",
|
||||
"real": "double",
|
||||
"number": "double",
|
||||
"string": "std::string",
|
||||
"binary": "boost::dynamic_bitset<>",
|
||||
}
|
||||
|
||||
supported_argument_types = set(
|
||||
[
|
||||
"INT",
|
||||
"BOOL",
|
||||
"LOGICAL",
|
||||
"DOUBLE",
|
||||
"STRING",
|
||||
"BINARY",
|
||||
"ENUMERATION",
|
||||
"ENTITY_INSTANCE",
|
||||
"AGGREGATE_OF_INT",
|
||||
"AGGREGATE_OF_DOUBLE",
|
||||
"AGGREGATE_OF_STRING",
|
||||
"AGGREGATE_OF_BINARY",
|
||||
"AGGREGATE_OF_ENTITY_INSTANCE",
|
||||
"AGGREGATE_OF_AGGREGATE_OF_INT",
|
||||
"AGGREGATE_OF_AGGREGATE_OF_DOUBLE",
|
||||
"AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE",
|
||||
]
|
||||
)
|
||||
|
||||
def __init__(self, schema: schema.Schema):
|
||||
self.schema = schema
|
||||
|
||||
def flatten_type_string(self, type):
|
||||
return self.flatten_type_string(self.schema.types[type].type) if self.schema.is_simpletype(type) else type
|
||||
|
||||
def flatten_type(self, type):
|
||||
res = self.flatten_type(self.schema.types[type].type) if self.schema.is_simpletype(type) else type
|
||||
return res
|
||||
|
||||
def simple_type_parent(self, type):
|
||||
parent = self.schema.types[type].type
|
||||
if isinstance(parent, (nodes.AggregationType, nodes.StringType)) or (
|
||||
isinstance(parent, nodes.SimpleType) and isinstance(parent.type, nodes.StringType)
|
||||
):
|
||||
return None
|
||||
if str(parent) in self.express_to_cpp_typemapping:
|
||||
return None
|
||||
return str(parent)
|
||||
|
||||
def make_type_string(self, type):
|
||||
if isinstance(type, nodes.StringType) or (
|
||||
isinstance(type, nodes.SimpleType) and isinstance(type.type, nodes.StringType)
|
||||
):
|
||||
type = "string"
|
||||
if isinstance(type, (str, nodes.BinaryType, nodes.SimpleType, nodes.NamedType)):
|
||||
return self.express_to_cpp_typemapping.get(str(type), "::%s::%s" % (self.schema.name.capitalize(), type))
|
||||
else:
|
||||
if type.bounds is None:
|
||||
import pdb
|
||||
|
||||
pdb.set_trace()
|
||||
is_list = self.schema.is_entity(type.type)
|
||||
is_nested_list = isinstance(type.type, nodes.AggregationType)
|
||||
tmpl = (
|
||||
templates.list_list_type if is_nested_list else templates.list_type if is_list else templates.array_type
|
||||
)
|
||||
return tmpl % {
|
||||
"instance_type": self.make_type_string(self.flatten_type_string(type.type)),
|
||||
"lower": type.bounds.lower,
|
||||
"upper": type.bounds.upper,
|
||||
}
|
||||
|
||||
def is_array(self, type):
|
||||
if isinstance(type, nodes.AggregationType):
|
||||
return True
|
||||
elif isinstance(type, str) and self.schema.is_type(type):
|
||||
return self.is_array(self.schema.types[type].type)
|
||||
else:
|
||||
return False
|
||||
|
||||
def make_argument_entity(self, attr):
|
||||
type = attr.type if hasattr(attr, "type") else attr
|
||||
while isinstance(type, nodes.AggregationType):
|
||||
type = type.type
|
||||
if str(type) in self.express_to_cpp_typemapping:
|
||||
return "Type::UNDEFINED"
|
||||
else:
|
||||
return "Type::%s" % type
|
||||
|
||||
def make_argument_type(self, attr):
|
||||
def _make_argument_type(type):
|
||||
if isinstance(type, nodes.SimpleType):
|
||||
type = type.type
|
||||
if self.schema.is_entity(type) or isinstance(type, nodes.SelectType):
|
||||
return "ENTITY_INSTANCE"
|
||||
elif isinstance(type, nodes.BinaryType):
|
||||
return "BINARY"
|
||||
elif isinstance(type, nodes.StringType):
|
||||
return "STRING"
|
||||
elif isinstance(type, nodes.EnumerationType):
|
||||
return "ENUMERATION"
|
||||
elif isinstance(type, nodes.AggregationType):
|
||||
ty = _make_argument_type(type.type)
|
||||
if ty == "UNKNOWN":
|
||||
return "UNKNOWN"
|
||||
return "AGGREGATE_OF_" + ty
|
||||
elif str(type) in self.express_to_cpp_typemapping:
|
||||
return self.express_to_cpp_typemapping.get(str(type), type).split("::")[-1].upper()
|
||||
elif self.schema.is_type(type):
|
||||
return _make_argument_type(self.schema.types[type].type)
|
||||
else:
|
||||
raise ValueError("Unable to map type %r for attribute %r" % (type, attr))
|
||||
|
||||
ty = _make_argument_type(attr.type if hasattr(attr, "type") else attr)
|
||||
if ty == "TRIBOOL":
|
||||
ty = "LOGICAL"
|
||||
|
||||
if ty not in self.supported_argument_types:
|
||||
import pdb
|
||||
|
||||
pdb.set_trace()
|
||||
print("Attribute %r mapped as 'unknown'" % (attr), file=sys.stderr)
|
||||
ty = "UNKNOWN"
|
||||
return "IfcUtil::Argument_%s" % ty
|
||||
|
||||
def get_type_dep(self, type):
|
||||
if isinstance(type, str):
|
||||
return self.express_to_cpp_typemapping.get(str(type), type)
|
||||
else:
|
||||
return self.get_type_dep(type.type)
|
||||
|
||||
def get_parameter_type(self, attr, allow_optional=True):
|
||||
attr_type = self.flatten_type(attr.type)
|
||||
|
||||
if (isinstance(attr_type, nodes.SimpleType) and isinstance(attr_type.type, nodes.StringType)) or isinstance(
|
||||
attr_type, nodes.StringType
|
||||
):
|
||||
type_str = self.express_to_cpp_typemapping["string"]
|
||||
else:
|
||||
type_str = self.express_to_cpp_typemapping.get(str(attr_type), attr_type)
|
||||
|
||||
is_ptr = False
|
||||
|
||||
if self.schema.is_enumeration(attr_type):
|
||||
type_str = "::%s::%s::Value" % (self.schema.name.capitalize(), attr_type)
|
||||
elif isinstance(type_str, nodes.AggregationType):
|
||||
is_nested_list = isinstance(attr_type.type, nodes.AggregationType)
|
||||
ty = self.get_parameter_type(attr_type.type if is_nested_list else attr_type)
|
||||
# We do not use pointers in aggregate_of<T>. aggregate_of has member vector<T*>
|
||||
ty = ty.replace("*", "")
|
||||
|
||||
# https://github.com/IfcOpenShell/IfcOpenShell/issues/2805
|
||||
# We do support statically typed select types as aggregates when USE_VIRTUAL_INHERITANCE=True
|
||||
|
||||
if not USE_VIRTUAL_INHERITANCE and self.schema.is_select(attr_type.type):
|
||||
type_str = templates.untyped_list
|
||||
elif self.schema.is_simpletype(ty) or str(ty) in self.express_to_cpp_typemapping.values():
|
||||
tmpl = templates.nested_array_type if is_nested_list else templates.array_type
|
||||
bounds = (attr_type.bounds.lower, attr_type.bounds.upper) if attr_type.bounds else (-1, -1)
|
||||
type_str = tmpl % {"instance_type": ty, "lower": bounds[0], "upper": bounds[1]}
|
||||
else:
|
||||
tmpl = templates.list_list_type if is_nested_list else templates.list_type
|
||||
type_str = tmpl % {"instance_type": ty}
|
||||
elif self.schema.is_entity(type_str) or self.schema.is_select(type_str):
|
||||
type_str = "::%s::%s*" % (self.schema.name.capitalize(), attr_type)
|
||||
is_ptr = True
|
||||
if allow_optional and attr.optional and not is_ptr:
|
||||
# pointers are still handled with nullptr for the time being
|
||||
type_str = "boost::optional< %s >" % type_str
|
||||
return type_str
|
||||
|
||||
def argument_count(self, t):
|
||||
c = sum([self.argument_count(self.schema.entities[s]) for s in t.supertypes])
|
||||
return c + len(t.attributes)
|
||||
|
||||
def arguments(self, t):
|
||||
c = sum([self.arguments(self.schema.entities[s]) for s in t.supertypes], [])
|
||||
return c + t.attributes
|
||||
|
||||
def derived_in_supertype(self, t):
|
||||
c = sum([self.derived_in_supertype(self.schema.entities[s]) for s in t.supertypes], [])
|
||||
derived = c + t.derive
|
||||
return [d[0][1] for d in derived if isinstance(d[0], tuple)]
|
||||
|
||||
def list_instance_type(self, attr):
|
||||
attr_type = attr.type if isinstance(attr, nodes.ExplicitAttribute) else attr
|
||||
if isinstance(attr_type, str):
|
||||
return None
|
||||
|
||||
def f(v):
|
||||
v = self.flatten_type(v)
|
||||
if isinstance(v, (nodes.AggregationType, nodes.StringType)) or (
|
||||
isinstance(v, nodes.SimpleType) and isinstance(v.type, nodes.StringType)
|
||||
):
|
||||
return "string"
|
||||
if not USE_VIRTUAL_INHERITANCE and self.schema.is_select(v):
|
||||
return "IfcUtil::IfcBaseClass"
|
||||
if str(v) in self.schema.types or str(v) in self.schema.entities:
|
||||
return "::%s::%s" % (self.schema.name.capitalize(), v)
|
||||
else:
|
||||
return str(v)
|
||||
|
||||
if self.is_array(attr_type):
|
||||
if not isinstance(attr_type, str) and self.is_array(attr_type.type):
|
||||
if isinstance(attr_type.type, str):
|
||||
return f(attr_type.type)
|
||||
else:
|
||||
return f(attr_type.type.type)
|
||||
else:
|
||||
if isinstance(attr_type, str):
|
||||
return f(attr_type)
|
||||
else:
|
||||
return f(attr_type.type)
|
||||
return None
|
||||
|
||||
def is_templated_list(self, attr):
|
||||
attr_type = attr.type if isinstance(attr, nodes.ExplicitAttribute) else attr
|
||||
if isinstance(attr, str):
|
||||
return False
|
||||
ty = self.list_instance_type(attr)
|
||||
if ty is None:
|
||||
return False
|
||||
arr = self.is_array(attr_type)
|
||||
simple = self.schema.is_simpletype(ty)
|
||||
express = self.flatten_type_string(ty) in self.express_to_cpp_typemapping
|
||||
select = ty == "IfcUtil::IfcBaseClass"
|
||||
return arr and not simple and not express and not select
|
||||
|
||||
def get_assignable_arguments(self, t, include_derived=False):
|
||||
count = self.argument_count(t)
|
||||
num_inherited = count - len(t.attributes)
|
||||
derived = set(self.derived_in_supertype(t))
|
||||
attrs = enumerate(self.arguments(t))
|
||||
|
||||
def include(attr):
|
||||
not_derived = include_derived or (attr.name not in derived)
|
||||
supported = self.make_argument_type(attr) != "IfcUtil::Argument_UNKNOWN"
|
||||
return not_derived and supported
|
||||
|
||||
return [
|
||||
{
|
||||
"index": i + 1,
|
||||
"name": attr.name,
|
||||
"full_type": self.get_parameter_type(attr),
|
||||
"specialized_type": self.get_parameter_type(attr),
|
||||
"non_optional_type": self.get_parameter_type(attr, allow_optional=False),
|
||||
"list_instance_type": self.list_instance_type(attr),
|
||||
"is_optional": attr.optional,
|
||||
"is_inherited": i < num_inherited,
|
||||
"is_enum": attr.type in self.schema.enumerations,
|
||||
"is_array": self.is_array(attr.type),
|
||||
"is_nested": self.is_array(attr.type)
|
||||
and not isinstance(attr.type, str)
|
||||
and self.is_array(attr.type.type),
|
||||
"is_derived": attr.name in derived,
|
||||
"is_templated_list": self.is_templated_list(attr),
|
||||
"argument_type_enum": self.make_argument_type(attr),
|
||||
"argument_entity": self.make_argument_entity(attr),
|
||||
"argument_type": attr.type,
|
||||
}
|
||||
for i, attr in attrs
|
||||
if include(attr)
|
||||
]
|
||||
@@ -0,0 +1,603 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import io
|
||||
import string
|
||||
import operator
|
||||
import collections
|
||||
import bootstrap
|
||||
|
||||
|
||||
class Node:
|
||||
def __init__(self, s, loc, tokens, rule=None):
|
||||
self.rule = rule or (type(self).__name__)
|
||||
self.tokens = tokens.asDict()
|
||||
self.flat = sum([getattr(t, "flat", [t]) for t in tokens.asList()], [])
|
||||
if rule is None:
|
||||
self.init()
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%s)" % (self.rule, ",".join("%s:%s" % i for i in self.tokens.items()))
|
||||
|
||||
def __getattr__(self, k):
|
||||
return self.tokens.get(k)
|
||||
|
||||
def __getstate__(self):
|
||||
return self.__dict__
|
||||
|
||||
def __setstate__(self, d):
|
||||
self.__dict__.update(d)
|
||||
|
||||
def init(self):
|
||||
pass
|
||||
|
||||
def any(self):
|
||||
return next(iter(self.tokens.values()))
|
||||
|
||||
|
||||
class ListNode:
|
||||
def __init__(self, s, loc, tokens, rule=None):
|
||||
self.rule = rule or (type(self).__name__)
|
||||
self.tokens = tokens.asList()
|
||||
self.dict_tokens = collections.defaultdict(list)
|
||||
|
||||
rules_as_list = set()
|
||||
for t in self.tokens:
|
||||
r = getattr(t, "rule", None)
|
||||
if r:
|
||||
rules_as_list.add(r)
|
||||
self.dict_tokens[r].append(t)
|
||||
|
||||
for r, t in tokens.asDict().items():
|
||||
if r not in rules_as_list:
|
||||
self.dict_tokens[r].append(t)
|
||||
|
||||
self.flat = sum([getattr(t, "flat", [t]) for t in self.tokens], [])
|
||||
|
||||
def __repr__(self):
|
||||
return "%s[%s]" % (self.rule, ",".join("%s" % i for i in self.tokens))
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.tokens)
|
||||
|
||||
# Somehow indexing messes up the pyparsing results, so instead of x[0] use list(x)[0]
|
||||
# def __getitem__(self, i):
|
||||
# return self.tokens[i]
|
||||
|
||||
def init(self):
|
||||
pass
|
||||
|
||||
|
||||
class SimpleType(Node):
|
||||
def get_type(self):
|
||||
t = self.any()
|
||||
if type(t) == Node:
|
||||
return t.any()
|
||||
else:
|
||||
t = t[0]
|
||||
if type(t) == Node:
|
||||
return t.any().any()
|
||||
else:
|
||||
return t
|
||||
|
||||
type = property(get_type)
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.type)
|
||||
|
||||
|
||||
def format_clause(exp):
|
||||
def whitespace(t):
|
||||
if t in {"=", "|", "<*", "or", "in", "<>", "and"}:
|
||||
return " %s " % t
|
||||
return t
|
||||
|
||||
return "".join(whitespace(term) for term in exp.flat)
|
||||
|
||||
|
||||
class TypeDeclaration(Node):
|
||||
name = property(lambda self: self.type_id[0])
|
||||
utype = property(lambda self: self.underlying_type.any().any())
|
||||
type = property(lambda self: self.utype[0] if isinstance(self.utype, list) else self.utype)
|
||||
|
||||
def init(self):
|
||||
|
||||
assert hasattr(self, "TYPE")
|
||||
|
||||
self.where = []
|
||||
clause = self.where_clause
|
||||
if clause:
|
||||
clause = list(clause[0])
|
||||
|
||||
self.where = [(r.simple_id, format_clause(r.expression[0])) for r in clause[1::2]]
|
||||
|
||||
def __repr__(self):
|
||||
s = "TYPE %s = %s;\n" % (self.name, self.type)
|
||||
if self.where:
|
||||
s += " WHERE\n"
|
||||
for nm_exp in self.where:
|
||||
s += " %s : %s;\n" % nm_exp
|
||||
s += "END_TYPE;"
|
||||
return s
|
||||
|
||||
|
||||
class EntityDeclaration(Node):
|
||||
name = property(lambda self: self.entity_head[0].entity_id[0])
|
||||
supertype = property(lambda self: self.entity_head[0].subsuper[0].supertype_constraint)
|
||||
subtype = property(lambda self: self.entity_head[0].subsuper[0].subtype_declaration)
|
||||
supertypes = property(lambda self: [self.subtype.super_type] if self.subtype else [])
|
||||
|
||||
def get_abstract(self):
|
||||
if self.entity_head[0].subsuper[0].supertype_constraint:
|
||||
return self.entity_head[0].subsuper[0].supertype_constraint.abstract
|
||||
else:
|
||||
return False
|
||||
|
||||
abstract = property(get_abstract)
|
||||
|
||||
def init(self):
|
||||
def redeclared_attribute(a):
|
||||
try:
|
||||
return (
|
||||
a.attribute_decl.redeclared_attribute.qualified_attribute.group_qualifier.simple_id,
|
||||
a.attribute_decl.redeclared_attribute.qualified_attribute.attribute_qualifier.simple_id,
|
||||
)
|
||||
except:
|
||||
return a.attribute_decl.simple_id
|
||||
|
||||
assert self.flat[0] == "entity"
|
||||
|
||||
self.attributes = [a for a in self.entity_body[0] if isinstance(a, ExplicitAttribute)]
|
||||
self.inverse = []
|
||||
alist = [x for x in self.entity_body[0] if isinstance(x, AttributeList) and x.type == "inverse"]
|
||||
if alist:
|
||||
self.inverse = alist[0]
|
||||
|
||||
self.derive = []
|
||||
alist = [x for x in self.entity_body[0] if isinstance(x, AttributeList) and x.type == "derive"]
|
||||
if alist:
|
||||
alist = alist[0]
|
||||
self.derive = [(redeclared_attribute(a), format_clause(a.expression[0])) for a in alist]
|
||||
|
||||
self.where = []
|
||||
clause = [r for r in self.entity_body[0] if r.rule == "where_clause"]
|
||||
if clause:
|
||||
clause = list(clause[0])
|
||||
|
||||
self.where = [(r.simple_id, format_clause(r.expression[0])) for r in clause[1::2]]
|
||||
|
||||
self.unique = []
|
||||
clause = [r for r in self.entity_body[0] if r.rule == "unique_clause"]
|
||||
if clause:
|
||||
clause = clause[0]
|
||||
self.unique = [(r[0], r[2].simple_id) for r in map(list, list(clause)[1::2])]
|
||||
|
||||
def __repr__(self):
|
||||
strm = io.StringIO()
|
||||
|
||||
print("ENTITY %s" % self.name, file=strm)
|
||||
|
||||
if self.supertype:
|
||||
print("", self.supertype, file=strm)
|
||||
if self.subtype:
|
||||
print("", self.subtype, file=strm)
|
||||
|
||||
strm.seek(strm.tell() - 1)
|
||||
print(";", file=strm)
|
||||
|
||||
for a in self.attributes:
|
||||
print(" ", a, ";", file=strm, sep="")
|
||||
|
||||
if self.derive:
|
||||
print(" DERIVE", file=strm)
|
||||
for nm, exp in self.derive:
|
||||
if isinstance(nm, tuple):
|
||||
nm = "SELF\\%s.%s" % nm
|
||||
print(" %s : %s;" % (nm, exp), file=strm)
|
||||
|
||||
if self.inverse:
|
||||
print(" INVERSE", file=strm)
|
||||
print(self.inverse, file=strm)
|
||||
|
||||
if self.where:
|
||||
print(" WHERE", file=strm)
|
||||
for nm_exp in self.where:
|
||||
print(" %s : %s;" % nm_exp, file=strm)
|
||||
|
||||
if self.unique:
|
||||
print(" UNIQUE", file=strm)
|
||||
for nm_exp in self.unique:
|
||||
print(" %s : %s;" % nm_exp, file=strm)
|
||||
|
||||
print("END_ENTITY;", file=strm)
|
||||
return strm.getvalue()
|
||||
|
||||
|
||||
class EnumerationType(Node):
|
||||
values = property(lambda self: list(self.enumeration_type[2])[1::2])
|
||||
|
||||
def __repr__(self):
|
||||
return "ENUMERATION OF (" + ",".join(self.values) + ")"
|
||||
|
||||
|
||||
class NamedType(Node):
|
||||
type = property(lambda self: self.simple_id)
|
||||
|
||||
def __repr__(self):
|
||||
return self.type
|
||||
|
||||
|
||||
def do_try(fn):
|
||||
try:
|
||||
return fn()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def get_rule_id(x):
|
||||
if not isinstance(x, str):
|
||||
x = type(x).__name__
|
||||
matches = [k for k, v in bootstrap.actions.items() if v == x]
|
||||
if matches:
|
||||
return matches[0]
|
||||
|
||||
|
||||
rule_dependencies = {
|
||||
k: list(
|
||||
map(
|
||||
operator.attrgetter("contents"),
|
||||
bootstrap.reduce(lambda x, y: x | y, (bootstrap.find_bytype(e, bootstrap.Keyword) for e in [v])),
|
||||
)
|
||||
)
|
||||
for k, v in bootstrap.express
|
||||
}
|
||||
|
||||
all_rules = [k for k, e in bootstrap.express]
|
||||
|
||||
rule_definitions = {k: v for k, v in bootstrap.express}
|
||||
|
||||
|
||||
def to_tree(x, key=None):
|
||||
|
||||
def prune(di):
|
||||
# translate class names back to grammar rules if nested actions are encountered
|
||||
di = {get_rule_id(k) or k: v for k, v in di.items()}
|
||||
|
||||
def replace_synonyms(x):
|
||||
for y in x:
|
||||
yield y
|
||||
if False: # y in di:
|
||||
# production element from grammar is found in parsed data,
|
||||
# return that.
|
||||
|
||||
# we now always explore other synonym, because more often than not we loose data otherwise
|
||||
yield y
|
||||
else:
|
||||
# lookup rule
|
||||
rule = [e for k, e in bootstrap.express if k == y][0]
|
||||
|
||||
def is_synonym(rl):
|
||||
if isinstance(rl, bootstrap.Term) and isinstance(rl.contents, bootstrap.Keyword):
|
||||
return rl.contents.contents
|
||||
|
||||
# is this a synonym? then processs that
|
||||
if S := is_synonym(rule):
|
||||
yield S
|
||||
# Do this recursively
|
||||
yield from replace_synonyms([S])
|
||||
|
||||
# is this a concatenation with zero or more synonyms? then also processs that
|
||||
# @todo catches:
|
||||
# - simple_expression = term { add_like_op term } .
|
||||
# but should probably also work on
|
||||
# - a = b { b }
|
||||
# in which case the second Concat would be eliminated
|
||||
elif (
|
||||
isinstance(rule, bootstrap.Concat)
|
||||
and len(rule.contents) == 2
|
||||
and is_synonym(rule.contents[0])
|
||||
and isinstance(rule.contents[1].contents, bootstrap.Repeated)
|
||||
and isinstance(rule.contents[1].contents.contents[0], bootstrap.Concat)
|
||||
and str(rule.contents[1].contents.contents[0].contents[1]) == str(rule.contents[0])
|
||||
):
|
||||
S = is_synonym(rule.contents[0])
|
||||
yield S
|
||||
# Do this recursively
|
||||
yield from replace_synonyms([S])
|
||||
|
||||
subrules = list(replace_synonyms(rule_dependencies[key]))
|
||||
|
||||
if key == "aggregation_types":
|
||||
# hack hack hack apparently the parser can't distinguish these
|
||||
subrules += list(replace_synonyms(rule_dependencies["general_aggregation_types"]))
|
||||
|
||||
if rule_dependencies[key] and not subrules:
|
||||
# sometimes an intermediate production rule is missing
|
||||
# from the pyparsing output, e.g from parameter to simple_expression
|
||||
# directly. Recover from this.
|
||||
subrules = sum(map(rule_dependencies.__getitem__, rule_dependencies[key]), [])
|
||||
|
||||
if not isinstance(rule_definitions[key], bootstrap.Union):
|
||||
# Filter out terminals when not a union. E.g no
|
||||
# reason to retain TYPE, END_TYPE, but operators
|
||||
# such as IN, LIKE should be retained.
|
||||
subrules = list(filter(str.islower, subrules))
|
||||
|
||||
vs = list(di.values())
|
||||
|
||||
return {k: v for k, v in di.items() if k in subrules or (k == key and len(vs) == 1 and vs[0] not in all_rules)}
|
||||
|
||||
def simplify(di):
|
||||
if isinstance(di, list):
|
||||
if set(map(type, di)) == {str} and set(map(len, di)) == {1}:
|
||||
return "".join(di)
|
||||
return [simplify(v) for v in di]
|
||||
elif isinstance(di, dict) and len(di) == 1 and next(iter(di.values())) == {}:
|
||||
return next(iter(di.keys()))
|
||||
elif isinstance(di, dict):
|
||||
return {k: simplify(v) for k, v in di.items()}
|
||||
else:
|
||||
return di
|
||||
|
||||
if isinstance(x, ListNode):
|
||||
d = to_tree(x.dict_tokens, key=get_rule_id(x) or key)
|
||||
|
||||
if key == "if_stmt":
|
||||
# The definition of if statement if (roughy):
|
||||
# 'if' expr 'then' stmt+ 'else' stmt+
|
||||
# this causes stmt to be joined under the same
|
||||
# dict key. The code below creates an artifical
|
||||
# `else_stmt` that collects the second group
|
||||
# of stmts.
|
||||
|
||||
statements = x.dict_tokens["stmt"]
|
||||
|
||||
else_index = None
|
||||
if_nesting = 0
|
||||
for i, tk in enumerate(x.flat):
|
||||
if tk == "if":
|
||||
if_nesting += 1
|
||||
if tk == "end_if":
|
||||
if_nesting -= 1
|
||||
if tk == "else" and if_nesting == 1:
|
||||
else_index = i
|
||||
|
||||
if else_index:
|
||||
indices = []
|
||||
for s in statements:
|
||||
for i in range(max(indices, default=0), len(x.flat)):
|
||||
if x.flat[i : i + len(s.flat)] == s.flat:
|
||||
indices.append(i)
|
||||
break
|
||||
|
||||
assert len(indices) == len(statements)
|
||||
before_else = [i < else_index for i in indices]
|
||||
|
||||
else_stmt = [st for b, st in zip(before_else, d["stmt"]) if not b]
|
||||
d["stmt"] = [st for b, st in zip(before_else, d["stmt"]) if b]
|
||||
|
||||
if else_stmt:
|
||||
d["else_stmt"] = else_stmt
|
||||
|
||||
if key == "formal_parameter":
|
||||
# Not so pretty hack to fix the overwriting of simple_id-like
|
||||
# ast nodes. The full solution would probably to register parse
|
||||
# actions. And directly reassign.
|
||||
pid = d["parameter_id"][0][0]
|
||||
d["parameter_id"][0] = x.flat[: x.flat.index(pid) + 1 : 2]
|
||||
|
||||
if key is None:
|
||||
return {get_rule_id(x): d}
|
||||
return d
|
||||
elif isinstance(x, Node):
|
||||
d = to_tree(x.tokens, key=get_rule_id(x) or key)
|
||||
if key is None:
|
||||
return {get_rule_id(x): d}
|
||||
return d
|
||||
elif isinstance(x, dict):
|
||||
# d = {k: to_tree(v, key=k) for k, v in x.items()}
|
||||
# not fully understood, but when finding specific node Types and production rules, prioritize the former
|
||||
d = {
|
||||
get_rule_id(k) or k: to_tree(v, key=k)
|
||||
for k, v in sorted(x.items(), key=lambda p: get_rule_id(p[0]) is not None)
|
||||
}
|
||||
return simplify(prune(d))
|
||||
elif isinstance(x, list):
|
||||
return [to_tree(v, key=key) for v in x]
|
||||
else:
|
||||
return x
|
||||
|
||||
|
||||
class AggregationType(Node):
|
||||
aggregate_type = property(lambda self: self.flat[0])
|
||||
bounds = property(lambda self: (list(self.tokens.values())[0][0].bound_spec or [None])[0])
|
||||
unique = property(lambda self: list(self.tokens.values())[0][0].UNIQUE is not None)
|
||||
|
||||
def get_type(self):
|
||||
v = list(self.tokens.values())[0][0]
|
||||
if v.instantiable_type:
|
||||
try:
|
||||
return v.instantiable_type.concrete_types.simple_id or v.instantiable_type.concrete_types.simple_types
|
||||
except:
|
||||
return v.instantiable_type
|
||||
elif v.parameter_type.simple_types:
|
||||
return v.parameter_type.simple_types
|
||||
elif v.parameter_type.named_types:
|
||||
return v.parameter_type.named_types
|
||||
elif v.parameter_type.generalized_types.general_aggregation_types:
|
||||
return v.parameter_type.generalized_types.general_aggregation_types
|
||||
elif do_try(lambda: v.parameter_type.generalized_types.generic_type.generic_type[0].GENERIC):
|
||||
return do_try(lambda: v.parameter_type.generalized_types.generic_type.generic_type[0].GENERIC)
|
||||
else:
|
||||
import pdb
|
||||
|
||||
pdb.set_trace()
|
||||
raise ValueError()
|
||||
|
||||
type = property(get_type)
|
||||
|
||||
def init(self):
|
||||
assert self.bounds is None or isinstance(self.bounds, BoundSpecification)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s%s of %s%s" % (self.aggregate_type, self.bounds, "unique " if self.unique else "", self.type)
|
||||
|
||||
|
||||
class SelectType(Node):
|
||||
values = property(lambda self: list(self.select_type[1])[1::2])
|
||||
|
||||
def __repr__(self):
|
||||
return "SELECT (" + ",".join(map(str, self.values)) + ")"
|
||||
|
||||
|
||||
class SuperTypeExpression(Node):
|
||||
abstract = property(lambda self: self.abstract_supertype_declaration is not None)
|
||||
|
||||
def get_sub_types(self):
|
||||
if self.abstract:
|
||||
constraint = self.abstract_supertype_declaration[0]
|
||||
else:
|
||||
constraint = self.supertype_rule[0]
|
||||
return [
|
||||
list(list(s)[0])[0].simple_id
|
||||
for s in list(list(list(constraint.subtype_constraint[0].supertype_expression[0])[0])[0].one_of[0])[2::2]
|
||||
]
|
||||
|
||||
sub_types = property(get_sub_types)
|
||||
|
||||
def __repr__(self):
|
||||
return "%sSUPERTYPE OF(ONEOF(%s))" % ("ABSTRACT " if self.abstract else "", ",".join(self.sub_types))
|
||||
|
||||
|
||||
class SubTypeExpression(Node):
|
||||
super_type = property(lambda self: self.entity_ref[0])
|
||||
|
||||
def __repr__(self):
|
||||
return "SUBTYPE OF(%s)" % self.super_type
|
||||
|
||||
|
||||
class AttributeList(ListNode):
|
||||
type = property(lambda self: self.flat[0] if self.flat[0] in {"inverse", "derive"} else "explicit")
|
||||
|
||||
def __repr__(self):
|
||||
return "\n".join([" %s;" % s for s in self.tokens[1:]])
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.tokens[1:])
|
||||
|
||||
def __len__(self):
|
||||
return len(self.tokens[1:])
|
||||
|
||||
|
||||
class InverseAttribute(Node):
|
||||
name = property(lambda self: self.attribute_decl.simple_id)
|
||||
type = property(lambda self: self.flat[2] if self.flat[2] != self.flat[-4] else None)
|
||||
bounds = property(lambda self: self.bound_spec[0] if self.bound_spec else None)
|
||||
entity = property(lambda self: self.entity_ref[0])
|
||||
attribute = property(lambda self: self.attribute_ref[0])
|
||||
|
||||
def __repr__(self):
|
||||
def _():
|
||||
yield self.name
|
||||
yield ":"
|
||||
if self.type:
|
||||
yield self.type.upper()
|
||||
yield "OF"
|
||||
if self.bounds:
|
||||
yield self.bounds
|
||||
yield self.entity
|
||||
yield "FOR"
|
||||
yield self.attribute
|
||||
|
||||
return " ".join(map(str, _()))
|
||||
|
||||
|
||||
"""
|
||||
class DerivedAttribute(Node):
|
||||
def init(self):
|
||||
return
|
||||
name_index = list(self.tokens).index(':') - 1
|
||||
self.name = self.tokens[name_index]
|
||||
def __repr__(self):
|
||||
return str(self.name)
|
||||
"""
|
||||
|
||||
|
||||
class BinaryType(Node):
|
||||
def __repr__(self):
|
||||
return "binary"
|
||||
|
||||
|
||||
class BoundSpecification(Node):
|
||||
lower = property(lambda self: self.flat[1])
|
||||
upper = property(lambda self: self.flat[3])
|
||||
|
||||
def __repr__(self):
|
||||
return "[%s:%s]" % (self.lower, self.upper)
|
||||
|
||||
|
||||
class ExplicitAttribute(Node):
|
||||
name = property(lambda self: self.attribute_decl.simple_id)
|
||||
optional = property(lambda self: self.OPTIONAL is not None)
|
||||
|
||||
def get_type(self):
|
||||
v = next(iter(self.parameter_type.tokens.values()))
|
||||
if v.general_aggregation_types:
|
||||
return v.general_aggregation_types
|
||||
else:
|
||||
return v
|
||||
|
||||
type = property(get_type)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s : %s%s" % (self.name, "optional " if self.optional else "", self.type)
|
||||
|
||||
|
||||
class WidthSpec(Node):
|
||||
fixed = property(lambda self: self.FIXED is not None)
|
||||
|
||||
def init(self):
|
||||
self.width = int("".join(list(self.width)[0].flat))
|
||||
|
||||
def __repr__(self):
|
||||
return "(%d)%s" % (self.width, " fixed" if self.fixed else "")
|
||||
|
||||
|
||||
class StringType(Node):
|
||||
width = property(lambda self: self.width_spec[0] if self.width_spec else None)
|
||||
|
||||
def __repr__(self):
|
||||
s = "string"
|
||||
if self.width:
|
||||
s += " " + repr(self.width)
|
||||
return s
|
||||
|
||||
|
||||
class ProcedureDeclaration(ListNode):
|
||||
@property
|
||||
def name(self):
|
||||
return self.flat[1]
|
||||
|
||||
|
||||
class FunctionDeclaration(ProcedureDeclaration):
|
||||
pass
|
||||
|
||||
|
||||
class RuleDeclaration(ProcedureDeclaration):
|
||||
pass
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,299 @@
|
||||
import os
|
||||
import re
|
||||
import ast
|
||||
import collections
|
||||
import ifcopenshell
|
||||
from logging import Logger
|
||||
from dataclasses import dataclass
|
||||
from codegen import indent
|
||||
|
||||
|
||||
def reverse_compile(s):
|
||||
return re.sub(
|
||||
r"\bself\b",
|
||||
"SELF",
|
||||
re.sub(
|
||||
r"\s*\-\s*EXPRESS_ONE_BASED_INDEXING",
|
||||
"",
|
||||
re.sub(
|
||||
", )?+.(, INDETERMINATE)\\"[::-1],
|
||||
"]\\1[",
|
||||
re.sub(
|
||||
r", '(\w+)', INDETERMINATE\)",
|
||||
".\\1",
|
||||
s.strip()
|
||||
.replace("len(", "SIZEOF(")
|
||||
.replace("assert ", "")
|
||||
.replace(" is not False", "")
|
||||
.replace("express_getattr(", "")
|
||||
.replace("express_getitem(", ""),
|
||||
)[::-1],
|
||||
)[::-1],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class error(Exception):
|
||||
rule_name: str
|
||||
rule_definition: str
|
||||
violation: str
|
||||
instance: ifcopenshell.entity_instance = None
|
||||
|
||||
def __str__(self):
|
||||
inst = ""
|
||||
if self.instance:
|
||||
inst = f"On instance:\n{indent(4, str(self.instance))}\n"
|
||||
if self.rule_name:
|
||||
return f"{inst}Rule {self.rule_name}:\n{indent(4, self.rule_definition)}\nViolated by:\n{indent(4, self.violation)}"
|
||||
else:
|
||||
if inst:
|
||||
inst = f"\n\n{inst}"
|
||||
return f"{self.rule_definition}\n\nViolated by:\n{indent(4, self.violation)}{inst}"
|
||||
|
||||
|
||||
def fix_type(v):
|
||||
if isinstance(v, (list, tuple)):
|
||||
# 1-based indexing:
|
||||
#
|
||||
# @todo this is not the best way, because it still allows to index the 0-th element,
|
||||
# but given the existing body of rules this should be sufficient.
|
||||
# return type(v)([None]) + type(v)(map(fix_type, v))
|
||||
|
||||
# We don't do this anymore, because it doesn't fix instance attribute lookups
|
||||
# We now instead perform a -1 on the index qualifier in the code generation
|
||||
pass
|
||||
# @todo enrich entity instances with code to evaluate derived attributes
|
||||
return v
|
||||
|
||||
|
||||
def run(f: ifcopenshell.file, logger: Logger) -> None:
|
||||
from _pytest import assertion
|
||||
|
||||
if hasattr(logger, "set_instance"):
|
||||
# when using the json logger, we notify it of the relevant instance
|
||||
pre_annotate_instance = lambda instance: (
|
||||
logger.set_state("instance", instance) if hasattr(logger, "set_state") else None
|
||||
)
|
||||
post_annotate_instance = lambda instance: instance
|
||||
pre_annotate_attribute = lambda attribute: (
|
||||
logger.set_state("attribute", attribute) if hasattr(logger, "set_state") else None
|
||||
)
|
||||
post_annotate_attribute = lambda attribute: None
|
||||
else:
|
||||
# when using the normal text logger the instance is appended to the method
|
||||
pre_annotate_instance = lambda instance: None
|
||||
post_annotate_instance = lambda instance: instance
|
||||
pre_annotate_attribute = lambda attribute: None
|
||||
post_annotate_attribute = lambda attribute: attribute
|
||||
|
||||
orig = ifcopenshell.settings.unpack_non_aggregate_inverses
|
||||
ifcopenshell.settings.unpack_non_aggregate_inverses = True
|
||||
|
||||
fn = os.path.join(os.path.dirname(__file__), "rules", f"{f.schema_identifier}.py")
|
||||
try:
|
||||
source = open(fn, "r").read()
|
||||
except FileNotFoundError as e:
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
current_dir_files = {fn.lower(): fn for fn in os.listdir(".")}
|
||||
schema_name = str(f.schema_identifier).split(" ")[-1].lower()
|
||||
schema_path = current_dir_files.get(schema_name + ".exp")
|
||||
fn = schema_path[:-4] + ".py"
|
||||
if not os.path.exists(fn):
|
||||
subprocess.run([sys.executable, "-m", "ifcopenshell.express.rule_compiler", schema_path, fn], check=True)
|
||||
time.sleep(1.0)
|
||||
source = open(fn, "r").read()
|
||||
|
||||
a = ast.parse(source)
|
||||
assertion.rewrite.rewrite_asserts(mod=a, source=source)
|
||||
cd = compile(a, f"{f.schema_identifier}.py", "exec")
|
||||
scope = {}
|
||||
exec(cd, scope)
|
||||
S = ifcopenshell.ifcopenshell_wrapper.schema_by_name(f.schema_identifier)
|
||||
|
||||
rules = list(filter(lambda x: hasattr(x, "SCOPE"), scope.values()))
|
||||
|
||||
if hasattr(logger, "set_state"):
|
||||
logger.set_state("type", "global_rule")
|
||||
|
||||
for R in [r for r in rules if r.SCOPE == "file"]:
|
||||
try:
|
||||
R()(f)
|
||||
except RecursionError as e:
|
||||
logger.info(str(e))
|
||||
except Exception as e:
|
||||
ln = e.__traceback__.tb_next.tb_lineno
|
||||
pre_annotate_attribute(R.__name__)
|
||||
logger.error(
|
||||
str(
|
||||
error(
|
||||
post_annotate_attribute(R.__name__),
|
||||
reverse_compile(source.split("\n")[ln - 1]),
|
||||
reverse_compile(e.args[0]),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if hasattr(logger, "set_state"):
|
||||
logger.set_state("type", "simpletype_rule")
|
||||
|
||||
types = {}
|
||||
subtypes = collections.defaultdict(list)
|
||||
for d in S.declarations():
|
||||
if isinstance(d, ifcopenshell.ifcopenshell_wrapper.type_declaration):
|
||||
types[d.name()] = d
|
||||
if isinstance(d.declared_type(), ifcopenshell.ifcopenshell_wrapper.named_type):
|
||||
subtypes[d.declared_type().declared_type().name()].append(d.name())
|
||||
|
||||
D = collections.defaultdict(list)
|
||||
for r in rules:
|
||||
if r.SCOPE == "type":
|
||||
|
||||
def visit(nm):
|
||||
D[nm].append(r)
|
||||
for nm2 in subtypes[nm]:
|
||||
visit(nm2)
|
||||
|
||||
visit(r.TYPE_NAME)
|
||||
|
||||
def type_name(ty):
|
||||
if isinstance(ty, ifcopenshell.ifcopenshell_wrapper.named_type):
|
||||
return type_name(ty.declared_type())
|
||||
elif isinstance(ty, ifcopenshell.ifcopenshell_wrapper.aggregation_type):
|
||||
# breakpoint()
|
||||
pass
|
||||
elif isinstance(ty, ifcopenshell.ifcopenshell_wrapper.simple_type):
|
||||
pass
|
||||
else:
|
||||
return ty.name()
|
||||
|
||||
def check(value, type, instance):
|
||||
if value is None:
|
||||
return
|
||||
|
||||
if type_name(type) in D:
|
||||
for R in D[type_name(type)]:
|
||||
try:
|
||||
R()(fix_type(value))
|
||||
except RecursionError as e:
|
||||
logger.info(str(e))
|
||||
except Exception as e:
|
||||
ln = e.__traceback__.tb_next.tb_lineno
|
||||
pre_annotate_instance(instance)
|
||||
pre_annotate_attribute(f"{R.TYPE_NAME}.{R.RULE_NAME}")
|
||||
logger.error(
|
||||
str(
|
||||
error(
|
||||
post_annotate_attribute(f"{R.TYPE_NAME}.{R.RULE_NAME}"),
|
||||
reverse_compile(source.split("\n")[ln - 1]),
|
||||
reverse_compile(e.args[0]),
|
||||
post_annotate_instance(instance),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# @nb something can be a named type with rules and still be an aggregation.
|
||||
# case in point IfcCompoundPlaneAngleMeasure. Therefore only unpack named
|
||||
# type references from this point onwards.
|
||||
while isinstance(
|
||||
type,
|
||||
(
|
||||
ifcopenshell.ifcopenshell_wrapper.named_type,
|
||||
ifcopenshell.ifcopenshell_wrapper.type_declaration,
|
||||
),
|
||||
):
|
||||
type = type.declared_type()
|
||||
|
||||
if isinstance(value, (list, tuple)):
|
||||
if isinstance(type, ifcopenshell.ifcopenshell_wrapper.aggregation_type):
|
||||
ty = type.type_of_element()
|
||||
for v in value:
|
||||
check(v, ty, instance=inst)
|
||||
else:
|
||||
# Let's hope a schema validation error was reported for this case
|
||||
pass
|
||||
|
||||
elif isinstance(value, ifcopenshell.entity_instance):
|
||||
if isinstance(
|
||||
S.declaration_by_name(value.is_a()),
|
||||
ifcopenshell.ifcopenshell_wrapper.entity,
|
||||
):
|
||||
# top level entity instances will be checked on their own
|
||||
pass
|
||||
else:
|
||||
# unpack the type instance
|
||||
check(value[0], S.declaration_by_name(value.is_a()), instance=inst)
|
||||
|
||||
for inst in f:
|
||||
try:
|
||||
values = list(inst)
|
||||
except RecursionError as e:
|
||||
logger.info(str(e))
|
||||
except Exception as e:
|
||||
if hasattr(logger, "set_state"):
|
||||
logger.error(str(e))
|
||||
else:
|
||||
logger.error("For instance:\n %s\n%s", inst, e)
|
||||
continue
|
||||
entity = S.declaration_by_name(inst.is_a())
|
||||
attrs = entity.all_attributes()
|
||||
for i, (attr, val, is_derived) in enumerate(zip(attrs, values, entity.derived())):
|
||||
if is_derived:
|
||||
# @todo
|
||||
pass
|
||||
else:
|
||||
check(val, attr.type_of_attribute(), instance=inst)
|
||||
|
||||
if hasattr(logger, "set_state"):
|
||||
logger.set_state("type", "entity_rule")
|
||||
|
||||
for R in [r for r in rules if r.SCOPE == "entity"]:
|
||||
for inst in f.by_type(R.TYPE_NAME):
|
||||
try:
|
||||
R()(inst)
|
||||
except RecursionError as e:
|
||||
logger.info(str(e))
|
||||
except Exception as e:
|
||||
ln = e.__traceback__.tb_next.tb_lineno
|
||||
pre_annotate_instance(inst)
|
||||
pre_annotate_attribute(f"{R.TYPE_NAME}.{R.RULE_NAME}")
|
||||
logger.error(
|
||||
str(
|
||||
error(
|
||||
post_annotate_attribute(f"{R.TYPE_NAME}.{R.RULE_NAME}"),
|
||||
reverse_compile(source.split("\n")[ln - 1]),
|
||||
reverse_compile(e.args[0]),
|
||||
post_annotate_instance(inst),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
ifcopenshell.settings.unpack_non_aggregate_inverses = orig
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
import json
|
||||
import logging
|
||||
import ifcopenshell
|
||||
from ifcopenshell.validate import json_logger
|
||||
|
||||
filenames = [x for x in sys.argv[1:] if not x.startswith("--")]
|
||||
flags = set(x for x in sys.argv[1:] if x.startswith("--"))
|
||||
|
||||
for fn in filenames:
|
||||
if "--json" in flags:
|
||||
logger = json_logger()
|
||||
else:
|
||||
logger = logging.getLogger("validate")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
f = ifcopenshell.open(fn)
|
||||
|
||||
run(f, logger)
|
||||
|
||||
if "--json" in flags:
|
||||
print("\n".join(json.dumps(x, default=str) for x in logger.statements))
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,185 @@
|
||||
@ECHO OFF
|
||||
|
||||
:: python bootstrap.py express.bnf > express_parser.py
|
||||
|
||||
IF EXIST IFC2X3_TC1.exp (
|
||||
python express_parser.py IFC2X3_TC1.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc2x3-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3.cpp txt/header_ifc2x3.txt Ifc2x3.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3.h txt/header_ifc2x3.txt Ifc2x3.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3-schema.cpp txt/header_ifc2x3.txt Ifc2x3-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3-definitions.h txt/header_ifc2x3.txt Ifc2x3-definitions.h
|
||||
) ELSE (
|
||||
:: v0.5.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3.cpp txt/header_ifc2x3.txt txt/ifndef_ifc4.txt Ifc2x3.cpp txt/endif.txt
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3.h txt/header_ifc2x3.txt Ifc2x3.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3enum.h txt/header_ifc2x3.txt Ifc2x3enum.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3-latebound.cpp txt/header_ifc2x3.txt txt/ifndef_ifc4.txt Ifc2x3-latebound.cpp txt/endif.txt
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc2x3-latebound.h txt/header_ifc2x3.txt Ifc2x3-latebound.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4_ADD2TC1.exp (
|
||||
python express_parser.py IFC4_ADD2TC1.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4.cpp txt/header_ifc4.txt Ifc4.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4.h txt/header_ifc4.txt Ifc4.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4-schema.cpp txt/header_ifc4.txt Ifc4-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4-definitions.h txt/header_ifc4.txt Ifc4-definitions.h
|
||||
) ELSE (
|
||||
:: v0.5.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4.cpp txt/header_ifc4.txt txt/ifdef_ifc4.txt Ifc4.cpp txt/endif.txt
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4.h txt/header_ifc4.txt Ifc4.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4enum.h txt/header_ifc4.txt Ifc4enum.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4-latebound.cpp txt/header_ifc4.txt txt/ifdef_ifc4.txt Ifc4-latebound.cpp txt/endif.txt
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4-latebound.h txt/header_ifc4.txt Ifc4-latebound.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4x1.exp (
|
||||
python express_parser.py IFC4x1.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x1-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x1.cpp txt/header_ifc4x1.txt Ifc4x1.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x1.h txt/header_ifc4x1.txt Ifc4x1.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x1-schema.cpp txt/header_ifc4x1.txt Ifc4x1-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x1-definitions.h txt/header_ifc4x1.txt Ifc4x1-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4x2.exp (
|
||||
python express_parser.py IFC4x2.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x2-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x2.cpp txt/header_ifc4x2.txt Ifc4x2.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x2.h txt/header_ifc4x2.txt Ifc4x2.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x2-schema.cpp txt/header_ifc4x2.txt Ifc4x2-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x2-definitions.h txt/header_ifc4x2.txt Ifc4x2-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4x3_RC1.exp (
|
||||
python express_parser.py IFC4x3_RC1.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x3_rc1-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc1.cpp txt/header_ifc4x3_rc1.txt Ifc4x3_rc1.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc1.h txt/header_ifc4x3_rc1.txt Ifc4x3_rc1.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc1-schema.cpp txt/header_ifc4x3_rc1.txt Ifc4x3_rc1-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc1-definitions.h txt/header_ifc4x3_rc1.txt Ifc4x3_rc1-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4x3_RC2.exp (
|
||||
python express_parser.py IFC4x3_RC2.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x3_rc2-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc2.cpp txt/header_ifc4x3_rc2.txt Ifc4x3_rc2.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc2.h txt/header_ifc4x3_rc2.txt Ifc4x3_rc2.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc2-schema.cpp txt/header_ifc4x3_rc2.txt Ifc4x3_rc2-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc2-definitions.h txt/header_ifc4x3_rc2.txt Ifc4x3_rc2-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4x3_RC3.exp (
|
||||
python express_parser.py IFC4x3_RC3.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x3_rc3-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc3.cpp txt/header_ifc4x3_rc2.txt Ifc4x3_rc3.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc3.h txt/header_ifc4x3_rc2.txt Ifc4x3_rc3.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc3-schema.cpp txt/header_ifc4x3_rc2.txt Ifc4x3_rc3-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc3-definitions.h txt/header_ifc4x3_rc2.txt Ifc4x3_rc3-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4x3_RC4.exp (
|
||||
python express_parser.py IFC4x3_RC4.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x3_rc4-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc4.cpp txt/header_ifc4x3_rc2.txt Ifc4x3_rc4.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc4.h txt/header_ifc4x3_rc2.txt Ifc4x3_rc4.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc4-schema.cpp txt/header_ifc4x3_rc2.txt Ifc4x3_rc4-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_rc4-definitions.h txt/header_ifc4x3_rc2.txt Ifc4x3_rc4-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4X3.exp (
|
||||
python express_parser.py IFC4X3.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x3-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3.cpp txt/header_ifc4x3_rc2.txt Ifc4x3.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3.h txt/header_ifc4x3_rc2.txt Ifc4x3.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3-schema.cpp txt/header_ifc4x3_rc2.txt Ifc4x3-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3-definitions.h txt/header_ifc4x3_rc2.txt Ifc4x3-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4X3_TC1.exp (
|
||||
python express_parser.py IFC4X3_TC1.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x3_tc1-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_tc1.cpp txt/header_ifc4x3_tc1.txt Ifc4x3_tc1.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_tc1.h txt/header_ifc4x3_tc1.txt Ifc4x3_tc1.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_tc1-schema.cpp txt/header_ifc4x3_tc1.txt Ifc4x3_tc1-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_tc1-definitions.h txt/header_ifc4x3_tc1.txt Ifc4x3_tc1-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4X3_ADD1.exp (
|
||||
python express_parser.py IFC4X3_ADD1.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x3_add1-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_add1.cpp txt/header_ifc4x3_add1.txt Ifc4x3_add1.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_add1.h txt/header_ifc4x3_add1.txt Ifc4x3_add1.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_add1-schema.cpp txt/header_ifc4x3_add1.txt Ifc4x3_add1-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_add1-definitions.h txt/header_ifc4x3_add1.txt Ifc4x3_add1-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
|
||||
IF EXIST IFC4X3_ADD2.exp (
|
||||
python express_parser.py IFC4X3_ADD2.exp header implementation schema_class definitions
|
||||
|
||||
IF EXIST Ifc4x3_add2-schema.cpp (
|
||||
:: v0.6.0
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_add2.cpp txt/header_ifc4x3_add2.txt Ifc4x3_add2.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_add2.h txt/header_ifc4x3_add2.txt Ifc4x3_add2.h
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_add2-schema.cpp txt/header_ifc4x3_add2.txt Ifc4x3_add2-schema.cpp
|
||||
python cat.py -o ..\..\..\ifcparse\Ifc4x3_add2-definitions.h txt/header_ifc4x3_add2.txt Ifc4x3_add2-definitions.h
|
||||
)
|
||||
|
||||
del *.cpp *.h
|
||||
)
|
||||
@@ -0,0 +1,122 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import nodes
|
||||
import platform
|
||||
import collections
|
||||
import pyparsing
|
||||
|
||||
if tuple(map(int, platform.python_version_tuple())) < (2, 7):
|
||||
import ordereddict
|
||||
|
||||
collections.OrderedDict = ordereddict.OrderedDict
|
||||
|
||||
|
||||
# According to ISO 10303-11 7.1.2: Letters: "... The case of
|
||||
# letters is significant only within explicit string literals."
|
||||
class OrderedCaseInsensitiveDict_KeyObject(str):
|
||||
def __eq__(self, other):
|
||||
return self.lower() == other.lower()
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.lower())
|
||||
|
||||
|
||||
class OrderedCaseInsensitiveDict(collections.OrderedDict):
|
||||
def __init__(self, *args, **kwargs):
|
||||
collections.OrderedDict.__init__(self)
|
||||
for key, value in collections.OrderedDict(*args, **kwargs).items():
|
||||
self[OrderedCaseInsensitiveDict_KeyObject(key)] = value
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
return collections.OrderedDict.__setitem__(self, OrderedCaseInsensitiveDict_KeyObject(key), value)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return collections.OrderedDict.__getitem__(self, OrderedCaseInsensitiveDict_KeyObject(key))
|
||||
|
||||
def get(self, key, *args, **kwargs):
|
||||
return collections.OrderedDict.get(self, OrderedCaseInsensitiveDict_KeyObject(key), *args, **kwargs)
|
||||
|
||||
def __contains__(self, key):
|
||||
return collections.OrderedDict.__contains__(self, OrderedCaseInsensitiveDict_KeyObject(key))
|
||||
|
||||
def __delitem__(self, key):
|
||||
return collections.OrderedDict.__delitem__(self, OrderedCaseInsensitiveDict_KeyObject(key))
|
||||
|
||||
|
||||
class Schema:
|
||||
def is_enumeration(self, v):
|
||||
return str(v) in self.enumerations
|
||||
|
||||
def is_select(self, v):
|
||||
return str(v) in self.selects
|
||||
|
||||
def is_simpletype(self, v):
|
||||
return str(v) in self.simpletypes
|
||||
|
||||
def is_type(self, v):
|
||||
return str(v) in self.types
|
||||
|
||||
def is_entity(self, v):
|
||||
return str(v) in self.entities
|
||||
|
||||
def __len__(self):
|
||||
return len(self.keys)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.keys)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.all_declarations[OrderedCaseInsensitiveDict_KeyObject(key)]
|
||||
|
||||
def __init__(self, parsetree: pyparsing.ParseResults):
|
||||
self.tree = parsetree
|
||||
schema = next(iter(parsetree.syntax[0]))
|
||||
self.name = schema.simple_id
|
||||
schema_declarations = list(schema.schema_body[0])
|
||||
|
||||
sort = lambda d: OrderedCaseInsensitiveDict(sorted(d))
|
||||
|
||||
declarations = [d.any()[0] for d in schema_declarations if d.rule == "declaration"] + [
|
||||
d for d in schema_declarations if d.rule == "RuleDeclaration"
|
||||
]
|
||||
|
||||
self.types = sort([(t.name, t) for t in declarations if isinstance(t, nodes.TypeDeclaration)])
|
||||
self.entities = sort([(t.name, t) for t in declarations if isinstance(t, nodes.EntityDeclaration)])
|
||||
self.rules = sort([(t.name, t) for t in declarations if isinstance(t, nodes.RuleDeclaration)])
|
||||
self.functions = sort([(t.name, t) for t in declarations if isinstance(t, nodes.FunctionDeclaration)])
|
||||
|
||||
self.keys = (
|
||||
list(self.types.keys()) + list(self.entities.keys()) + list(self.rules.keys()) + list(self.functions.keys())
|
||||
)
|
||||
self.all_declarations = {
|
||||
k: v for d in (self.types, self.entities, self.rules, self.functions) for k, v in d.items()
|
||||
}
|
||||
|
||||
of_type = lambda *types: sort(
|
||||
[(a, b.type) for a, b in self.types.items() if any(isinstance(b.type, ty) for ty in types)]
|
||||
)
|
||||
|
||||
self.enumerations = of_type(nodes.EnumerationType)
|
||||
self.selects = of_type(nodes.SelectType)
|
||||
self.simpletypes = of_type(
|
||||
str, nodes.AggregationType, nodes.BinaryType, nodes.StringType, nodes.SimpleType, nodes.NamedType
|
||||
)
|
||||
|
||||
assert len(self.enumerations) + len(self.selects) + len(self.simpletypes) == len(self.types)
|
||||
@@ -0,0 +1,588 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import operator
|
||||
import re
|
||||
|
||||
import nodes
|
||||
import codegen
|
||||
import templates
|
||||
import mapping
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
try:
|
||||
import ifcopenshell.ifcopenshell_wrapper as w
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
class LateBoundSchemaInstantiator:
|
||||
def __init__(self, schema_name):
|
||||
self.schema_name = schema_name
|
||||
self.schema_name_title = schema_name.capitalize()
|
||||
self.declarations = {}
|
||||
self.names = []
|
||||
# We need to make sure anonymous types are not gc'ed.
|
||||
self.cache = []
|
||||
|
||||
def aggregation_type(self, aggr_type, bound1, bound2, decl_type):
|
||||
self.cache.append(
|
||||
w.aggregation_type(getattr(w.aggregation_type, aggr_type + "_type"), bound1, bound2, decl_type)
|
||||
)
|
||||
return self.cache[-1]
|
||||
|
||||
def simple_type(self, type):
|
||||
self.cache.append(w.simple_type(getattr(w.simple_type, type + "_type")))
|
||||
return self.cache[-1]
|
||||
|
||||
def named_type(self, type):
|
||||
self.cache.append(w.named_type(self.declarations[str(type)]))
|
||||
return self.cache[-1]
|
||||
|
||||
def declare(self, definition_type, name):
|
||||
self.names.append(str(name))
|
||||
|
||||
def begin_schema(self):
|
||||
self.names.sort(key=str.lower)
|
||||
|
||||
def typedef(self, name, declared_type):
|
||||
index_in_schema = self.names.index(str(name))
|
||||
self.declarations[str(name)] = w.type_declaration(name, index_in_schema, declared_type)
|
||||
|
||||
def enumeration(self, name, enum):
|
||||
schema_name = self.schema_name
|
||||
index_in_schema = self.names.index(str(name))
|
||||
self.declarations[str(name)] = w.enumeration_type(name, index_in_schema, enum.values)
|
||||
|
||||
def entity(self, name, type):
|
||||
index_in_schema = self.names.index(str(name))
|
||||
supertype = None if len(type.supertypes) == 0 else self.declarations[str(type.supertypes[0])]
|
||||
self.declarations[str(name)] = w.entity(name, type.abstract, index_in_schema, supertype)
|
||||
|
||||
def select(self, name, type):
|
||||
index_in_schema = self.names.index(str(name))
|
||||
children = [self.declarations[str(v)] for v in type.values]
|
||||
self.declarations[str(name)] = w.select_type(name, index_in_schema, children)
|
||||
|
||||
def entity_attributes(self, name, attribute_definitions, is_derived):
|
||||
attributes = []
|
||||
for attr_name, decl_type, optional in attribute_definitions:
|
||||
attributes.append(w.attribute(attr_name, decl_type, optional))
|
||||
self.declarations[str(name)].set_attributes(attributes, is_derived)
|
||||
self.cache.extend(attributes)
|
||||
|
||||
def inverse_attributes(self, name, inv_attrs):
|
||||
attributes = []
|
||||
for attr_name, aggr_type, bound1, bound2, entity_ref, attribute_entity, attribute_entity_index in inv_attrs:
|
||||
en = self.declarations[str(entity_ref)]
|
||||
attributes.append(
|
||||
w.inverse_attribute(
|
||||
attr_name,
|
||||
getattr(w.inverse_attribute, aggr_type + "_type"),
|
||||
bound1,
|
||||
bound2,
|
||||
en,
|
||||
en.attributes()[attribute_entity_index],
|
||||
)
|
||||
)
|
||||
self.cache.extend(attributes)
|
||||
self.declarations[str(name)].set_inverse_attributes(attributes)
|
||||
|
||||
def entity_subtypes(self, name, tys):
|
||||
self.declarations[str(name)].set_subtypes([self.declarations[str(v)] for v in tys])
|
||||
|
||||
def finalize(self, can_be_instantiated_set, override_schema_name=None):
|
||||
self.schema = w.schema_definition(
|
||||
override_schema_name or self.schema_name, list(self.declarations.values()), None
|
||||
)
|
||||
|
||||
def disown(self):
|
||||
for elem in self.cache + list(self.declarations.values()):
|
||||
elem.this.disown()
|
||||
|
||||
|
||||
class string_pool:
|
||||
def __init__(self, fn):
|
||||
self.di = {}
|
||||
self.fn = fn
|
||||
|
||||
def append(self, v):
|
||||
def _():
|
||||
if i := self.di.get(v):
|
||||
return i
|
||||
else:
|
||||
i = len(self.di)
|
||||
self.di[v] = i
|
||||
return i
|
||||
|
||||
return self.fn(_())
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.di.keys())
|
||||
|
||||
|
||||
class EarlyBoundCodeWriter:
|
||||
def __init__(self, schema_name):
|
||||
self.strings = string_pool(lambda i: "strings[%d]" % i)
|
||||
self.schema_name = schema_name
|
||||
self.schema_name_title = schema_name.capitalize()
|
||||
|
||||
self.statements = [
|
||||
"",
|
||||
'#include "../ifcparse/IfcSchema.h"',
|
||||
'#include "../ifcparse/%(schema_name_title)s.h"' % self.__dict__,
|
||||
"#include <string>",
|
||||
"",
|
||||
"using namespace std::string_literals;",
|
||||
"using namespace IfcParse;",
|
||||
"",
|
||||
]
|
||||
|
||||
self.names = []
|
||||
|
||||
def aggregation_type(self, aggr_type, bound1, bound2, decl_type):
|
||||
return (
|
||||
"new aggregation_type(aggregation_type::%(aggr_type)s_type, %(bound1)d, %(bound2)d, %(decl_type)s)"
|
||||
% locals()
|
||||
)
|
||||
|
||||
def simple_type(self, type):
|
||||
return "new simple_type(simple_type::%s_type)" % type
|
||||
|
||||
def named_type(self, type):
|
||||
return "new named_type(%s_%s_type)" % (self.schema_name, type)
|
||||
|
||||
def declare(self, definition_type, name):
|
||||
schema_name = self.schema_name
|
||||
# self.statements.append("%(definition_type)s* %(schema_name)s_%(name)s_type = 0;" % locals())
|
||||
self.names.append(name)
|
||||
|
||||
def begin_schema(self):
|
||||
self.names.sort(key=str.lower)
|
||||
schema_name = self.schema_name.upper()
|
||||
num_names = len(self.names)
|
||||
self.statements.append("declaration* %(schema_name)s_types[%(num_names)d] = {nullptr};" % locals())
|
||||
|
||||
self.statements.append("{factory_placeholder}")
|
||||
|
||||
# self.statements.append(
|
||||
# """
|
||||
# #if defined(__clang__)
|
||||
# __attribute__((optnone))
|
||||
# #elif defined(__GNUC__) || defined(__GNUG__)
|
||||
# #pragma GCC push_options
|
||||
# #pragma GCC optimize ("O0")
|
||||
# #elif defined(_MSC_VER)
|
||||
# #pragma optimize("", off)
|
||||
# #endif
|
||||
# """
|
||||
# )
|
||||
self.statements.append("IfcParse::schema_definition* %s_populate_schema() {" % self.schema_name.upper())
|
||||
self.statements.append("{string_pool_placeholder}")
|
||||
|
||||
def typedef(self, name, declared_type):
|
||||
schema_name = self.schema_name.upper()
|
||||
index_in_schema = self.names.index(name)
|
||||
ref = self.strings.append(name)
|
||||
self.statements.append(
|
||||
" %(schema_name)s_types[%(index_in_schema)d] = new type_declaration(%(ref)s, %(index_in_schema)d, %(declared_type)s);"
|
||||
% locals()
|
||||
)
|
||||
|
||||
def enumeration(self, name, enum):
|
||||
schema_name = self.schema_name.upper()
|
||||
index_in_schema = self.names.index(name)
|
||||
ref = self.strings.append(name)
|
||||
items = ",".join(self.strings.append(v) for v in enum.values)
|
||||
self.statements.append(
|
||||
" %(schema_name)s_types[%(index_in_schema)d] = new enumeration_type(%(ref)s, %(index_in_schema)d, {%(items)s});"
|
||||
% locals()
|
||||
)
|
||||
|
||||
def entity(self, name, type):
|
||||
schema_name = self.schema_name.upper()
|
||||
index_in_schema = self.names.index(name)
|
||||
ref = self.strings.append(name)
|
||||
supertype = (
|
||||
"0"
|
||||
if len(type.supertypes) == 0
|
||||
else "%s_types[%d]" % (self.schema_name, self.names.index(type.supertypes[0]))
|
||||
)
|
||||
is_abstract = "true" if type.abstract else "false"
|
||||
self.statements.append(
|
||||
" %(schema_name)s_types[%(index_in_schema)d] = new entity(%(ref)s, %(is_abstract)s, %(index_in_schema)d, (entity*) %(supertype)s);"
|
||||
% locals()
|
||||
)
|
||||
|
||||
def select(self, name, type):
|
||||
schema_name = self.schema_name.upper()
|
||||
index_in_schema = self.names.index(name)
|
||||
ref = self.strings.append(name)
|
||||
items = ",".join(
|
||||
map(lambda v: "%s_types[%d]" % (self.schema_name, self.names.index(v)), sorted(map(str, type.values)))
|
||||
)
|
||||
self.statements.append(
|
||||
" %(schema_name)s_types[%(index_in_schema)d] = new select_type(%(ref)s, %(index_in_schema)d, {%(items)s});"
|
||||
% locals()
|
||||
)
|
||||
|
||||
def entity_attributes(self, name, attribute_definitions, is_derived):
|
||||
schema_name = self.schema_name.upper()
|
||||
index_in_schema = self.names.index(name)
|
||||
|
||||
def _():
|
||||
index_in_schema = self.names.index(name)
|
||||
schema_name = self.schema_name
|
||||
for attr_name, decl_type, optional in attribute_definitions:
|
||||
attr_name_ref = self.strings.append(attr_name)
|
||||
optional_cpp = str(optional).lower()
|
||||
yield "new attribute(%(attr_name_ref)s, %(decl_type)s, %(optional_cpp)s)" % locals()
|
||||
|
||||
attributes = ",".join(_())
|
||||
derived = ",".join(map(lambda b: str(b).lower(), is_derived))
|
||||
self.statements.append(
|
||||
" ((entity*)%(schema_name)s_types[%(index_in_schema)d])->set_attributes({%(attributes)s}, {%(derived)s});"
|
||||
% locals()
|
||||
)
|
||||
|
||||
def inverse_attributes(self, name, inv_attrs):
|
||||
schema_name = self.schema_name.upper()
|
||||
index_in_schema = self.names.index(name)
|
||||
|
||||
def _():
|
||||
schema_name = self.schema_name
|
||||
index_in_schema = self.names.index(name)
|
||||
for attr_name, aggr_type, bound1, bound2, entity_ref, attribute_entity, attribute_entity_index in inv_attrs:
|
||||
attr_name_ref = self.strings.append(attr_name)
|
||||
opposite_index_in_schema = self.names.index(entity_ref)
|
||||
opposite1 = "%(schema_name)s_types[%(opposite_index_in_schema)d]" % locals()
|
||||
opposite_index_in_schema = self.names.index(attribute_entity)
|
||||
opposite2 = "%(schema_name)s_types[%(opposite_index_in_schema)d]" % locals()
|
||||
yield "new inverse_attribute(%(attr_name_ref)s, inverse_attribute::%(aggr_type)s_type, %(bound1)d, %(bound2)d, ((entity*) %(opposite1)s), ((entity*) %(opposite2)s)->attributes()[%(attribute_entity_index)d])" % locals()
|
||||
|
||||
attributes = ",".join(_())
|
||||
self.statements.append(
|
||||
" ((entity*) %(schema_name)s_types[%(index_in_schema)d])->set_inverse_attributes({%(attributes)s});"
|
||||
% locals()
|
||||
)
|
||||
|
||||
def entity_subtypes(self, name, tys):
|
||||
schema_name = self.schema_name.upper()
|
||||
index_in_schema = self.names.index(name)
|
||||
subtypes = (
|
||||
",".join(map(lambda t: ("((entity*) %%(schema_name)s_types[%d])" % self.names.index(t)), tys)) % locals()
|
||||
)
|
||||
self.statements.append(
|
||||
" ((entity*) %(schema_name)s_types[%(index_in_schema)d])->set_subtypes({%(subtypes)s});" % locals()
|
||||
)
|
||||
|
||||
def finalize(self, can_be_instantiated_set):
|
||||
schema_name = self.schema_name.upper()
|
||||
schema_name_title = self.schema_name.capitalize()
|
||||
|
||||
def _():
|
||||
schema_name = self.schema_name.upper()
|
||||
schema_name_title = self.schema_name.capitalize()
|
||||
for type_name in self.names:
|
||||
index_in_schema = self.names.index(type_name)
|
||||
yield "%(schema_name)s_types[%(index_in_schema)d]" % locals()
|
||||
|
||||
declarations = ",".join(_())
|
||||
schema_name_ref = self.strings.append(schema_name)
|
||||
self.statements.append(
|
||||
" return new schema_definition(%(schema_name_ref)s, {%(declarations)s}, new %(schema_name)s_instance_factory());"
|
||||
% locals()
|
||||
)
|
||||
self.statements.append("}")
|
||||
|
||||
# self.statements.append(
|
||||
# """
|
||||
# #if defined(__clang__)
|
||||
# #elif defined(__GNUC__) || defined(__GNUG__)
|
||||
# #pragma GCC pop_options
|
||||
# #elif defined(_MSC_VER)
|
||||
# #pragma optimize("", on)
|
||||
# #endif
|
||||
# """
|
||||
# )
|
||||
|
||||
self.statements.extend(
|
||||
(
|
||||
"static std::unique_ptr<schema_definition> schema;",
|
||||
"",
|
||||
"void %s::clear_schema() {" % schema_name_title,
|
||||
" schema.reset();",
|
||||
"}",
|
||||
"",
|
||||
)
|
||||
)
|
||||
|
||||
self.statements.extend(
|
||||
(
|
||||
"const schema_definition& %s::get_schema() {" % schema_name_title,
|
||||
" if (!schema) {",
|
||||
" schema.reset(%(schema_name)s_populate_schema());" % locals(),
|
||||
" }",
|
||||
" return *schema;",
|
||||
"}",
|
||||
"",
|
||||
"",
|
||||
)
|
||||
)
|
||||
|
||||
def can_be_instantiated(idx_name):
|
||||
name = idx_name[1]
|
||||
return name in can_be_instantiated_set
|
||||
|
||||
instance_mapping = """switch(decl->index_in_schema()) {
|
||||
%s
|
||||
default: throw IfcParse::IfcException(decl->name() + " cannot be instantiated");
|
||||
}
|
||||
""" % "\n ".join(
|
||||
map(
|
||||
lambda tup: ("case %%d: return new ::%s::%%s(std::move(data));" % schema_name_title) % tup,
|
||||
filter(can_be_instantiated, enumerate(self.names)),
|
||||
)
|
||||
)
|
||||
|
||||
self.statements[self.statements.index("{factory_placeholder}")] = """
|
||||
class %(schema_name)s_instance_factory : public IfcParse::instance_factory {
|
||||
virtual IfcUtil::IfcBaseClass* operator()(const IfcParse::declaration* decl, IfcEntityInstanceData&& data) const {
|
||||
%(instance_mapping)s
|
||||
}
|
||||
};
|
||||
""" % locals()
|
||||
|
||||
""
|
||||
self.statements[self.statements.index("{string_pool_placeholder}")] = """
|
||||
const std::string strings[] = {%s};
|
||||
""" % ",".join(map(lambda s: '"%s"s' % s, self.strings))
|
||||
|
||||
def __str__(self):
|
||||
return "\n".join(self.statements)
|
||||
|
||||
|
||||
class SchemaClass(codegen.Base):
|
||||
def __init__(self, mapping: mapping.Mapping, code=EarlyBoundCodeWriter):
|
||||
class UnmetDependenciesException(Exception):
|
||||
pass
|
||||
|
||||
schema_name = mapping.schema.name
|
||||
self.schema_name = schema_name_title = schema_name.capitalize()
|
||||
|
||||
declared_types = []
|
||||
|
||||
x = code(schema_name)
|
||||
|
||||
def transform_to_indexed(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
schema_name_upper = mapping.schema.name.upper()
|
||||
declared_type = fn(*args, **kwargs)
|
||||
if "simple_type" in declared_type:
|
||||
pass
|
||||
else:
|
||||
match = re.search(r"\((\w+?_[\w+]+?_\w+?)\)", declared_type)
|
||||
if match:
|
||||
old_decl = match.group(1)
|
||||
name = old_decl.lower().replace(schema_name.lower() + "_", "").replace("_type", "")
|
||||
idx = [n.lower() for n in x.names].index(name)
|
||||
declared_type = declared_type.replace(
|
||||
old_decl, "%(schema_name_upper)s_types[%(idx)d]" % locals()
|
||||
)
|
||||
return declared_type
|
||||
|
||||
return wrapper if code == EarlyBoundCodeWriter else fn
|
||||
|
||||
@transform_to_indexed
|
||||
def get_declared_type(type, emitted_names=None):
|
||||
if isinstance(type, nodes.SimpleType):
|
||||
type = type.type
|
||||
if isinstance(type, nodes.NamedType):
|
||||
type = str(type)
|
||||
|
||||
if isinstance(type, nodes.AggregationType):
|
||||
aggr_type = type.aggregate_type
|
||||
make_bound = lambda b: -1 if b == "?" else int(b)
|
||||
bound1, bound2 = map(make_bound, (type.bounds.lower, type.bounds.upper))
|
||||
decl_type = get_declared_type(type.type, emitted_names)
|
||||
return x.aggregation_type(aggr_type, bound1, bound2, decl_type)
|
||||
elif isinstance(type, nodes.BinaryType):
|
||||
return x.simple_type("binary")
|
||||
elif isinstance(type, nodes.StringType):
|
||||
return x.simple_type("string")
|
||||
elif isinstance(type, str):
|
||||
if mapping.schema.is_type(type) or mapping.schema.is_entity(type):
|
||||
if emitted_names is None or type.lower() in emitted_names:
|
||||
return x.named_type(type)
|
||||
else:
|
||||
raise UnmetDependenciesException(type)
|
||||
else:
|
||||
return x.simple_type(type)
|
||||
else:
|
||||
raise ValueError("No declared type for <%r>" % type)
|
||||
|
||||
def find_inverse_name_and_index(entity_name, attribute_name):
|
||||
entity_name_orig = entity_name
|
||||
attributes_per_subtype = []
|
||||
while True:
|
||||
entity = mapping.schema.entities[entity_name]
|
||||
attr_names = list(map(operator.attrgetter("name"), entity.attributes))
|
||||
if len(attr_names):
|
||||
attributes_per_subtype.append((entity_name, attr_names))
|
||||
if len(entity.supertypes) != 1:
|
||||
break
|
||||
entity_name = entity.supertypes[0]
|
||||
index = 0
|
||||
for et, attrs in attributes_per_subtype[::-1]:
|
||||
try:
|
||||
return et, attrs.index(attribute_name)
|
||||
except:
|
||||
pass
|
||||
|
||||
else:
|
||||
raise Exception("No attribute named %s.%s" % (entity_name_orig, attribute_name))
|
||||
|
||||
collections_by_type = (
|
||||
("entity", mapping.schema.entities),
|
||||
("type_declaration", mapping.schema.simpletypes),
|
||||
("select_type", mapping.schema.selects),
|
||||
("enumeration_type", mapping.schema.enumerations),
|
||||
)
|
||||
|
||||
for definition_type, collection in collections_by_type:
|
||||
for name in collection.keys():
|
||||
x.declare(definition_type, name)
|
||||
|
||||
declarations_by_index = []
|
||||
|
||||
x.begin_schema()
|
||||
|
||||
emitted = set()
|
||||
len_to_emit = len(mapping.schema) - len(mapping.schema.rules) - len(mapping.schema.functions)
|
||||
|
||||
def write_simpletype(schema_name, name, type):
|
||||
try:
|
||||
declared_type = get_declared_type(type, emitted)
|
||||
except UnmetDependenciesException:
|
||||
# @todo?
|
||||
# print("Unmet", repr(name))
|
||||
return False
|
||||
|
||||
x.typedef(name, declared_type)
|
||||
|
||||
def write_enumeration(schema_name, name, enum):
|
||||
x.enumeration(name, enum)
|
||||
|
||||
def write_entity(schema_name, name, type):
|
||||
if len(type.supertypes) == 0 or set(map(lambda s: s.lower(), type.supertypes)) < emitted:
|
||||
x.entity(name, type)
|
||||
else:
|
||||
return False
|
||||
|
||||
def write_select(schema_name, name, type):
|
||||
if set(map(lambda s: str(s).lower(), type.values)) < emitted:
|
||||
x.select(name, type)
|
||||
else:
|
||||
return False
|
||||
|
||||
def write(name):
|
||||
if mapping.schema.is_simpletype(name):
|
||||
fn = write_simpletype
|
||||
elif mapping.schema.is_enumeration(name):
|
||||
fn = write_enumeration
|
||||
elif mapping.schema.is_entity(name):
|
||||
fn = write_entity
|
||||
elif mapping.schema.is_select(name):
|
||||
fn = write_select
|
||||
elif name in mapping.schema.rules:
|
||||
return
|
||||
elif name in mapping.schema.functions:
|
||||
return
|
||||
|
||||
decl = mapping.schema[name]
|
||||
if isinstance(decl, nodes.TypeDeclaration):
|
||||
decl = decl.type
|
||||
return fn(schema_name, name, decl) is not False
|
||||
|
||||
while len(emitted) < len_to_emit:
|
||||
for name in mapping.schema:
|
||||
if name.lower() in emitted:
|
||||
continue
|
||||
if write(name):
|
||||
emitted.add(name.lower())
|
||||
declarations_by_index.append(name)
|
||||
|
||||
num_declarations = len(emitted)
|
||||
|
||||
for name, type in mapping.schema.entities.items():
|
||||
derived = set(mapping.derived_in_supertype(type))
|
||||
attribute_names = list(map(operator.attrgetter("name"), mapping.arguments(type)))
|
||||
is_derived = [b in derived for b in attribute_names]
|
||||
attribute_definitions = []
|
||||
for attr in type.attributes:
|
||||
decl_type = get_declared_type(attr.type)
|
||||
attribute_definitions.append((attr.name, decl_type, attr.optional))
|
||||
x.entity_attributes(name, attribute_definitions, is_derived)
|
||||
|
||||
for name, type in mapping.schema.entities.items():
|
||||
if type.inverse:
|
||||
inv_attrs = []
|
||||
for attr in type.inverse:
|
||||
if attr.bounds:
|
||||
make_bound = lambda b: -1 if b == "?" else int(b)
|
||||
bound1, bound2 = map(make_bound, (attr.bounds.lower, attr.bounds.upper))
|
||||
else:
|
||||
bound1, bound2 = -1, -1
|
||||
attr_name, aggr_type, entity_ref = attr.name, attr.type, attr.entity
|
||||
if aggr_type is None:
|
||||
aggr_type = "unspecified"
|
||||
attribute_entity, attribute_entity_index = find_inverse_name_and_index(entity_ref, attr.attribute)
|
||||
inv_attrs.append(
|
||||
(attr_name, aggr_type, bound1, bound2, entity_ref, attribute_entity, attribute_entity_index)
|
||||
)
|
||||
x.inverse_attributes(name, inv_attrs)
|
||||
|
||||
subtypes = defaultdict(list)
|
||||
|
||||
for name, type in mapping.schema.entities.items():
|
||||
for ty in type.supertypes:
|
||||
subtypes[ty].append(name)
|
||||
|
||||
for name, tys in subtypes.items():
|
||||
x.entity_subtypes(name, tys)
|
||||
|
||||
can_be_instantiated_set = set(
|
||||
list(mapping.schema.entities.keys())
|
||||
+ list(mapping.schema.simpletypes.keys())
|
||||
+ list(mapping.schema.enumerations.keys())
|
||||
)
|
||||
|
||||
x.finalize(can_be_instantiated_set)
|
||||
|
||||
self.str = str(x)
|
||||
self.file_name = "%s-schema.cpp" % self.schema_name
|
||||
self.code = x
|
||||
|
||||
def __repr__(self):
|
||||
return self.str
|
||||
|
||||
|
||||
Generator = SchemaClass
|
||||
@@ -0,0 +1,275 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Thomas Krijnen <thomas@aecgeeks.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
header = """
|
||||
#ifndef %(schema_name_upper)s_H
|
||||
#define %(schema_name_upper)s_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include "../ifcparse/ifc_parse_api.h"
|
||||
|
||||
#include "../ifcparse/aggregate_of_instance.h"
|
||||
#include "../ifcparse/IfcBaseClass.h"
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/Argument.h"
|
||||
|
||||
struct %(schema_name)s {
|
||||
|
||||
IFC_PARSE_API static const IfcParse::schema_definition& get_schema();
|
||||
|
||||
IFC_PARSE_API static void clear_schema();
|
||||
|
||||
static const char* const Identifier;
|
||||
|
||||
// Forward definitions
|
||||
%(forward_definitions)s
|
||||
|
||||
%(declarations)s
|
||||
|
||||
%(class_definitions)s
|
||||
};
|
||||
|
||||
#endif
|
||||
"""
|
||||
|
||||
enum_header = """
|
||||
#ifndef %(schema_name_upper)sENUM_H
|
||||
#define %(schema_name_upper)sENUM_H
|
||||
|
||||
#include "../ifcparse/ifc_parse_api.h"
|
||||
|
||||
#include <string>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#endif
|
||||
"""
|
||||
|
||||
lb_header = """"""
|
||||
|
||||
implementation = """
|
||||
#include "../ifcparse/%(schema_name)s.h"
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
const char* const %(schema_name)s::Identifier = "%(schema_name_upper)s";
|
||||
|
||||
using namespace IfcParse;
|
||||
|
||||
// External definitions
|
||||
%(external_definitions)s
|
||||
|
||||
%(enumeration_functions)s
|
||||
|
||||
%(simple_type_impl)s
|
||||
|
||||
%(entity_implementations)s
|
||||
"""
|
||||
|
||||
lb_implementation = """"""
|
||||
|
||||
entity_descriptor = """ current = entity_descriptor_map[Type::%(type)s] = new IfcEntityDescriptor(Type::%(type)s,%(parent_statement)s);
|
||||
%(entity_descriptor_attributes)s"""
|
||||
|
||||
entity_descriptor_parent = "entity_descriptor_map.find(Type::%(type)s)->second"
|
||||
entity_descriptor_attribute_without_entity = ' current->add("%(name)s",%(optional)s,%(type)s);'
|
||||
entity_descriptor_attribute_with_entity = ' current->add("%(name)s",%(optional)s,%(type)s,Type::%(entity_name)s);'
|
||||
|
||||
enumeration_descriptor = """ values.clear(); values.reserve(128);
|
||||
%(enumeration_descriptor_values)s
|
||||
enumeration_descriptor_map[Type::%(type)s] = new IfcEnumerationDescriptor(Type::%(type)s, values);"""
|
||||
|
||||
enumeration_descriptor_value = ' values.push_back("%(name)s");'
|
||||
|
||||
derived_field_statement = " {std::set<int> idxs; %(statements)sderived_map[Type::%(type)s] = idxs;}"
|
||||
derived_field_statement_attrs = "idxs.insert(%d); "
|
||||
|
||||
simpletype = """%(documentation)s
|
||||
class IFC_PARSE_API %(name)s : %(superclass)s {
|
||||
public:
|
||||
virtual const IfcParse::type_declaration& declaration() const;
|
||||
static const IfcParse::type_declaration& Class();
|
||||
explicit %(name)s (IfcEntityInstanceData&& e);
|
||||
%(name)s (%(type)s v);
|
||||
operator %(type)s() const;
|
||||
};
|
||||
"""
|
||||
|
||||
simpletype_impl_comment = "// Function implementations for %(name)s"
|
||||
simpletype_impl_argument_type = 'if (i == 0) { return %(attr_type)s; } else { throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); }'
|
||||
simpletype_impl_argument = "return get_attribute_value(i);"
|
||||
simpletype_impl_is_with_supertype = "return v == %(class_name)s_type || %(superclass)s::is(v);"
|
||||
simpletype_impl_is_without_supertype = "return v == %(class_name)s_type;"
|
||||
simpletype_impl_type = "return *((IfcParse::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);"
|
||||
simpletype_impl_class = "return *((IfcParse::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);"
|
||||
simpletype_impl_explicit_constructor = "data_ = e;"
|
||||
simpletype_impl_constructor = (
|
||||
"data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]); set_attribute_value(0, v);"
|
||||
)
|
||||
simpletype_impl_constructor_templated = "data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]); set_attribute_value(0, v->generalize());"
|
||||
simpletype_impl_cast = "return get_attribute_value(0);"
|
||||
simpletype_impl_cast_templated = (
|
||||
"aggregate_of_instance::ptr es = get_attribute_value(0); return es->as< %(underlying_type)s >();"
|
||||
)
|
||||
simpletype_impl_declaration = "return *((IfcParse::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);"
|
||||
|
||||
select_virtual = """%(documentation)s
|
||||
class IFC_PARSE_API %(name)s : public virtual IfcUtil::IfcBaseInterface {
|
||||
public:
|
||||
static const IfcParse::select_type& Class();
|
||||
typedef aggregate_of< %(name)s > list;
|
||||
};
|
||||
"""
|
||||
|
||||
select_plain = """%(documentation)s
|
||||
typedef IfcUtil::IfcBaseClass %(name)s;
|
||||
"""
|
||||
|
||||
enumeration = """class IFC_PARSE_API %(name)s : public IfcUtil::IfcBaseType {
|
||||
%(documentation)s
|
||||
public:
|
||||
typedef enum {%(values)s} Value;
|
||||
static const char* ToString(Value v);
|
||||
static Value FromString(const std::string& s);
|
||||
|
||||
virtual const IfcParse::enumeration_type& declaration() const;
|
||||
static const IfcParse::enumeration_type& Class();
|
||||
%(name)s (IfcEntityInstanceData&& e);
|
||||
%(name)s (Value v);
|
||||
%(name)s (const std::string& v);
|
||||
operator Value() const;
|
||||
};
|
||||
"""
|
||||
|
||||
entity = """%(documentation)s
|
||||
class IFC_PARSE_API %(name)s : %(superclass)s {
|
||||
public:
|
||||
%(attributes)s %(inverse)s virtual const IfcParse::entity& declaration() const;
|
||||
static const IfcParse::entity& Class();
|
||||
%(name)s (IfcEntityInstanceData&& e);
|
||||
%(name)s (%(constructor_arguments)s);
|
||||
typedef aggregate_of< %(name)s > list;
|
||||
};
|
||||
"""
|
||||
|
||||
select_function = """
|
||||
const IfcParse::select_type& %(schema_name)s::%(name)s::Class() { return *((IfcParse::select_type*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
"""
|
||||
|
||||
enumeration_function = """
|
||||
const IfcParse::enumeration_type& %(schema_name)s::%(name)s::declaration() const { return *((IfcParse::enumeration_type*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
const IfcParse::enumeration_type& %(schema_name)s::%(name)s::Class() { return *((IfcParse::enumeration_type*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
|
||||
%(schema_name)s::%(name)s::%(name)s(IfcEntityInstanceData&& e)
|
||||
: IfcBaseType(std::move(e))
|
||||
{}
|
||||
|
||||
%(schema_name)s::%(name)s::%(name)s(Value v) {
|
||||
set_attribute_value(0, EnumerationReference(&declaration(), static_cast<size_t>(v)));
|
||||
}
|
||||
|
||||
%(schema_name)s::%(name)s::%(name)s(const std::string& v) {
|
||||
set_attribute_value(0, EnumerationReference(&declaration(), declaration().lookup_enum_offset(v)));
|
||||
}
|
||||
|
||||
const char* %(schema_name)s::%(name)s::ToString(Value v) {
|
||||
return %(schema_name)s::%(name)s::%(name)s::Class().lookup_enum_value((size_t)v);
|
||||
}
|
||||
|
||||
%(schema_name)s::%(name)s::Value %(schema_name)s::%(name)s::FromString(const std::string& s) {
|
||||
return (%(schema_name)s::%(name)s::Value) %(schema_name)s::%(name)s::%(name)s::Class().lookup_enum_offset(s);
|
||||
}
|
||||
|
||||
%(schema_name)s::%(name)s::operator %(schema_name)s::%(name)s::Value() const {
|
||||
return (%(schema_name)s::%(name)s::Value) ((EnumerationReference) get_attribute_value(0)).index();
|
||||
}
|
||||
"""
|
||||
|
||||
entity_implementation = """// Function implementations for %(name)s
|
||||
%(attributes)s
|
||||
%(inverse)s
|
||||
const IfcParse::entity& %(schema_name)s::%(name)s::declaration() const { return *((IfcParse::entity*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
const IfcParse::entity& %(schema_name)s::%(name)s::Class() { return *((IfcParse::entity*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
%(schema_name)s::%(name)s::%(name)s(IfcEntityInstanceData&& e) : %(superclass)s { }
|
||||
%(schema_name)s::%(name)s::%(name)s(%(constructor_arguments)s) : %(superclass_num_attrs)s { %(constructor_implementation)s; populate_derived(); }
|
||||
"""
|
||||
|
||||
# data_ = e;
|
||||
# data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]);
|
||||
|
||||
optional_attribute_description = "/// Whether the optional attribute %s is defined for this %s"
|
||||
|
||||
function = "%(return_type)s %(schema_name)s::%(class_name)s::%(name)s(%(arguments)s) { %(body)s }"
|
||||
const_function = "%(return_type)s %(schema_name)s::%(class_name)s::%(name)s(%(arguments)s) const { %(body)s }"
|
||||
constructor = "%(schema_name)s::%(class_name)s::%(class_name)s(%(arguments)s) { %(body)s }"
|
||||
constructor_single_initlist = (
|
||||
"%(schema_name)s::%(class_name)s::%(class_name)s(%(arguments)s) : %(superclass)s(%(superclass_init)s) { %(body)s }"
|
||||
)
|
||||
cast_function = "%(schema_name)s::%(class_name)s::operator %(return_type)s() const { %(body)s }"
|
||||
|
||||
array_type = "std::vector< %(instance_type)s > /*[%(lower)s:%(upper)s]*/"
|
||||
nested_array_type = "std::vector< std::vector< %(instance_type)s > >"
|
||||
list_type = "aggregate_of< %(instance_type)s >::ptr"
|
||||
list_list_type = "aggregate_of_aggregate_of< %(instance_type)s >::ptr"
|
||||
untyped_list = "aggregate_of_instance::ptr"
|
||||
inverse_attr = "aggregate_of< %(entity)s >::ptr %(name)s() const; // INVERSE %(entity)s::%(attribute)s"
|
||||
|
||||
enum_from_string_stmt = ' if (s == "%(value)s") return ::%(schema_name)s::%(name)s::%(short_name)s_%(value)s;'
|
||||
|
||||
schema_entity_stmt = " case Type::%(name)s: return new %(name)s(e); break;"
|
||||
string_map_statement = ' string_map["%(uppercase_name)s"%(padding)s] = Type::%(name)s;'
|
||||
parent_type_stmt = " if(v==%(name)s%(padding)s) { return %(parent)s; }"
|
||||
|
||||
parent_type_test = " || %s::is(v)"
|
||||
|
||||
optional_attr_stmt = "return !get_attribute_value(%(index)d).isNull();"
|
||||
|
||||
get_attr_stmt = "%(null_check)s %(non_optional_type)s v = get_attribute_value(%(index)d); return v;"
|
||||
get_attr_stmt_enum = "%(null_check)s return %(non_optional_type)s::FromString(get_attribute_value(%(index)d));"
|
||||
get_attr_stmt_entity = "%(null_check)s return ((IfcUtil::IfcBaseClass*)(get_attribute_value(%(index)d)))->as<%(non_optional_type_no_pointer)s>(true);"
|
||||
get_attr_stmt_array = "%(null_check)s aggregate_of_instance::ptr es = get_attribute_value(%(index)d); return es->as< %(list_instance_type)s >();"
|
||||
get_attr_stmt_nested_array = "%(null_check)s aggregate_of_aggregate_of_instance::ptr es = get_attribute_value(%(index)d); return es->as< %(list_instance_type)s >();"
|
||||
|
||||
get_inverse = "if (!file_) { return nullptr; } return file_->getInverse(id_, %(schema_name_upper)s_types[%(type_index)d], %(index)d)->as<%(type)s>();"
|
||||
|
||||
set_attr_stmt = "%(check_optional_set_begin)sset_attribute_value(%(index)d, %(star_if_optional)sv);%(check_optional_set_else)sunset_attribute_value(%(index)d);%(check_optional_set_end)s"
|
||||
set_attr_instance = "%(check_optional_set_begin)sset_attribute_value(%(index)d, v->as<IfcUtil::IfcBaseClass>());%(check_optional_set_else)sunset_attribute_value(%(index)d);%(check_optional_set_end)s"
|
||||
set_attr_stmt_enum = "%(check_optional_set_begin)sset_attribute_value(%(index)d, EnumerationReference(&%(non_optional_type)s::Class(), (size_t) %(star_if_optional)sv));%(check_optional_set_else)sunset_attribute_value(%(index)d);%(check_optional_set_end)s"
|
||||
set_attr_stmt_array = "%(check_optional_set_begin)sset_attribute_value(%(index)d, (%(star_if_optional)sv)->generalize());%(check_optional_set_else)sunset_attribute_value(%(index)d);%(check_optional_set_end)s"
|
||||
|
||||
constructor_stmt = "set_attribute_value(%(index)d, (%(name)s));"
|
||||
constructor_stmt_enum = "set_attribute_value(%(index)d, (EnumerationReference(&%(type)s::Class(),(size_t)%(name)s)));"
|
||||
constructor_stmt_array = "set_attribute_value(%(index)d, (%(name)s)->generalize());"
|
||||
constructor_stmt_derived = ""
|
||||
constructor_stmt_instance = "set_attribute_value(%(index)d, %(name)s ? %(name)s->as<IfcUtil::IfcBaseClass>() : (IfcUtil::IfcBaseClass*) nullptr);"
|
||||
|
||||
constructor_stmt_optional = " if (%(name)s) {%(stmt)s }"
|
||||
|
||||
inverse_implementation = ' inverse_map[Type::%(type)s].insert(std::make_pair("%(name)s", std::make_pair(Type::%(related_type)s, %(index)d)));'
|
||||
|
||||
|
||||
def multi_line_comment(li):
|
||||
return ("/// %s" % ("\n/// ".join(li))) if len(li) else ""
|
||||
@@ -0,0 +1 @@
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC2X3_TC1.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4x1.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4x2.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4X3_ADD1.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4X3_ADD2.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4x3_RC1.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4x3_RC2.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,25 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell 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 *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4X3_TC1.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
#ifdef USE_IFC4
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
#ifdef USE_IFC4X1
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
#ifndef USE_IFC4
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
#ifndef USE_IFC4X1
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
#ifndef USE_IFC4X1
|
||||
Reference in New Issue
Block a user