#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # 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 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """Brackets: This is where glyphs take on meaning""" ## \namespace rdf.language.grammar.punctuation Language's Punctuation Marks. from __future__ import absolute_import from iscesys.Parsers.rdf import reserved from iscesys.Parsers.rdf.reserved import glyphs ## A symbol is a string that can split a line on it's left most occurance\n ## It's a puncuatin mark that can find itself class Glyph(str): """A Glyph is a str sub-class that can be called. symbol(line) splits the line on the 1st occorence of symbol in line. If it is not in line, you still get 2 results: line, "" so it i basically an 2-ple safe unpacking of a split on self. """ ## split line on self ## \param line A line ## \returns (left, right) side of line (with possible null str on right) def __call__(self, line): try: index = line.index(self) except ValueError: left, right = line, "" else: left = line[:index] right = line[index+1:] return list(map(str.strip, (left, right))) ## Get line left of self ## \param line A line with or without self ## \retval left line left of self def left(self, line): """left symbol""" return self(line)[0] ## Get line right of self ## \param line A line with or without self ## \retval right line right of self def right(self, line): """right symbol""" return self(line)[-1] ## Brackets that ## know thy selves. class Brackets(str): """_Delimeter('LR') get it? Knows how to find itself in line """ ## L, R --> -, + \n + is right def __pos__(self): return self[-len(self)//2:] ## L, R --> -, + \n - is left def __neg__(self): return self[:len(self)//2] ## extract enclosed: line<>pair or go blank def __rrshift__(self, line): """Insert non-zero line in string, or nothing""" return " %s%s%s " % (-self, str(line), +self) if line else "" __lshift__ = __rrshift__ __rshift__ = __rlshift__ ## (line in delimiter) IF the line has token in it legally # \param line an RDF sentence # \retval IF Bracket is in the line def __contains__(self, line): return ( (-self in line) and (+self in line) and line.index(-self) < line.index(+self) ) ## line - delimiter removes delimeter from line, with no IF def __rsub__(self, line): """IF line in self __get_inner(line) else line""" return {True : self.__get_inner, False : self.__no_inner}[line in self](line) ## Call IF line is in self, then go get it def __get_inner(self, line): return (line[:line.rindex(-self)] + line[1+line.rindex(+self):]).strip() ## Call IF line is not in self, a no-op. @staticmethod def __no_inner(line): return line ## Unit defining Brackets from rdf.reserved.glyphs.UNITS UNITS = Brackets(glyphs.UNITS) ## DIMENSIONS defining Brackets from rdf.reserved.glyphs.DIMENSIONS DIMENSIONS = Brackets(glyphs.DIMENSIONS) ## ELEMENT defining Brackets from rdf.reserved.glyphs.ELEMENT ELEMENT = Brackets(glyphs.ELEMENT) ## Tuple of RDF Optional Left Fields _OPTIONAL_LEFT_FIELDS = (UNITS, DIMENSIONS, ELEMENT) ## Self explanatory NUMBER_OF_OPTIONAL_LEFT_FIELDS = len(_OPTIONAL_LEFT_FIELDS) ## get ::_OPTIONAL_LEFT_FIELDS (olf). def get_olf(left_line): """parse out UNITS DIMENSIONS ELEMENT from input line""" return [left_line << item for item in _OPTIONAL_LEFT_FIELDS] ## Get the key out of the left side of an rdf record \n ## Note: this relies on the Brackets.__rsub__ operator def get_key(leftline): """Get key part only form a record line's left-of-operator portion""" return (leftline - UNITS - DIMENSIONS - ELEMENT).strip() ## get key and delimeters - the entrie left side of an rdf record, parsed def key_parse(leftline): """Break left-of-operator portion into key, units, dimensions, element""" return [get_key(leftline)] + get_olf(leftline)