Merge remote-tracking branch 'origin/v0.7.0' into v0.8.0

This commit is contained in:
Thomas Krijnen
2023-03-29 12:55:05 +02:00
977 changed files with 317352 additions and 64693 deletions
@@ -29,11 +29,9 @@ 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)
import express_parser
import schema_class
import ifcopenshell.ifcopenshell_wrapper
def parse(fn):
import express_parser
import schema_class
mapping = express_parser.parse(fn)
return schema_class.SchemaClass(mapping, schema_class.LateBoundSchemaInstantiator).code
@@ -151,6 +151,8 @@ actions = {
"string_type": "StringType",
"named_types": "NamedType",
"simple_types": "SimpleType",
"function_decl": "FunctionDeclaration",
"rule_decl": "RuleDeclaration",
}
to_emit = set(id for id, expr in express)
@@ -192,7 +194,9 @@ for id in to_emit:
if id in to_combine:
stmt = "Suppress%s" % stmt
if id not in no_action and not isinstance(expr.contents, Keyword):
node_type = "ListNode" if "ZeroOrMore" in stmt else "Node"
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)
)
@@ -16,6 +16,18 @@
# 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(object):
"""
@@ -152,7 +152,7 @@ def parse(fn):
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("abstract") + ~CaselessKeyword("reference") + ~CaselessKeyword("pi") + ~CaselessKeyword("andor") + ~CaselessKeyword("loindex") + ~CaselessKeyword("aggregate") + ~CaselessKeyword("self") + ~CaselessKeyword("length") + ~CaselessKeyword("optional") + ~CaselessKeyword("for") + ~CaselessKeyword("end") + ~CaselessKeyword("local") + ~CaselessKeyword("true") + ~CaselessKeyword("logical") + ~CaselessKeyword("constant") + ~CaselessKeyword("nvl") + ~CaselessKeyword("bag") + ~CaselessKeyword("repeat") + ~CaselessKeyword("boolean") + ~CaselessKeyword("otherwise") + ~CaselessKeyword("type") + ~CaselessKeyword("typeof") + ~CaselessKeyword("alias") + ~CaselessKeyword("in") + ~CaselessKeyword("mod") + ~CaselessKeyword("escape") + ~CaselessKeyword("or") + ~CaselessKeyword("of") + ~CaselessKeyword("like") + ~CaselessKeyword("value_unique") + ~CaselessKeyword("tan") + ~CaselessKeyword("oneof") + ~CaselessKeyword("log") + ~CaselessKeyword("schema") + ~CaselessKeyword("fixed") + ~CaselessKeyword("by") + ~CaselessKeyword("integer") + ~CaselessKeyword("div") + ~CaselessKeyword("log10") + ~CaselessKeyword("not") + ~CaselessKeyword("skip") + ~CaselessKeyword("odd") + ~CaselessKeyword("return") + ~CaselessKeyword("end_subtype_constraint") + ~CaselessKeyword("end_alias") + ~CaselessKeyword("remove") + ~CaselessKeyword("unknown") + ~CaselessKeyword("end_repeat") + ~CaselessKeyword("enumeration") + ~CaselessKeyword("query") + ~CaselessKeyword("function") + ~CaselessKeyword("list") + ~CaselessKeyword("end_local") + ~CaselessKeyword("cos") + ~CaselessKeyword("atan") + ~CaselessKeyword("hibound") + ~CaselessKeyword("rolesof") + ~CaselessKeyword("end_function") + ~CaselessKeyword("abs") + ~CaselessKeyword("renamed") + ~CaselessKeyword("select") + ~CaselessKeyword("end_if") + ~CaselessKeyword("case") + ~CaselessKeyword("sizeof") + ~CaselessKeyword("var") + ~CaselessKeyword("end_case") + ~CaselessKeyword("acos") + ~CaselessKeyword("supertype") + ~CaselessKeyword("then") + ~CaselessKeyword("inverse") + ~CaselessKeyword("hiindex") + ~CaselessKeyword("false") + ~CaselessKeyword("generic") + ~CaselessKeyword("as") + ~CaselessKeyword("use") + ~CaselessKeyword("end_entity") + ~CaselessKeyword("rule") + ~CaselessKeyword("derive") + ~CaselessKeyword("set") + ~CaselessKeyword("subtype") + ~CaselessKeyword("unique") + ~CaselessKeyword("subtype_constraint") + ~CaselessKeyword("where") + ~CaselessKeyword("until") + ~CaselessKeyword("usedin") + ~CaselessKeyword("value") + ~CaselessKeyword("array") + ~CaselessKeyword("sqrt") + ~CaselessKeyword("value_in") + ~CaselessKeyword("to") + ~CaselessKeyword("xor") + ~CaselessKeyword("sin") + ~CaselessKeyword("while") + ~CaselessKeyword("with") + ~CaselessKeyword("string") + ~CaselessKeyword("total_over") + ~CaselessKeyword("binary") + ~CaselessKeyword("exp") + ~CaselessKeyword("and") + ~CaselessKeyword("number") + ~CaselessKeyword("generic_entity") + ~CaselessKeyword("const_e") + ~CaselessKeyword("end_type") + ~CaselessKeyword("log2") + ~CaselessKeyword("lobound") + ~CaselessKeyword("end_procedure") + ~CaselessKeyword("end_schema") + ~CaselessKeyword("end_constant") + ~CaselessKeyword("procedure") + ~CaselessKeyword("else") + ~CaselessKeyword("end_rule") + ~CaselessKeyword("if") + ~CaselessKeyword("based_on") + ~CaselessKeyword("exists") + ~CaselessKeyword("asin") + ~CaselessKeyword("blength") + ~CaselessKeyword("entity") + ~CaselessKeyword("from") + ~CaselessKeyword("format") + ~CaselessKeyword("insert") + ~CaselessKeyword("begin") + ~CaselessKeyword("extensible") + ~CaselessKeyword("real") + originalTextFor(Combine((letter + ZeroOrMore((letter | digit | CaselessLiteral("_"))))))("simple_id")
simple_id = ~CaselessKeyword("bag") + ~CaselessKeyword("lobound") + ~CaselessKeyword("aggregate") + ~CaselessKeyword("reference") + ~CaselessKeyword("abstract") + ~CaselessKeyword("value_unique") + ~CaselessKeyword("if") + ~CaselessKeyword("loindex") + ~CaselessKeyword("format") + ~CaselessKeyword("true") + ~CaselessKeyword("insert") + ~CaselessKeyword("exp") + ~CaselessKeyword("end_type") + ~CaselessKeyword("end") + ~CaselessKeyword("optional") + ~CaselessKeyword("in") + ~CaselessKeyword("like") + ~CaselessKeyword("type") + ~CaselessKeyword("end_rule") + ~CaselessKeyword("repeat") + ~CaselessKeyword("nvl") + ~CaselessKeyword("otherwise") + ~CaselessKeyword("procedure") + ~CaselessKeyword("number") + ~CaselessKeyword("boolean") + ~CaselessKeyword("exists") + ~CaselessKeyword("andor") + ~CaselessKeyword("alias") + ~CaselessKeyword("entity") + ~CaselessKeyword("constant") + ~CaselessKeyword("tan") + ~CaselessKeyword("or") + ~CaselessKeyword("oneof") + ~CaselessKeyword("from") + ~CaselessKeyword("escape") + ~CaselessKeyword("typeof") + ~CaselessKeyword("extensible") + ~CaselessKeyword("div") + ~CaselessKeyword("then") + ~CaselessKeyword("by") + ~CaselessKeyword("unknown") + ~CaselessKeyword("var") + ~CaselessKeyword("pi") + ~CaselessKeyword("inverse") + ~CaselessKeyword("skip") + ~CaselessKeyword("array") + ~CaselessKeyword("end_subtype_constraint") + ~CaselessKeyword("use") + ~CaselessKeyword("self") + ~CaselessKeyword("end_alias") + ~CaselessKeyword("select") + ~CaselessKeyword("for") + ~CaselessKeyword("sizeof") + ~CaselessKeyword("fixed") + ~CaselessKeyword("local") + ~CaselessKeyword("remove") + ~CaselessKeyword("enumeration") + ~CaselessKeyword("end_local") + ~CaselessKeyword("not") + ~CaselessKeyword("function") + ~CaselessKeyword("cos") + ~CaselessKeyword("logical") + ~CaselessKeyword("query") + ~CaselessKeyword("atan") + ~CaselessKeyword("return") + ~CaselessKeyword("schema") + ~CaselessKeyword("hiindex") + ~CaselessKeyword("rolesof") + ~CaselessKeyword("log10") + ~CaselessKeyword("end_function") + ~CaselessKeyword("abs") + ~CaselessKeyword("length") + ~CaselessKeyword("renamed") + ~CaselessKeyword("acos") + ~CaselessKeyword("end_case") + ~CaselessKeyword("case") + ~CaselessKeyword("mod") + ~CaselessKeyword("end_if") + ~CaselessKeyword("list") + ~CaselessKeyword("end_repeat") + ~CaselessKeyword("generic") + ~CaselessKeyword("of") + ~CaselessKeyword("supertype") + ~CaselessKeyword("false") + ~CaselessKeyword("end_entity") + ~CaselessKeyword("odd") + ~CaselessKeyword("integer") + ~CaselessKeyword("hibound") + ~CaselessKeyword("rule") + ~CaselessKeyword("as") + ~CaselessKeyword("derive") + ~CaselessKeyword("log") + ~CaselessKeyword("set") + ~CaselessKeyword("subtype_constraint") + ~CaselessKeyword("unique") + ~CaselessKeyword("value") + ~CaselessKeyword("subtype") + ~CaselessKeyword("until") + ~CaselessKeyword("with") + ~CaselessKeyword("sqrt") + ~CaselessKeyword("where") + ~CaselessKeyword("value_in") + ~CaselessKeyword("to") + ~CaselessKeyword("xor") + ~CaselessKeyword("sin") + ~CaselessKeyword("while") + ~CaselessKeyword("string") + ~CaselessKeyword("usedin") + ~CaselessKeyword("total_over") + ~CaselessKeyword("binary") + ~CaselessKeyword("and") + ~CaselessKeyword("end_schema") + ~CaselessKeyword("generic_entity") + ~CaselessKeyword("end_constant") + ~CaselessKeyword("const_e") + ~CaselessKeyword("based_on") + ~CaselessKeyword("else") + ~CaselessKeyword("asin") + ~CaselessKeyword("blength") + ~CaselessKeyword("real") + ~CaselessKeyword("end_procedure") + ~CaselessKeyword("log2") + ~CaselessKeyword("begin") + 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")
@@ -250,224 +250,224 @@ def parse(fn):
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")
list_type = Forward()("list_type")
parameter_type = Forward()("parameter_type")
qualifiable_factor = Forward()("qualifiable_factor")
supertype_expression = Forward()("supertype_expression")
precision_spec = Forward()("precision_spec")
element = Forward()("element")
subtype_constraint_decl = Forward()("subtype_constraint_decl")
derived_attr = Forward()("derived_attr")
general_bag_type = Forward()("general_bag_type")
aggregation_types = Forward()("aggregation_types")
entity_decl = Forward()("entity_decl")
rule_decl = Forward()("rule_decl")
numeric_expression = Forward()("numeric_expression")
increment = Forward()("increment")
supertype_constraint = Forward()("supertype_constraint")
concrete_types = Forward()("concrete_types")
remark = Forward()("remark")
width = Forward()("width")
index = Forward()("index")
selector = Forward()("selector")
simple_factor = Forward()("simple_factor")
actual_parameter_list = Forward()("actual_parameter_list")
general_set_type = Forward()("general_set_type")
declaration = Forward()("declaration")
repeat_stmt = Forward()("repeat_stmt")
until_control = Forward()("until_control")
supertype_factor = Forward()("supertype_factor")
one_of = Forward()("one_of")
stmt = Forward()("stmt")
general_aggregation_types = Forward()("general_aggregation_types")
procedure_call_stmt = Forward()("procedure_call_stmt")
repetition = Forward()("repetition")
case_action = Forward()("case_action")
inverse_attr = Forward()("inverse_attr")
aggregate_initializer = Forward()("aggregate_initializer")
bound_spec = Forward()("bound_spec")
interval_high = Forward()("interval_high")
algorithm_head = Forward()("algorithm_head")
real_type = Forward()("real_type")
case_stmt = Forward()("case_stmt")
constant_decl = Forward()("constant_decl")
alias_stmt = Forward()("alias_stmt")
function_head = Forward()("function_head")
interval_low = Forward()("interval_low")
aggregate_source = Forward()("aggregate_source")
query_expression = Forward()("query_expression")
derived_attr = Forward()("derived_attr")
width_spec = Forward()("width_spec")
interval_item = Forward()("interval_item")
subsuper = Forward()("subsuper")
array_type = Forward()("array_type")
primary = Forward()("primary")
case_label = Forward()("case_label")
index_1 = Forward()("index_1")
entity_constructor = Forward()("entity_constructor")
subtype_constraint_body = Forward()("subtype_constraint_body")
constant_body = Forward()("constant_body")
actual_parameter_list = Forward()("actual_parameter_list")
type_decl = Forward()("type_decl")
selector = Forward()("selector")
abstract_supertype_declaration = Forward()("abstract_supertype_declaration")
explicit_attr = Forward()("explicit_attr")
entity_body = Forward()("entity_body")
repeat_control = Forward()("repeat_control")
expression = Forward()("expression")
if_stmt = Forward()("if_stmt")
subtype_constraint = Forward()("subtype_constraint")
while_control = Forward()("while_control")
logical_expression = Forward()("logical_expression")
aggregate_type = Forward()("aggregate_type")
interval = Forward()("interval")
general_array_type = Forward()("general_array_type")
aggregation_types = Forward()("aggregation_types")
domain_rule = Forward()("domain_rule")
entity_constructor = Forward()("entity_constructor")
function_call = Forward()("function_call")
numeric_expression = Forward()("numeric_expression")
general_set_type = Forward()("general_set_type")
qualifier = Forward()("qualifier")
formal_parameter = Forward()("formal_parameter")
index_1 = Forward()("index_1")
underlying_type = Forward()("underlying_type")
instantiable_type = Forward()("instantiable_type")
supertype_rule = Forward()("supertype_rule")
generalized_types = Forward()("generalized_types")
local_variable = Forward()("local_variable")
schema_body = Forward()("schema_body")
general_list_type = Forward()("general_list_type")
assignment_stmt = Forward()("assignment_stmt")
bound_2 = Forward()("bound_2")
binary_type = Forward()("binary_type")
syntax = Forward()("syntax")
aggregate_source = Forward()("aggregate_source")
while_control = Forward()("while_control")
interval_low = Forward()("interval_low")
parameter = Forward()("parameter")
string_type = Forward()("string_type")
supertype_term = Forward()("supertype_term")
embedded_remark = Forward()("embedded_remark")
increment_control = Forward()("increment_control")
local_decl = Forward()("local_decl")
precision_spec = Forward()("precision_spec")
one_of = Forward()("one_of")
subtype_constraint_body = Forward()("subtype_constraint_body")
general_array_type = Forward()("general_array_type")
list_type = Forward()("list_type")
subtype_constraint_decl = Forward()("subtype_constraint_decl")
schema_decl = Forward()("schema_decl")
algorithm_head = Forward()("algorithm_head")
query_expression = Forward()("query_expression")
primary = Forward()("primary")
repeat_control = Forward()("repeat_control")
factor = Forward()("factor")
procedure_head = Forward()("procedure_head")
function_decl = Forward()("function_decl")
type_decl = Forward()("type_decl")
general_aggregation_types = Forward()("general_aggregation_types")
domain_rule = Forward()("domain_rule")
schema_decl = Forward()("schema_decl")
derive_clause = Forward()("derive_clause")
return_stmt = Forward()("return_stmt")
bag_type = Forward()("bag_type")
procedure_decl = Forward()("procedure_decl")
abstract_supertype_declaration = Forward()("abstract_supertype_declaration")
inverse_clause = Forward()("inverse_clause")
index_qualifier = Forward()("index_qualifier")
bound_1 = Forward()("bound_1")
compound_stmt = Forward()("compound_stmt")
set_type = Forward()("set_type")
where_clause = Forward()("where_clause")
qualifier = Forward()("qualifier")
entity_head = Forward()("entity_head")
stmt = Forward()("stmt")
index_2 = Forward()("index_2")
term = Forward()("term")
function_call = Forward()("function_call")
formal_parameter = Forward()("formal_parameter")
aggregate_type = Forward()("aggregate_type")
repeat_stmt = Forward()("repeat_stmt")
entity_body = Forward()("entity_body")
interval_high = Forward()("interval_high")
logical_expression = Forward()("logical_expression")
simple_expression = Forward()("simple_expression")
remark = Forward()("remark")
simple_factor = Forward()("simple_factor")
case_stmt = Forward()("case_stmt")
derive_clause = Forward()("derive_clause")
supertype_constraint = Forward()("supertype_constraint")
assignment_stmt = Forward()("assignment_stmt")
entity_head = Forward()("entity_head")
set_type = Forward()("set_type")
instantiable_type = Forward()("instantiable_type")
declaration = Forward()("declaration")
binary_type = Forward()("binary_type")
interval = Forward()("interval")
parameter_type = Forward()("parameter_type")
term = Forward()("term")
index = Forward()("index")
expression = Forward()("expression")
bag_type = Forward()("bag_type")
schema_body = Forward()("schema_body")
until_control = Forward()("until_control")
simple_types = Forward()("simple_types")
list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="list_type"))
parameter_type << (((generalized_types | simple_types | named_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="parameter_type"))
qualifiable_factor << (((function_call | attribute_ref | constant_factor | general_ref | population))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifiable_factor"))
supertype_expression << (((supertype_factor + ZeroOrMore((ANDOR + supertype_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_expression"))
precision_spec << (numeric_expression)
element << (((expression + Optional((CaselessLiteral(":") + repetition))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="element"))
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"))
derived_attr << (((attribute_decl + CaselessLiteral(":") + parameter_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="derived_attr"))
general_bag_type << (((BAG + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_bag_type"))
aggregation_types << (((array_type | bag_type | list_type | set_type))).setParseAction(AggregationType)
entity_decl << (((entity_head + entity_body + END_ENTITY + CaselessLiteral(";")))).setParseAction(EntityDeclaration)
rule_decl << (((rule_head + algorithm_head + ZeroOrMore(stmt) + where_clause + END_RULE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="rule_decl"))
numeric_expression << (simple_expression)
increment << (numeric_expression)
supertype_constraint << (((abstract_supertype_declaration | abstract_entity_declaration | supertype_rule))).setParseAction(SuperTypeExpression)
concrete_types << (((aggregation_types | simple_types | type_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="concrete_types"))
remark << (((embedded_remark | tail_remark))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="remark"))
width << (numeric_expression)
index << (numeric_expression)
selector << (expression)
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"))
actual_parameter_list << (((CaselessLiteral("(") + Optional(parameter) + ZeroOrMore((CaselessLiteral(",") + parameter)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="actual_parameter_list"))
general_set_type << (((SET + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_set_type"))
declaration << (((entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="declaration"))
repeat_stmt << (((REPEAT + repeat_control + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_REPEAT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="repeat_stmt"))
until_control << (((UNTIL + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="until_control"))
supertype_factor << (((supertype_term + ZeroOrMore((AND + supertype_term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_factor"))
one_of << (((ONEOF + CaselessLiteral("(") + supertype_expression + ZeroOrMore((CaselessLiteral(",") + supertype_expression)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="one_of"))
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"))
repetition << (numeric_expression)
case_action << (((case_label + ZeroOrMore((CaselessLiteral(",") + case_label)) + CaselessLiteral(":") + stmt))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_action"))
inverse_attr << (((attribute_decl + CaselessLiteral(":") + Optional(((SET | BAG) + Optional(bound_spec) + OF)) + entity_ref + FOR + Optional((entity_ref + CaselessLiteral("."))) + attribute_ref + CaselessLiteral(";")))).setParseAction(InverseAttribute)
aggregate_initializer << (((CaselessLiteral("[") + Optional((element + ZeroOrMore((CaselessLiteral(",") + element)))) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="aggregate_initializer"))
bound_spec << (((CaselessLiteral("[") + bound_1 + CaselessLiteral(":") + bound_2 + CaselessLiteral("]")))).setParseAction(BoundSpecification)
interval_high << (simple_expression)
algorithm_head << (((ZeroOrMore(declaration) + Optional(constant_decl) + Optional(local_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="algorithm_head"))
real_type << (((REAL + Optional((CaselessLiteral("(") + precision_spec + CaselessLiteral(")")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="real_type"))
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"))
constant_decl << (((CONSTANT + constant_body + ZeroOrMore(constant_body) + END_CONSTANT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="constant_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"))
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"))
interval_low << (simple_expression)
aggregate_source << (simple_expression)
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"))
width_spec << (((CaselessLiteral("(") + width + CaselessLiteral(")") + Optional(FIXED)))).setParseAction(WidthSpec)
interval_item << (simple_expression)
subsuper << (((Optional(supertype_constraint) + Optional(subtype_declaration)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subsuper"))
array_type << (((ARRAY + bound_spec + OF + Optional(OPTIONAL) + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="array_type"))
primary << (((literal | (qualifiable_factor + ZeroOrMore(qualifier))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="primary"))
case_label << (expression)
index_1 << (index)
entity_constructor << (((entity_ref + CaselessLiteral("(") + Optional((expression + ZeroOrMore((CaselessLiteral(",") + expression)))) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_constructor"))
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"))
constant_body << (((constant_id + CaselessLiteral(":") + instantiable_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constant_body"))
explicit_attr << (((attribute_decl + ZeroOrMore((CaselessLiteral(",") + attribute_decl)) + CaselessLiteral(":") + Optional(OPTIONAL) + parameter_type + CaselessLiteral(";")))).setParseAction(ExplicitAttribute)
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"))
repeat_control << (((Optional(increment_control) + Optional(while_control) + Optional(until_control)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="repeat_control"))
expression << (((simple_expression + Optional((rel_op_extended + simple_expression))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="expression"))
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"))
subtype_constraint << (((OF + CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint"))
while_control << (((WHILE + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="while_control"))
logical_expression << (expression)
aggregate_type << (((AGGREGATE + Optional((CaselessLiteral(":") + type_label)) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="aggregate_type"))
interval << (((CaselessLiteral("{") + interval_low + interval_op + interval_item + interval_op + interval_high + CaselessLiteral("}")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="interval"))
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"))
underlying_type << (((constructed_types | concrete_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="underlying_type"))
instantiable_type << (((concrete_types | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="instantiable_type"))
supertype_rule << (((SUPERTYPE + subtype_constraint))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_rule"))
generalized_types << (((aggregate_type | general_aggregation_types | generic_entity_type | generic_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generalized_types"))
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"))
schema_body << (((ZeroOrMore(interface_specification) + Optional(constant_decl) + ZeroOrMore((declaration | rule_decl))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="schema_body"))
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"))
assignment_stmt << (((general_ref + ZeroOrMore(qualifier) + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="assignment_stmt"))
bound_2 << (numeric_expression)
binary_type << (((BINARY + Optional(width_spec)))).setParseAction(BinaryType)
syntax << (((schema_decl + ZeroOrMore(schema_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="syntax"))
parameter << (expression)
string_type << (((STRING + Optional(width_spec)))).setParseAction(StringType)
supertype_term << (((one_of | (CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")) | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_term"))
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"))
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_decl << (((LOCAL + local_variable + ZeroOrMore(local_variable) + END_LOCAL + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_decl"))
factor << (((simple_factor + Optional((CaselessLiteral("**") + simple_factor))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="factor"))
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(lambda s, loc, t: ListNode(s, loc, t, rule="function_decl"))
type_decl << (((TYPE + type_id + CaselessLiteral("=") + underlying_type + CaselessLiteral(";") + Optional(where_clause) + END_TYPE + CaselessLiteral(";")))).setParseAction(TypeDeclaration)
general_aggregation_types << (((general_array_type | general_bag_type | general_list_type | general_set_type))).setParseAction(AggregationType)
domain_rule << (((Optional((rule_label_id + CaselessLiteral(":"))) + expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="domain_rule"))
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"))
derive_clause << (((DERIVE + derived_attr + ZeroOrMore(derived_attr)))).setParseAction(AttributeList)
return_stmt << (((RETURN + Optional((CaselessLiteral("(") + expression + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="return_stmt"))
bag_type << (((BAG + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="bag_type"))
procedure_decl << (((procedure_head + algorithm_head + ZeroOrMore(stmt) + END_PROCEDURE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_decl"))
abstract_supertype_declaration << (((ABSTRACT + SUPERTYPE + Optional(subtype_constraint)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype_declaration"))
inverse_clause << (((INVERSE + inverse_attr + ZeroOrMore(inverse_attr)))).setParseAction(AttributeList)
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)
compound_stmt << (((BEGIN + stmt + ZeroOrMore(stmt) + END + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="compound_stmt"))
set_type << (((SET + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="set_type"))
where_clause << (((WHERE + domain_rule + CaselessLiteral(";") + ZeroOrMore((domain_rule + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="where_clause"))
qualifier << (((attribute_qualifier | group_qualifier | index_qualifier))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifier"))
entity_head << (((ENTITY + entity_id + subsuper + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="entity_head"))
subsuper = Forward()("subsuper")
entity_decl = Forward()("entity_decl")
concrete_types = Forward()("concrete_types")
element = Forward()("element")
general_bag_type = Forward()("general_bag_type")
interval_item = Forward()("interval_item")
constant_body = Forward()("constant_body")
increment = Forward()("increment")
case_label = Forward()("case_label")
case_action = Forward()("case_action")
width = Forward()("width")
procedure_decl = Forward()("procedure_decl")
increment_control = Forward()("increment_control")
index_qualifier = Forward()("index_qualifier")
constant_decl = Forward()("constant_decl")
supertype_rule = Forward()("supertype_rule")
syntax = Forward()("syntax")
function_head = Forward()("function_head")
repetition = Forward()("repetition")
if_stmt = Forward()("if_stmt")
supertype_expression = Forward()("supertype_expression")
inverse_clause = Forward()("inverse_clause")
aggregate_initializer = Forward()("aggregate_initializer")
return_stmt = Forward()("return_stmt")
generalized_types = Forward()("generalized_types")
bound_2 = Forward()("bound_2")
real_type = Forward()("real_type")
index_2 = Forward()("index_2")
array_type = Forward()("array_type")
local_decl = Forward()("local_decl")
supertype_term = Forward()("supertype_term")
where_clause = Forward()("where_clause")
embedded_remark = Forward()("embedded_remark")
compound_stmt = Forward()("compound_stmt")
bound_1 = Forward()("bound_1")
alias_stmt = Forward()("alias_stmt")
subtype_constraint = Forward()("subtype_constraint")
string_type = Forward()("string_type")
function_decl = Forward()("function_decl")
general_list_type = Forward()("general_list_type")
supertype_factor = Forward()("supertype_factor")
rule_decl = Forward()("rule_decl")
qualifiable_factor = Forward()("qualifiable_factor")
bound_spec = Forward()("bound_spec")
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"))
index_2 << (index)
term << (((factor + ZeroOrMore((multiplication_like_op + factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="term"))
general_aggregation_types << (((general_array_type | general_bag_type | general_list_type | general_set_type))).setParseAction(AggregationType)
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"))
inverse_attr << (((attribute_decl + CaselessLiteral(":") + Optional(((SET | BAG) + Optional(bound_spec) + OF)) + entity_ref + FOR + Optional((entity_ref + CaselessLiteral("."))) + attribute_ref + CaselessLiteral(";")))).setParseAction(InverseAttribute)
derived_attr << (((attribute_decl + CaselessLiteral(":") + parameter_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="derived_attr"))
width_spec << (((CaselessLiteral("(") + width + CaselessLiteral(")") + Optional(FIXED)))).setParseAction(WidthSpec)
actual_parameter_list << (((CaselessLiteral("(") + Optional(parameter) + ZeroOrMore((CaselessLiteral(",") + parameter)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="actual_parameter_list"))
type_decl << (((TYPE + type_id + CaselessLiteral("=") + underlying_type + CaselessLiteral(";") + Optional(where_clause) + END_TYPE + CaselessLiteral(";")))).setParseAction(TypeDeclaration)
selector << (expression)
abstract_supertype_declaration << (((ABSTRACT + SUPERTYPE + Optional(subtype_constraint)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype_declaration"))
explicit_attr << (((attribute_decl + ZeroOrMore((CaselessLiteral(",") + attribute_decl)) + CaselessLiteral(":") + Optional(OPTIONAL) + parameter_type + CaselessLiteral(";")))).setParseAction(ExplicitAttribute)
aggregation_types << (((array_type | bag_type | list_type | set_type))).setParseAction(AggregationType)
domain_rule << (((Optional((rule_label_id + CaselessLiteral(":"))) + expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="domain_rule"))
entity_constructor << (((entity_ref + CaselessLiteral("(") + Optional((expression + ZeroOrMore((CaselessLiteral(",") + expression)))) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_constructor"))
function_call << ((((built_in_function | function_ref) + actual_parameter_list))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="function_call"))
numeric_expression << (simple_expression)
general_set_type << (((SET + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_set_type"))
qualifier << (((attribute_qualifier | group_qualifier | index_qualifier))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifier"))
formal_parameter << (((parameter_id + ZeroOrMore((CaselessLiteral(",") + parameter_id)) + CaselessLiteral(":") + parameter_type))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="formal_parameter"))
index_1 << (index)
underlying_type << (((constructed_types | concrete_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="underlying_type"))
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"))
aggregate_source << (simple_expression)
while_control << (((WHILE + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="while_control"))
interval_low << (simple_expression)
parameter << (expression)
precision_spec << (numeric_expression)
one_of << (((ONEOF + CaselessLiteral("(") + supertype_expression + ZeroOrMore((CaselessLiteral(",") + supertype_expression)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="one_of"))
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"))
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"))
list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="list_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"))
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"))
algorithm_head << (((ZeroOrMore(declaration) + Optional(constant_decl) + Optional(local_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="algorithm_head"))
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"))
primary << (((literal | (qualifiable_factor + ZeroOrMore(qualifier))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="primary"))
repeat_control << (((Optional(increment_control) + Optional(while_control) + Optional(until_control)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="repeat_control"))
factor << (((simple_factor + Optional((CaselessLiteral("**") + simple_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="factor"))
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"))
aggregate_type << (((AGGREGATE + Optional((CaselessLiteral(":") + type_label)) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="aggregate_type"))
repeat_stmt << (((REPEAT + repeat_control + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_REPEAT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="repeat_stmt"))
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"))
interval_high << (simple_expression)
logical_expression << (expression)
simple_expression << (((term + ZeroOrMore((add_like_op + term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="simple_expression"))
remark << (((embedded_remark | tail_remark))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="remark"))
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"))
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"))
derive_clause << (((DERIVE + derived_attr + ZeroOrMore(derived_attr)))).setParseAction(AttributeList)
supertype_constraint << (((abstract_supertype_declaration | abstract_entity_declaration | supertype_rule))).setParseAction(SuperTypeExpression)
assignment_stmt << (((general_ref + ZeroOrMore(qualifier) + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="assignment_stmt"))
entity_head << (((ENTITY + entity_id + subsuper + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="entity_head"))
set_type << (((SET + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="set_type"))
instantiable_type << (((concrete_types | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="instantiable_type"))
declaration << (((entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="declaration"))
binary_type << (((BINARY + Optional(width_spec)))).setParseAction(BinaryType)
interval << (((CaselessLiteral("{") + interval_low + interval_op + interval_item + interval_op + interval_high + CaselessLiteral("}")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="interval"))
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"))
index << (numeric_expression)
expression << (((simple_expression + Optional((rel_op_extended + simple_expression))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="expression"))
bag_type << (((BAG + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="bag_type"))
schema_body << (((ZeroOrMore(interface_specification) + Optional(constant_decl) + ZeroOrMore((declaration | rule_decl))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="schema_body"))
until_control << (((UNTIL + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="until_control"))
simple_types << (((binary_type | boolean_type | integer_type | logical_type | number_type | real_type | string_type))).setParseAction(SimpleType)
subsuper << (((Optional(supertype_constraint) + Optional(subtype_declaration)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subsuper"))
entity_decl << (((entity_head + entity_body + END_ENTITY + CaselessLiteral(";")))).setParseAction(EntityDeclaration)
concrete_types << (((aggregation_types | simple_types | type_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="concrete_types"))
element << (((expression + Optional((CaselessLiteral(":") + repetition))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="element"))
general_bag_type << (((BAG + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_bag_type"))
interval_item << (simple_expression)
constant_body << (((constant_id + CaselessLiteral(":") + instantiable_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constant_body"))
increment << (numeric_expression)
case_label << (expression)
case_action << (((case_label + ZeroOrMore((CaselessLiteral(",") + case_label)) + CaselessLiteral(":") + stmt))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_action"))
width << (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"))
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"))
index_qualifier << (((CaselessLiteral("[") + index_1 + Optional((CaselessLiteral(":") + index_2)) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="index_qualifier"))
constant_decl << (((CONSTANT + constant_body + ZeroOrMore(constant_body) + END_CONSTANT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="constant_decl"))
supertype_rule << (((SUPERTYPE + subtype_constraint))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_rule"))
syntax << (((schema_decl + ZeroOrMore(schema_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="syntax"))
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"))
repetition << (numeric_expression)
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"))
supertype_expression << (((supertype_factor + ZeroOrMore((ANDOR + supertype_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_expression"))
inverse_clause << (((INVERSE + inverse_attr + ZeroOrMore(inverse_attr)))).setParseAction(AttributeList)
aggregate_initializer << (((CaselessLiteral("[") + Optional((element + ZeroOrMore((CaselessLiteral(",") + element)))) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="aggregate_initializer"))
return_stmt << (((RETURN + Optional((CaselessLiteral("(") + expression + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="return_stmt"))
generalized_types << (((aggregate_type | general_aggregation_types | generic_entity_type | generic_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generalized_types"))
bound_2 << (numeric_expression)
real_type << (((REAL + Optional((CaselessLiteral("(") + precision_spec + CaselessLiteral(")")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="real_type"))
index_2 << (index)
array_type << (((ARRAY + bound_spec + OF + Optional(OPTIONAL) + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="array_type"))
local_decl << (((LOCAL + local_variable + ZeroOrMore(local_variable) + END_LOCAL + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_decl"))
supertype_term << (((one_of | (CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")) | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_term"))
where_clause << (((WHERE + domain_rule + CaselessLiteral(";") + ZeroOrMore((domain_rule + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="where_clause"))
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"))
compound_stmt << (((BEGIN + stmt + ZeroOrMore(stmt) + END + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="compound_stmt"))
bound_1 << (numeric_expression)
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"))
subtype_constraint << (((OF + CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint"))
string_type << (((STRING + Optional(width_spec)))).setParseAction(StringType)
function_decl << (((function_head + algorithm_head + stmt + ZeroOrMore(stmt) + END_FUNCTION + CaselessLiteral(";")))).setParseAction(FunctionDeclaration)
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"))
supertype_factor << (((supertype_term + ZeroOrMore((AND + supertype_term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_factor"))
rule_decl << (((rule_head + algorithm_head + ZeroOrMore(stmt) + where_clause + END_RULE + CaselessLiteral(";")))).setParseAction(RuleDeclaration)
qualifiable_factor << (((function_call | attribute_ref | constant_factor | general_ref | population))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifiable_factor"))
bound_spec << (((CaselessLiteral("[") + bound_1 + CaselessLiteral(":") + bound_2 + CaselessLiteral("]")))).setParseAction(BoundSpecification)
syntax.ignore("--" + restOfLine)
syntax.ignore(Regex(r"\((?:\*(?:[^*]*\*+)+?\))"))
@@ -24,6 +24,7 @@ import string
import operator
import collections
import bootstrap
class Node:
def __init__(self, s, loc, tokens, rule=None):
@@ -57,10 +58,18 @@ class ListNode:
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:
self.dict_tokens[r].append(t)
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):
@@ -68,9 +77,10 @@ class ListNode:
def __iter__(self):
return iter(self.tokens)
def __getitem__(self, i):
return self.tokens[i]
# 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
@@ -115,7 +125,7 @@ class TypeDeclaration(Node):
self.where = []
clause = self.where_clause
if clause:
clause = clause[0]
clause = list(clause[0])
self.where = [(r.simple_id, format_clause(r.expression[0])) for r in clause[1::2]]
@@ -170,7 +180,7 @@ class EntityDeclaration(Node):
self.where = []
clause = [r for r in self.entity_body[0] if r.rule == "where_clause"]
if clause:
clause = clause[0]
clause = list(clause[0])
self.where = [(r.simple_id, format_clause(r.expression[0])) for r in clause[1::2]]
@@ -178,7 +188,7 @@ class EntityDeclaration(Node):
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 clause[1::2]]
self.unique = [(r[0], r[2].simple_id) for r in map(list, list(clause)[1::2])]
def __repr__(self):
strm = io.StringIO()
@@ -222,7 +232,7 @@ class EntityDeclaration(Node):
class EnumerationType(Node):
values = property(lambda self: self.enumeration_type[2][1::2])
values = property(lambda self: list(self.enumeration_type[2])[1::2])
def __repr__(self):
return "ENUMERATION OF (" + ",".join(self.values) + ")"
@@ -241,29 +251,160 @@ def do_try(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 get_rule_id(x):
from bootstrap import actions
ty = type(x).__name__
matches = [k for k, v in actions.items() if v == ty]
if matches:
return matches[0]
def prune(di):
import bootstrap
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
}
subrules = list(filter(str.islower, rule_dependencies[key]))
return {k: v for k, v in di.items() if k in subrules}
# 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):
return to_tree(x.dict_tokens, key=get_rule_id(x) or key)
if isinstance(x, Node,):
return to_tree(x.tokens, key=get_rule_id(x) or key)
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):
return prune({k: to_tree(v, key=k) for k, v in x.items()})
# 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:
@@ -306,7 +447,7 @@ class AggregationType(Node):
class SelectType(Node):
values = property(lambda self: self.select_type[1][1::2])
values = property(lambda self: list(self.select_type[1])[1::2])
def __repr__(self):
return "SELECT (" + ",".join(map(str, self.values)) + ")"
@@ -321,7 +462,7 @@ class SuperTypeExpression(Node):
else:
constraint = self.supertype_rule[0]
return [
s[0][0].simple_id for s in constraint.subtype_constraint[0].supertype_expression[0][0][0].one_of[0][2::2]
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)
@@ -418,7 +559,7 @@ class WidthSpec(Node):
fixed = property(lambda self: self.FIXED is not None)
def init(self):
self.width = int("".join(self.width[0].flat))
self.width = int("".join(list(self.width)[0].flat))
def __repr__(self):
return "(%d)%s" % (self.width, " fixed" if self.fixed else "")
@@ -432,3 +573,16 @@ class StringType(Node):
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,260 @@
import os
import re
import ast
import collections
import ifcopenshell
from dataclasses import dataclass
from codegen import indent
def reverse_compile(s):
return re.sub(
"\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("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, logger):
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}.py")
source = open(fn, "r").read()
a = ast.parse(source)
assertion.rewrite.rewrite_asserts(mod=a, source=source)
cd = compile(a, f"{f.schema}.py", "exec")
scope = {}
exec(cd, scope)
S = ifcopenshell.ifcopenshell_wrapper.schema_by_name(f.schema)
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 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 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)):
assert isinstance(type, ifcopenshell.ifcopenshell_wrapper.aggregation_type)
ty = type.type_of_element()
for v in value:
check(v, ty, instance=inst)
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:
values = list(inst)
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 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
@@ -75,31 +75,39 @@ class Schema:
return str(v) in self.entities
def __len__(self):
return len(self.types) + len(self.entities)
return len(self.keys)
def __iter__(self):
return iter(self.keys)
def __getitem__(self, key):
return self.types_entities[key]
return self.all_declarations[OrderedCaseInsensitiveDict_KeyObject(key)]
def __init__(self, parsetree):
self.tree = parsetree
self.name = parsetree.syntax[0][0].simple_id
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 parsetree.syntax[0][0].schema_body[0]
if d.rule == "declaration" and d.any()[0].rule != "function_decl"
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())
self.types_entities = {k: v for d in (self.types, self.entities) for k, v in d.items()}
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)]
@@ -392,9 +392,10 @@ class SchemaClass(codegen.Base):
else:
return x.simple_type(type)
else:
raise ValueError("No mapping for '%s'" % type)
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]
@@ -412,7 +413,7 @@ class SchemaClass(codegen.Base):
pass
else:
raise Exception("No declared type for <%r>" % type)
raise Exception("No attribute named %s.%s" % (entity_name_orig, attribute_name))
collections_by_type = (
("entity", mapping.schema.entities),
@@ -430,7 +431,7 @@ class SchemaClass(codegen.Base):
x.begin_schema()
emitted = set()
len_to_emit = len(mapping.schema)
len_to_emit = len(mapping.schema) - len(mapping.schema.rules) - len(mapping.schema.functions)
def write_simpletype(schema_name, name, type):
try:
@@ -466,6 +467,10 @@ class SchemaClass(codegen.Base):
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):