def _parse_answer(self, answer_set: str) -> iter: """Yield atoms as (pred, args) from given answer set""" careful_parsing = self._careful_parsing or parsing.careful_parsing_required( answer_set) if isinstance(answer_set, str) and careful_parsing: # print('CAREFUL PARSING:', answer_set) # _discard_quotes is incompatible with atoms_as_string and as_pyasp. # atom_as_string: remove the quotes delimiting arguments. # as_pyasp: remove the quotes for the arguments. yield from parsing.Parser( self._collapse_atoms, self._collapse_args, self._discard_quotes and not self._collapse_atoms, self._first_arg_only, parse_integer=self._parse_int).parse_terms(answer_set) elif isinstance(answer_set, str): # the good ol' split # print('THE GOOD OLD SPLIT:', f"discard_quotes={self._discard_quotes} collapse_atoms={self._collapse_atoms}") yield from self.__finish_parsing( naive_parsing_of_answer_set(answer_set, discard_quotes=self._discard_quotes and not self._collapse_atoms, parse_int=self._parse_int, parse_args=True or self._collapse_args or self._first_arg_only)) elif isinstance(answer_set, (set, tuple)) and all( isinstance(atom, (str, int, tuple)) for atom in answer_set): # already parsed # print('FROM SET OR TUPLE') if not self._parse_int: answer_set = utils.integers_to_string_atoms(answer_set) yield from self.__finish_parsing(answer_set) else: # unknown format raise ValueError("unknow answer set format: {}, {}".format( type(answer_set), answer_set))
def _parse_answer(self, answer_set: str) -> iter: """Yield atoms as (pred, args) according to parsing options""" REG_ANSWER_SET = re.compile(r'([a-z][a-zA-Z0-9_]*)(\([^)]+\))?') if self._careful_parsing: yield from parsing.Parser( self._collapse_atoms, self._collapse_args, parse_integer=self._parse_int).parse_terms(answer_set) else: # the good ol' split current_answer = set() for match in REG_ANSWER_SET.finditer(answer_set): if self._atoms_as_string: pred, args = match.groups() if args is None: # atom with no arg args = '' yield pred + args # just send the match continue pred, args = match.groups() assert args is None or (args.startswith('(') and args.endswith(')')) if args: args = args[1:-1] if not self._collapse_atoms: # else: atom as string # parse also integers, if asked to args = tuple((int(arg) if self._parse_int and ( arg[1:] if arg.startswith('-') else arg ).isnumeric() else arg) for arg in args.split(',')) yield pred, args or ()
def answer_set_from_str(line:str, collapse_atoms:bool=False, collapse_args:bool=True, parse_integer:bool=True) -> iter: """Yield atoms found in given string. line -- parsable string containing an answer set collapse_atoms -- whole atoms are left unparsed collapse_args -- atoms args are left unparsed parse_integer -- integers are returned as python int objects >>> tuple(sorted(answer_set_from_str('a b c d', True))) ('a', 'b', 'c', 'd') >>> tuple(sorted((answer_set_from_str('a b(a) c("text") d', True)))) ('a', 'b(a)', 'c("text")', 'd') """ yield from parsing.Parser( collapse_atoms=collapse_atoms, collapse_args=collapse_args, parse_integer=parse_integer ).parse_terms(line)
def parse_clingo_output(clingo_output: [str]): "Yield answer sets found in given clingo output" yield from (answer for anstype, answer in parsing.Parser().parse_clasp_output(clingo_output) if anstype == 'answer')