Source code for yaslha.parser

"""Parsers for SLHA package.

Parsers for SLHA-format, JSON-format, and YAML-format are provided.
"""

import logging
from typing import Any, List, Optional, Type, Union

import yaslha.line
import yaslha.slha
from yaslha.block import AbsBlock, Block, Decay, InfoBlock

SLHAParserStatesType = Union[None, Block, InfoBlock, Decay]


logger = logging.getLogger(__name__)


[docs]class SLHAParser: """SLHA-format file parser.""" def __init__(self, **kw: Any) -> None: self.processing = None # type: SLHAParserStatesType def _parse_line(self, line: str) -> Optional[yaslha.line.AbsLine]: if not line.strip(): return None # empty line will be ignored if isinstance(self.processing, InfoBlock): classes = [ yaslha.line.BlockHeadLine, yaslha.line.DecayHeadLine, yaslha.line.InfoLine, yaslha.line.CommentLine, ] # type: List[Type[yaslha.line.AbsLine]] elif isinstance(self.processing, Block): classes = [ yaslha.line.BlockHeadLine, yaslha.line.DecayHeadLine, yaslha.line.NoIndexLine, yaslha.line.OneIndexLine, yaslha.line.TwoIndexLine, yaslha.line.ThreeIndexLine, yaslha.line.DecayLine, # for extensions yaslha.line.CommentLine, ] elif isinstance(self.processing, Decay): classes = [ yaslha.line.BlockHeadLine, yaslha.line.DecayHeadLine, yaslha.line.DecayLine, yaslha.line.CommentLine, ] elif self.processing is None: classes = [ yaslha.line.BlockHeadLine, yaslha.line.DecayHeadLine, yaslha.line.CommentLine, ] else: logger.critical("Unexpected state: %s", self.processing) raise RuntimeError for c in classes: obj = c.construct(line) if obj: return obj raise ValueError(line)
[docs] def parse(self, text: str) -> yaslha.slha.SLHA: """Parse SLHA format text and return SLHA object.""" self.processing = None slha = yaslha.slha.SLHA() comment_lines = [] # type: List[str] for line in text.splitlines(): try: obj = self._parse_line(line) if obj is None: continue except ValueError: logger.warning("Unrecognized line: %s", line) continue # comment handling if isinstance(obj, yaslha.line.CommentLine): comment_lines.append(obj.comment) continue elif isinstance(obj, yaslha.line.AbsLine): obj.pre_comment = comment_lines comment_lines = [] else: raise NotImplementedError(obj) # line handling if isinstance(obj, yaslha.line.BlockHeadLine): self.processing = AbsBlock.new(obj) assert self.processing is not None slha.add_block(self.processing) elif isinstance(obj, yaslha.line.DecayHeadLine): self.processing = Decay(obj) assert self.processing is not None slha.add_block(self.processing) elif isinstance(obj, yaslha.line.InfoLine): if not isinstance(self.processing, InfoBlock): logger.critical("InfoLine found outside of INFO block: %s", line) raise ValueError(self.processing) self.processing.append_line(obj) elif isinstance(obj, yaslha.line.ValueLine): if self.processing is None: logger.critical("ValueLine found outside of block: %s", line) raise ValueError(self.processing) self.processing.update_line(obj) else: raise TypeError(obj) # tail comments slha.tail_comment = comment_lines self.processing = None return slha