| 88 | return (int(items[0]), str(items[1]), items[2]) |
| 89 | |
| 90 | class stream(file): |
| 91 | def __init__(self, filepath: str): |
| 92 | self.history_size = 64 |
| 93 | self.history = [] |
| 94 | self.future = [] |
| 95 | self.transaction = None |
| 96 | |
| 97 | self.filepath = filepath |
| 98 | |
| 99 | self.file = open(filepath, "r") |
| 100 | self.id_map: dict[int, str] = {} |
| 101 | self.class_map: dict[str, list[int]] = {} |
| 102 | self.id_offset: dict[int, int] = {} |
| 103 | self.reference_pattern = re.compile(r"#(\d+)") |
| 104 | self.entity_cache: dict[int, stream_entity] = {} |
| 105 | self.inverses: dict[int, list[int]] = {} |
| 106 | |
| 107 | # common.INT doesn't support negative integers. |
| 108 | grammar = r""" |
| 109 | start: "#" NUMBER "=" TYPE "(" args ")" ";" |
| 110 | |
| 111 | args: arg ("," arg)* |
| 112 | |
| 113 | arg: STRING -> string |
| 114 | | FLOAT -> float |
| 115 | | IFCINT -> ifcint |
| 116 | | NULL -> null |
| 117 | | DERIVED -> derived |
| 118 | | ENUM -> enum |
| 119 | | REFERENCE -> reference |
| 120 | | list -> list |
| 121 | | inline_type -> inline_type |
| 122 | |
| 123 | list: "(" arg? ("," arg)* ")" |
| 124 | inline_type: TYPE "(" arg ")" |
| 125 | REFERENCE: "#" /[0-9]+/ |
| 126 | |
| 127 | TYPE: CNAME |
| 128 | NUMBER: INT |
| 129 | |
| 130 | STRING: "'" /([^']|'')*/ "'" |
| 131 | IFCINT: /-?[0-9]+/ |
| 132 | FLOAT: /-?[0-9]+\.[0-9]*([Ee]-?[0-9]+)?/ |
| 133 | NULL: "$" |
| 134 | DERIVED: "*" |
| 135 | ENUM: "." CNAME "." |
| 136 | |
| 137 | %import common.INT |
| 138 | %import common.CNAME |
| 139 | """ |
| 140 | |
| 141 | transformer = StreamTransformer() |
| 142 | transformer.file = self |
| 143 | self.parser = Lark(grammar, parser="lalr", transformer=transformer) |
| 144 | |
| 145 | exclude_classes = [ |
| 146 | "IfcObjectPlacement", |
| 147 | "IfcPresentationItem", |