Source code for fosf.parsers.theory
#!/usr/bin/env python3
from lark import Lark
from fosf.config import FOSF_GRAMMAR
from fosf.parsers.taxonomy import TaxonomyParser, _TaxonomyTransformer
from fosf.syntax.base import Sort, Tag
from fosf.syntax.terms import NormalTerm, Term
from fosf.syntax.theory import OsfTheory, TheoryTag
class _OsfTheoryTransformer(_TaxonomyTransformer):
def __init__(self):
super().__init__()
self.definitions: dict[Sort, Term] = {}
self.tags: dict[Tag, TheoryTag] = {}
def theory(self, tree):
return tree[0], self.definitions, self.tags, self.domains, self.ranges
def domain(self, tree):
feature = tree[0]
sort = tree[1]
if feature in self.domains and sort != self.domains[feature]:
msg = f"Multiple domain declarations for {feature}"
raise RuntimeError(msg)
self.domains[feature] = sort
def range(self, tree):
feature = tree[0]
sort = tree[1]
if feature in self.ranges and sort != self.ranges[feature]:
msg = f"Multiple range declarations for {feature}"
raise RuntimeError(msg)
self.ranges[feature] = sort
def definition(self, tree):
sort = tree[0]
term = tree[1]
self.definitions[sort] = term
def theory_term(self, tree):
tag = Tag(tree[0].value)
sort = tree[1]
if len(tree) <= 2:
self.tags[tag] = TheoryTag(tag, sort)
return NormalTerm(tag, sort)
pairs = tree[2]
features = {}
subterms = {}
for f, term in pairs:
subterms[f] = term
features[f] = term.X
theory_tag = TheoryTag(tag, sort, features)
self.tags[tag] = theory_tag
return NormalTerm(tag, sort, subterms)
def theory_unsorted_term(self, tree):
tag = Tag(tree[0].value)
if len(tree) > 1:
return NormalTerm(tag, s=None, subterms=tree[1])
return NormalTerm(tag)
def theory_subterms(self, tree):
return tree
def theory_subterm(self, tree):
return tree[0], tree[1]
def transform(self, parse_tree, **kwargs):
self.definitions = {}
self.tags = {}
self.domains = {}
self.ranges = {}
return super().transform(parse_tree, **kwargs)
[docs]
class OsfTheoryParser(TaxonomyParser):
def __init__(self):
self.parser = Lark.open_from_package("fosf", FOSF_GRAMMAR, start="theory")
self.transformer = _OsfTheoryTransformer()
[docs]
def parse(self, expression: str, ensure_closed=False, **kwargs) -> OsfTheory:
parse_tree = self.parser.parse(expression)
return OsfTheory(
*self.transformer.transform(parse_tree, **kwargs), ensure_closed=ensure_closed
)