Source code for fosf.parsers.taxonomy
#!/usr/bin/env python3
from collections import defaultdict
import networkx as nx
from lark import Lark
from fosf.parsers.base import BaseOSFParser, _BaseOSFTransformer
from fosf.syntax.base import Sort
from fosf.syntax.taxonomy import SortTaxonomy, FuzzySortTaxonomy
TAXONOMY_GRAMMAR = "grammars/taxonomy.lark"
class _GraphTransformer(_BaseOSFTransformer):
def __init__(self):
super().__init__()
self.decs = []
self.fuzzy = False
def sorts(self, tree):
return [t.value for t in tree]
def fuzzysort(self, tree):
"Handle a sort with an approximation degree."
if len(tree) > 1:
weight = float(tree[1].value)
if weight < 1:
self.fuzzy = True
return (tree[0].value, weight)
return (tree[0].value, 1.0)
def fuzzysorts(self, tree):
"Handle a list of sorts associated with an approximation degree."
return tree
def declaration(self, tree):
self.decs.extend([(subsort, supersort[0], supersort[1])
for subsort in tree[0]
for supersort in tree[1]])
def declarations(self, _):
g = nx.DiGraph()
for u, v, w in self.decs:
g.add_edge(u, v, weight=w)
return g
def transform(self, parse_tree) -> nx.DiGraph:
self.decs = []
return super().transform(parse_tree)
[docs]
class GraphParser(BaseOSFParser):
def __init__(self):
self.parser = Lark.open_from_package("fosf.parsers",
TAXONOMY_GRAMMAR, parser="lalr")
self.transformer = _GraphTransformer()
[docs]
def parse(self, expression: str) -> nx.DiGraph:
parse_tree = self.parser.parse(expression)
return self.transformer.transform(parse_tree)
class _TaxonomyTransformer(_GraphTransformer):
def __init__(self):
super().__init__()
self._instances = defaultdict(dict)
def baseinstance(self, tree):
return tree[0].value, 1.0
def fuzzyinstance(self, tree):
degree = float(tree[0].value)
instance = tree[1].value
return instance, degree
def instance(self, tree):
return tree[0]
def instances(self, tree):
return tree
def instance_dec(self, tree):
instances = tree[0]
sorts = tree[1]
for instance, degree in instances:
for sort in sorts:
self._instances[instance][Sort(sort)] = degree
def declarations(self, _) -> SortTaxonomy:
if self.fuzzy:
return FuzzySortTaxonomy(self.decs, instances=self._instances)
return SortTaxonomy(self.decs, instances=self._instances)
def transform(self, parse_tree):
self.decs = []
self.fuzzy = False
return super().transform(parse_tree)
[docs]
class TaxonomyParser(BaseOSFParser):
def __init__(self):
self.parser = Lark.open_from_package("fosf.parsers",
TAXONOMY_GRAMMAR, parser="lalr")
self.transformer = _TaxonomyTransformer()
[docs]
def parse(self, expression: str) -> SortTaxonomy:
parse_tree = self.parser.parse(expression)
return self.transformer.transform(parse_tree)