ISCE_INSAR/components/iscesys/Parsers/rdf/language/grammar/morpheme.py

123 lines
3.8 KiB
Python
Raw Normal View History

2019-01-16 19:40:08 +00:00
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2014 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Eric Belz
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""Suported morphemes are affixes. The Affix ABC (and subclass of the list
built-in) has two concrete subs:
Prefix
Suffix
They know how to apply themselves, and they know what to do to Grammar
as it traverses the IFT.
"""
## \namespace rdf.language.grammar.morpheme Key Changing Morphemes
import abc
## Abstract Base Class for Pre/Suf behavior
class Affix(list):
"""The Affix is an abstract base class.
It implements the:
descend/asend methods for traversing the IFT
It is callable: Given a key, it will do what morphemes do and make
as new key per the RDF spec.
Sub classes use operator overloads to do their thing
"""
__metaclass__ = abc.ABCMeta
## Descend the IFT-- add a null string to the affix list
## \param None
## \par Side Effects:
## Append null string to Affix
## \returns None
def descend(self):
"""append null string to self"""
return self.append("")
## Ascend the IFT-- pop the affix off and forget it
## \param None
## \par Side Effects:
## Pops last affix off of Affix
## \returns None
def ascend(self):
"""pop() from self"""
return self.pop()
## Call implements the construction of the affix (so IF you change the def
## you change this 1 line of code.
## \returns Sum of self- the complete affix
def __call__(self):
"""call implements the nest affix protocol: add 'em up"""
return "".join(self)
## strictly for safety
def __add__(self, other):
from rdf.language import errors
raise (
{True: errors.MorphemeExchangeError(
"Cannot Pre/Ap-pend a Suf/Pre-fix"),
False: TypeError("Can only add strings to this list sub")}[
isinstance(other, basestring)
]
)
__radd__ = __add__
## Appears Before the stem:
class Prefix(Affix):
"""prefix + stem
is the only allowed operator overload- it, by definition, must
be prepended"""
## prefix + stem (overides list concatenation)
def __add__(self, stem):
return self() + stem
## Appears After the stem
class Suffix(Affix):
"""stem + suffix
is the only allowed operator overload- it, by definition, must
be appended"""
## stem + prefix (overides list concatenation)
def __radd__(self, stem):
return stem + self()