mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 17:57:02 +00:00
Correctly allow rule labels to be optional
This commit is contained in:
@@ -19,8 +19,14 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import string
|
import string
|
||||||
|
import operator
|
||||||
|
import itertools
|
||||||
|
|
||||||
from pyparsing import *
|
from pyparsing import *
|
||||||
|
|
||||||
|
try: from functools import reduce
|
||||||
|
except: pass
|
||||||
|
|
||||||
class Expression:
|
class Expression:
|
||||||
def __init__(self, contents):
|
def __init__(self, contents):
|
||||||
self.contents = contents[0]
|
self.contents = contents[0]
|
||||||
@@ -56,12 +62,12 @@ class Keyword:
|
|||||||
class Terminal:
|
class Terminal:
|
||||||
def __init__(self, contents):
|
def __init__(self, contents):
|
||||||
self.contents = contents[0]
|
self.contents = contents[0]
|
||||||
def __repr__(self):
|
|
||||||
s = self.contents
|
s = self.contents
|
||||||
is_keyword = len(s) >= 4 and s[0::len(s)-1] == '""' and \
|
self.is_keyword = len(s) >= 4 and s[0::len(s)-1] == '""' and \
|
||||||
all(c in alphanums+"_" for c in s[1:-1])
|
all(c in alphanums+"_" for c in s[1:-1])
|
||||||
ty = "CaselessKeyword" if is_keyword else "CaselessLiteral"
|
def __repr__(self):
|
||||||
return "%s(%s)" % (ty, s)
|
ty = "CaselessKeyword" if self.is_keyword else "CaselessLiteral"
|
||||||
|
return "%s(%s)" % (ty, self.contents)
|
||||||
|
|
||||||
|
|
||||||
LPAREN = Suppress("(")
|
LPAREN = Suppress("(")
|
||||||
@@ -94,16 +100,16 @@ grammar.ignore(HASH + restOfLine)
|
|||||||
|
|
||||||
express = grammar.parseFile(sys.argv[1])
|
express = grammar.parseFile(sys.argv[1])
|
||||||
|
|
||||||
def find_keywords(expr, li = None):
|
def find_bytype(expr, ty, li = None):
|
||||||
if li is None: li = []
|
if li is None: li = []
|
||||||
if isinstance(expr, Term):
|
if isinstance(expr, Term):
|
||||||
expr = expr.contents
|
expr = expr.contents
|
||||||
if isinstance(expr, Keyword):
|
if isinstance(expr, ty):
|
||||||
li.append(repr(expr))
|
li.append(expr)
|
||||||
return li
|
return set(li)
|
||||||
elif isinstance(expr, Expression):
|
elif isinstance(expr, Expression):
|
||||||
for term in expr:
|
for term in expr:
|
||||||
find_keywords(term, li)
|
find_bytype(term, ty, li)
|
||||||
return set(li)
|
return set(li)
|
||||||
|
|
||||||
actions = {
|
actions = {
|
||||||
@@ -132,17 +138,21 @@ to_combine = set(["simple_id"])
|
|||||||
to_ignore = set(["where_clause", "supertype_constraint", "unique_clause"])
|
to_ignore = set(["where_clause", "supertype_constraint", "unique_clause"])
|
||||||
statements = []
|
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)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
emitted_in_loop = set()
|
emitted_in_loop = set()
|
||||||
for id, expr in express:
|
for id, expr in express:
|
||||||
kws = find_keywords(expr)
|
kws = map(repr, find_bytype(expr, Keyword))
|
||||||
found = [k in emitted for k in kws]
|
found = [k in emitted for k in kws]
|
||||||
if id in to_emit and all(found):
|
if id in to_emit and all(found):
|
||||||
emitted_in_loop.add(id)
|
emitted_in_loop.add(id)
|
||||||
emitted.add(id)
|
emitted.add(id)
|
||||||
stmt = "(%s)" % expr
|
stmt = "(%s)" % expr
|
||||||
if id in to_combine:
|
if id in to_combine:
|
||||||
stmt = "originalTextFor(Combine%s)" % stmt
|
stmt = " + ".join(itertools.chain(negated_keywords, ("originalTextFor(Combine%s)" % stmt,)))
|
||||||
if id in actions:
|
if id in actions:
|
||||||
stmt = "%s.setParseAction(%s)" % (stmt, actions[id])
|
stmt = "%s.setParseAction(%s)" % (stmt, actions[id])
|
||||||
statements.append("%s = %s" % (id, stmt))
|
statements.append("%s = %s" % (id, stmt))
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
# Taken from http://sourceforge.net/p/exp-engine/expresso/ci/master/tree/docs/iso-10303-11--2004.bnf
|
|
||||||
|
|
||||||
ABS = "abs" .
|
ABS = "abs" .
|
||||||
ABSTRACT = "abstract" .
|
ABSTRACT = "abstract" .
|
||||||
ACOS = "acos" .
|
ACOS = "acos" .
|
||||||
@@ -202,7 +200,7 @@ constructed_types = enumeration_type | select_type .
|
|||||||
declaration = entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl .
|
declaration = entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl .
|
||||||
derived_attr = attribute_decl ":" parameter_type ":=" expression ";" .
|
derived_attr = attribute_decl ":" parameter_type ":=" expression ";" .
|
||||||
derive_clause = DERIVE derived_attr { derived_attr } .
|
derive_clause = DERIVE derived_attr { derived_attr } .
|
||||||
domain_rule = rule_label_id ":" expression .
|
domain_rule = [ rule_label_id ":" ] expression .
|
||||||
element = expression [ ":" repetition ] .
|
element = expression [ ":" repetition ] .
|
||||||
entity_body = { explicit_attr } [ derive_clause ] [ inverse_clause ] [ unique_clause ] [ where_clause ] .
|
entity_body = { explicit_attr } [ derive_clause ] [ inverse_clause ] [ unique_clause ] [ where_clause ] .
|
||||||
entity_constructor = entity_ref "(" [ expression { "," expression } ] ")" .
|
entity_constructor = entity_ref "(" [ expression { "," expression } ] ")" .
|
||||||
@@ -334,7 +332,7 @@ type_label_id = simple_id .
|
|||||||
unary_op = "+" | "-" | NOT .
|
unary_op = "+" | "-" | NOT .
|
||||||
underlying_type = constructed_types | concrete_types .
|
underlying_type = constructed_types | concrete_types .
|
||||||
unique_clause = UNIQUE unique_rule ";" { unique_rule ";" } .
|
unique_clause = UNIQUE unique_rule ";" { unique_rule ";" } .
|
||||||
unique_rule = rule_label_id ":" referenced_attribute { "," referenced_attribute } .
|
unique_rule = [ rule_label_id ":" ] referenced_attribute { "," referenced_attribute } .
|
||||||
until_control = UNTIL logical_expression .
|
until_control = UNTIL logical_expression .
|
||||||
use_clause = USE FROM schema_ref [ "(" named_type_or_rename { "," named_type_or_rename } ")" ] ";" .
|
use_clause = USE FROM schema_ref [ "(" named_type_or_rename { "," named_type_or_rename } ")" ] ";" .
|
||||||
variable_id = simple_id .
|
variable_id = simple_id .
|
||||||
|
|||||||
Reference in New Issue
Block a user