mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
Correctly allow rule labels to be optional
This commit is contained in:
@@ -19,8 +19,14 @@
|
||||
|
||||
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]
|
||||
@@ -56,12 +62,12 @@ class Keyword:
|
||||
class Terminal:
|
||||
def __init__(self, contents):
|
||||
self.contents = contents[0]
|
||||
def __repr__(self):
|
||||
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])
|
||||
ty = "CaselessKeyword" if is_keyword else "CaselessLiteral"
|
||||
return "%s(%s)" % (ty, s)
|
||||
def __repr__(self):
|
||||
ty = "CaselessKeyword" if self.is_keyword else "CaselessLiteral"
|
||||
return "%s(%s)" % (ty, self.contents)
|
||||
|
||||
|
||||
LPAREN = Suppress("(")
|
||||
@@ -94,16 +100,16 @@ grammar.ignore(HASH + restOfLine)
|
||||
|
||||
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 isinstance(expr, Term):
|
||||
expr = expr.contents
|
||||
if isinstance(expr, Keyword):
|
||||
li.append(repr(expr))
|
||||
return li
|
||||
if isinstance(expr, ty):
|
||||
li.append(expr)
|
||||
return set(li)
|
||||
elif isinstance(expr, Expression):
|
||||
for term in expr:
|
||||
find_keywords(term, li)
|
||||
find_bytype(term, ty, li)
|
||||
return set(li)
|
||||
|
||||
actions = {
|
||||
@@ -131,18 +137,22 @@ emitted = set()
|
||||
to_combine = set(["simple_id"])
|
||||
to_ignore = set(["where_clause", "supertype_constraint", "unique_clause"])
|
||||
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:
|
||||
emitted_in_loop = set()
|
||||
for id, expr in express:
|
||||
kws = find_keywords(expr)
|
||||
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 = "originalTextFor(Combine%s)" % stmt
|
||||
stmt = " + ".join(itertools.chain(negated_keywords, ("originalTextFor(Combine%s)" % stmt,)))
|
||||
if id in actions:
|
||||
stmt = "%s.setParseAction(%s)" % (stmt, actions[id])
|
||||
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" .
|
||||
ABSTRACT = "abstract" .
|
||||
ACOS = "acos" .
|
||||
@@ -202,7 +200,7 @@ 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 .
|
||||
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 } ] ")" .
|
||||
@@ -334,7 +332,7 @@ 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 } .
|
||||
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 .
|
||||
|
||||
Reference in New Issue
Block a user