108 lines
2.3 KiB
Python
108 lines
2.3 KiB
Python
from lark import Transformer
|
|
from dataclasses import dataclass
|
|
import numbers
|
|
from lark import Lark, Transformer, Tree, Token
|
|
|
|
|
|
class IfcType:
|
|
def __init__(self, ifctype, value):
|
|
self.ifctype = ifctype
|
|
self.value = value
|
|
|
|
def __str__(self):
|
|
return self.ifctype + "(" + str(self.value) + ")"
|
|
|
|
__repr__ = __str__
|
|
|
|
|
|
@dataclass
|
|
class entity_instance:
|
|
id: int
|
|
type: str
|
|
attributes: tuple
|
|
lines: tuple
|
|
|
|
def __getitem__(self, k):
|
|
if isinstance(k, numbers.Integral):
|
|
return self.attributes[k]
|
|
else:
|
|
# compatibility with dict
|
|
return getattr(self, k)
|
|
|
|
def __repr__(self):
|
|
return f'#{self.id}={self.type}({",".join(map(str, self.attributes))})'
|
|
|
|
|
|
class T(Transformer):
|
|
def id(self, s):
|
|
return int(s[0][1:])
|
|
|
|
def string(self, s):
|
|
word = "".join(s).replace("''", "'")
|
|
return word
|
|
|
|
def keyword(self, s):
|
|
word = "".join(s)
|
|
return word
|
|
|
|
def untyped_parameter(self, s):
|
|
return s[0]
|
|
|
|
def parameter(self, s):
|
|
return s[0]
|
|
|
|
def typed_parameter(self, s):
|
|
if len(s):
|
|
return IfcType(s[0], s[1])
|
|
else:
|
|
return ()
|
|
|
|
def omitted_parameter(self, s):
|
|
return s[0]
|
|
|
|
def enumeration(self, s):
|
|
return s[0]
|
|
|
|
parameter_list = tuple
|
|
list = tuple
|
|
subsuper_record = list
|
|
INT = int
|
|
REAL = float
|
|
NONE = lambda *args: None
|
|
STAR = str
|
|
|
|
|
|
def create_step_entity(entity_tree):
|
|
t = T(visit_tokens=True).transform(entity_tree)
|
|
|
|
def get_line_number(t):
|
|
if isinstance(t, Token):
|
|
yield t.line
|
|
|
|
def traverse(fn, x):
|
|
yield from fn(x)
|
|
if isinstance(x, Tree):
|
|
for c in x.children:
|
|
yield from traverse(fn, c)
|
|
|
|
lines = list(traverse(get_line_number, entity_tree))
|
|
|
|
entity_id = t.children[0].children[0]
|
|
entity_type = t.children[0].children[1].children[0]
|
|
|
|
attributes_tree = t.children[0].children[1].children[1]
|
|
attributes = list(attributes_tree)
|
|
|
|
return entity_instance(
|
|
entity_id,
|
|
entity_type,
|
|
attributes,
|
|
(min(lines), max(lines)),
|
|
)
|
|
|
|
|
|
def make_header_ent(ast):
|
|
rule = ast.data
|
|
params = T(visit_tokens=True).transform(ast.children[0])
|
|
return rule.upper(), params
|