@@ -327,10 +327,14 @@ def parse(
327
327
with_progress = False ,
328
328
with_tree = True ,
329
329
with_header = False ,
330
+ only_header = False
330
331
):
331
332
if filename :
332
333
assert not filecontent
333
334
filecontent = builtins .open (filename , encoding = None ).read ()
335
+
336
+ if only_header :
337
+ assert with_header , "'only_header=True' requires 'with_header=True'"
334
338
335
339
# Match and remove the comments
336
340
p = r"/\*[\s\S]*?\*/"
@@ -339,6 +343,37 @@ def replace_fn(match):
339
343
return re .sub (r"[^\n]" , " " , match .group (), flags = re .M )
340
344
341
345
filecontent_wo_comments = re .sub (p , replace_fn , filecontent )
346
+
347
+
348
+ if only_header :
349
+ # Extract just the HEADER section using regex
350
+ header_match = re .search (
351
+ r"ISO-10303-21;\s*HEADER;(.*?)ENDSEC;" ,
352
+ filecontent_wo_comments ,
353
+ flags = re .DOTALL | re .IGNORECASE ,
354
+ )
355
+ if not header_match :
356
+ raise ValidationError ("No HEADER section found in file" )
357
+
358
+ header_text = f"HEADER;{ header_match .group (1 )} ENDSEC;"
359
+ full_header_text = f"ISO-10303-21;{ header_text } DATA;ENDSEC;END-ISO-10303-21;"
360
+
361
+ parser = Lark (grammar , parser = "lalr" , start = "file" )
362
+ try :
363
+ ast = parser .parse (full_header_text )
364
+ except (UnexpectedToken , UnexpectedCharacters ) as e :
365
+ raise SyntaxError (filecontent , e )
366
+
367
+ header_tree = ast .children [0 ] # HEADER section
368
+
369
+ def make_header_ent (ast ):
370
+ kw , param_list = ast .children
371
+ kw = kw .children [0 ].value
372
+ return kw , T (visit_tokens = True ).transform (param_list )
373
+
374
+ header = dict (map (make_header_ent , header_tree .children [0 ].children ))
375
+ return header
376
+
342
377
343
378
instance_identifiers = []
344
379
transformer = {}
@@ -483,5 +518,20 @@ def by_type(self, type: str) -> list[entity_instance]:
483
518
)
484
519
485
520
486
- def open (fn ) -> file :
487
- return file (parse (filename = fn , with_tree = True , with_header = True ))
521
+ def open (fn , only_header : bool = False ) -> file :
522
+ if only_header : # Ensure consistent options
523
+ parse_outcomes = parse (
524
+ filename = fn ,
525
+ with_tree = True ,
526
+ with_header = True , # must be True to return the header
527
+ only_header = True ,
528
+ )
529
+ return file ((parse_outcomes , defaultdict (list ))) # data section is empty
530
+ else :
531
+ parse_outcomes = parse (
532
+ filename = fn ,
533
+ with_tree = True ,
534
+ with_header = True ,
535
+ only_header = False ,
536
+ )
537
+ return file (parse_outcomes )
0 commit comments