Skip to content

Commit 4e255c6

Browse files
Ghesselinkaothms
authored andcommitted
add parse_only API
1 parent 65623fd commit 4e255c6

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

__init__.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,10 +327,14 @@ def parse(
327327
with_progress=False,
328328
with_tree=True,
329329
with_header=False,
330+
only_header=False
330331
):
331332
if filename:
332333
assert not filecontent
333334
filecontent = builtins.open(filename, encoding=None).read()
335+
336+
if only_header:
337+
assert with_header, "'only_header=True' requires 'with_header=True'"
334338

335339
# Match and remove the comments
336340
p = r"/\*[\s\S]*?\*/"
@@ -339,6 +343,37 @@ def replace_fn(match):
339343
return re.sub(r"[^\n]", " ", match.group(), flags=re.M)
340344

341345
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+
342377

343378
instance_identifiers = []
344379
transformer = {}
@@ -483,5 +518,20 @@ def by_type(self, type: str) -> list[entity_instance]:
483518
)
484519

485520

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

Comments
 (0)