Source code for fosf.parsers.clause
#!/usr/bin/env python3
from lark import Lark
from fosf.parsers.base import _BaseOSFTransformer, BaseOSFParser
from fosf.parsers.taxonomy import _TaxonomyTransformer
from fosf.syntax.base import Tag, Feature
from fosf.syntax.constraints import (Clause, RootedClause, SolvedClause,
RootedSolvedClause, EqualityConstraint,
SortConstraint, FeatureConstraint)
CONSTRAINT_GRAMMAR = "grammars/osf_constraints.lark"
CLAUSE_NORMALIZATION_GRAMMAR = "grammars/clause_normalization.lark"
class _OsfConstraintTransformer(_BaseOSFTransformer):
def __init__(self):
super().__init__()
self.osf_clause = Clause()
self.root = None
def clause(self, _):
return self.osf_clause
def sort_constraint(self, tree):
X = Tag(tree[0].value)
s = tree[1]
return self.osf_clause.add(SortConstraint(X, s))
def feature_constraint(self, tree):
X = Tag(tree[0].value)
f = Feature(tree[1].value)
Y = Tag(tree[2].value)
return self.osf_clause.add(FeatureConstraint(X, f, Y))
def equality_constraint(self, tree):
X = Tag(tree[0].value)
Y = Tag(tree[1].value)
return self.osf_clause.add(EqualityConstraint(X, Y))
def transform(self, parse_tree, create_using=None, root=None):
if create_using is None:
if root is None:
self.osf_clause = Clause()
else:
self.osf_clause = RootedClause(root)
elif root is None:
if create_using in {RootedClause, RootedSolvedClause}:
msg = ("A root must be specified for a clause"
f" of type {create_using}")
raise TypeError(msg)
self.osf_clause = create_using()
else:
if create_using in {Clause, SolvedClause}:
msg = f"Clauses of type {create_using} do not require a root"
raise TypeError(msg)
if isinstance(root, str):
root = Tag(root)
self.osf_clause = create_using(root)
return super().transform(parse_tree)
[docs]
class OsfConstraintParser(BaseOSFParser):
def __init__(self):
self.parser = Lark.open_from_package("fosf.parsers", CONSTRAINT_GRAMMAR,
parser="lalr")
self.transformer = _OsfConstraintTransformer()
[docs]
def parse(self, expression: str, create_using=None, root=None):
parse_tree = self.parser.parse(expression)
return self.transformer.transform(parse_tree, create_using, root)
class _NormalizationTransformer(_TaxonomyTransformer, _OsfConstraintTransformer):
def program(self, tree):
taxonomy = tree[0]
clause = tree[1]
return taxonomy, clause
[docs]
class NormalizationParser(BaseOSFParser):
def __init__(self):
self.parser = Lark.open_from_package("fosf.parsers",
CLAUSE_NORMALIZATION_GRAMMAR,
parser="lalr")
self.transformer = _NormalizationTransformer()