def __init__(self, ptr, sym): """ initialization arguments: self - ptr - parse tree sym - symbol table exceptions: FormatFailure on error """ self.ptr = ptr self.sym = sym self.exs = [] for x in ellyConfiguration.extractors: proc = x[0] synt = syntaxSpecification.SyntaxSpecification(sym, x[1].lower()) entry = [proc, synt.catg, synt.synf.positive] if len(x) > 2: f = None if x[2] == '-' else x[2].lower() smnt = featureSpecification.FeatureSpecification(sym, f, True) entry.append(smnt.positive) if len(x) > 3: entry.append(x[3]) self.exs.append(entry)
def __init__ ( self , symtb , defr ): """ initialization arguments: self - symtb - symbol table for interpreting syntax defr - definition input string """ self._errcount = 0 # print ( 'defr=' , defr ) ru = defr.split(' : ') if len(ru) != 2: self._err('incomplete template',defr) return [ elems , defns ] = ru rw = elems.split(' ') if len(rw) < 2: self._err('trivial template',defr) return le = [ ] for w in rw: # print ( 'w=' , w ) x = w.strip() lx = len(x) if lx == 0: self._err('null template element',defr) return if x[0] == '%': if lx > 1 and ellyChar.isLetter(x[1]): if lx > 2: if x[1] != '*': self._err('bad class ID',defr) return x = x.lower() le.append(x) if self._errcount > 0: return self.listing = le de = defns.split(' ') lde = len(de) if lde != 1 and lde != 3: self._err('bad template definition',defr) return syns = de[0] sems = de[1] if lde > 1 else None try: spec = syntaxSpecification.SyntaxSpecification(symtb,syns) semf = featureSpecification.FeatureSpecification(symtb,sems,True) except ellyException.FormatFailure: self._err('bad definition' , defr) return self.lstg = le self.catg = spec.catg self.synf = spec.synf.positive self.semf = semf.positive self.bias = int(de[2]) if lde > 1 else 0
def __init__(self, typ, fet, frs=_dfrs): """ initialization arguments: self - typ - syntactic type fet - syntactic features to set frs - to reset """ super(SplittingRule, self).__init__(typ, fet) self.ltfet = featureSpecification.FeatureSpecification(None) self.rtfet = featureSpecification.FeatureSpecification(None) self.sftr = frs self.rtyp = -1 self.nmrg = 2
def _FS ( symbls , featrs , ftype=False ): """ get ellyBits encoding of syntactic features arguments: syms - symbol table for feature names featrs - feature string ftype - True for semantic, False for syntactic returns: ellyBits object on success exceptions: FormatFailure on error """ return featureSpecification.FeatureSpecification(symbls,featrs,ftype).positive
def __init__ ( self , syms , spec ): """ initialization from input string and symbol table arguments: self - syms - current symbol table spec - input string exceptions: FormatFailure on error """ self.catg = -1 # values to set on an error self.synf = None # # print >> sys.stderr , 'specification=' , spec if spec == None: print >> sys.stderr , '** null syntax specification' raise ellyException.FormatFailure s = spec.lower() # must be lower case for all lookups n = 0 for c in s: if not ellyChar.isLetterOrDigit(c) and c != '.': break n += 1 if n == 0: print >> sys.stderr , '** no syntactic category' raise ellyException.FormatFailure typs = s[:n] # save category name # print >> sys.stderr , 'catg=' , self.catg catg = syms.getSyntaxTypeIndexNumber(typs) if catg == None: raise ellyException.FormatFailure s = s[n:].strip() # feature part of syntax if len(s) == 0: # check if there are any features synf = featureSpecification.FeatureSpecification(syms,None) if typs == '...': synf.id = '...' elif typs == '...': # ... category may have no features! raise ellyException.FormatFailure else: # decode features # print >> sys.stderr , 'syms=' , syms , 's=' , s if len(s) < 4: print >> sys.stderr , '** bad syntactic type or missing features= ' , typs+s raise ellyException.FormatFailure if typs in catid and catid[typs] != s[1]: print >> sys.stderr , '** type' , typs.upper() , 'has two feature IDs:' , catid[typs] , s[1] raise ellyException.FormatFailure catid[typs] = s[1] synf = featureSpecification.FeatureSpecification(syms,s) # FormatFailure exception may be raised above, but will not be caught here # print >> sys.stderr , 'success' self.catg = catg self.synf = synf
def _rightside(stb, txt, sta): """ process actions for a clause arguments: stb - symbol table txt - string input for single clause sta - for status reporting returns: action list on success, None otherwise """ # print ( "right side" ) actn = [] val = 0 cnc = '' # default is no concept specified m = txt.rfind(']') # look for semantic features to set or reset n = txt.rfind(' ') # look for space marking explicit concept # print ( 'n=',n ) # print ( "0 txt=[" , txt , "]" ) if n > m: # space must not be in semantic feature specification cnc = txt[n:].strip().upper() txt = txt[:n] # remove concept from right size of clause # print ( "1 txt=[" , txt , "]" ) if len(txt) > 1: if txt[0] == '*': # inherit from phrase component? c = txt[1] if c == 'l': actn.append([semanticCommand.Clhr]) sta.lh = True elif c == 'r': actn.append([semanticCommand.Crhr]) sta.rh = True else: return _err('bad inheritance') txt = txt[2:].strip() # print ( "2 txt=[" , txt , "]" ) if len(txt) > 3 and txt[0] == '[': n = txt.find(']') # set or unset semantic features for phrase? # print ( 'n=' , n ) if n < 3: return _err('incomplete semantic features to set or unset') try: f = featureSpecification.FeatureSpecification(stb, txt[:n + 1], semantic=True) sta.res = f except ellyException.FormatFailure: return _err('bad semantic features to set or unset') if sta.id[sS] == None: sta.id[sS] = f.id elif f.id != sta.id[sS]: _err('inconsistency: final features=' + txt[:n + 1]) return None # print ( 'features=' , f.positive , f.negative ) actn.append([semanticCommand.Csetf, f.positive]) if not f.negative.zeroed(): f.negative.complement() actn.append([semanticCommand.Crstf, f.negative]) # print ( 'set:' , actn[-1] ) txt = txt[n + 1:] # print ( "3 txt=[" , txt , "]" ) if len(txt) > 0: c = txt[0] # check for sign of plausibility change if c != '+' and c != '-': if ellyChar.isDigit(c): return _err('plausibility must begin with + or -') else: return _err('bad cognitive semantic action: ' + txt) # print ( "2 txt=[",txt,"]" ) if len(txt) == 1: val = 1 elif ellyChar.isDigit(txt[1]): try: val = int(txt[1:]) # explicit numerical change except ValueError: return _err('bad cognitive plausibility: ' + txt) elif c == txt[1]: # alternate notation for plausibility change val = 2 for xc in txt[2:]: if xc != c: return _err('must be all + or all -') val += 1 # count up value else: return _err('cannot interpret clause: ' + txt) if c == '-': val = -val # get right sign # print ( 'val=' , val ) if len(cnc) > 0: actn.append([semanticCommand.Csetc, cnc]) if val != 0: actn.append([semanticCommand.Cadd, val]) return actn
def _leftside(stb, txt, sta): """ process conditions for a clause and store arguments: stb - symbol table txt - string input for left side of single clause sta - for status reporting returns: predicate list on success, None otherwise """ # print ( "left side" ) pred = [] txt = txt.rstrip() while len(txt) > 0: txt = txt.lstrip() # print ( 'clause=' , txt ) if len(txt) <= 1: _err('malformed conditions for clause') return None side = txt[0] txt = txt[1:] if side in ['n', 'p', 'c']: sns = txt[0] txt = txt[1:] if sns != '<' and sns != '>': _err('invalid comparison in clause condition=' + sns) return None if side == 'n': op = semanticCommand.Cngt if sns == '>' else semanticCommand.Cnlt elif side == 'p': op = semanticCommand.Cpgt if sns == '>' else semanticCommand.Cplt else: op = semanticCommand.Ccgt if sns == '>' else semanticCommand.Cclt nd = 0 lt = len(txt) while nd < lt: if not ellyChar.isDigit(txt[nd]): break nd += 1 if nd == 0: _err('no token count for condition') return None test = int(txt[:nd]) txt = txt[nd:] pred.append([op, test]) continue if not side in ['l', 'r']: _err('invalid side for test=' + side) return None k = 0 if txt[0] == '[': # semantic feature check? k = txt.find(']') # if so, look for closing bracket if k < 0: return _err('incomplete semantic features to check') p = txt[:k + 1] # get semantic feature string # print ( "side:" , side , "test:" , p ) try: f = featureSpecification.FeatureSpecification(stb, p, semantic=True) except ellyException.FormatFailure: return _err('bad semantic features to check') if side == 'l': if sta.id[lS] == None: sta.id[lS] = f.id elif f.id != sta.id[lS]: _err('inconsistency: left features=' + p) return None else: if sta.id[rS] == None: sta.id[rS] = f.id elif f.id != sta.id[rS]: _err('inconsistency: right features=' + p) return None op = semanticCommand.Crhtf if side == 'r' else semanticCommand.Clftf if side == 'r': sta.rht = f else: sta.lft = f # print ( 'test:' , f.positive.hexadecimal() , f.negative.hexadecimal() ) test = ellyBits.join(f.positive, f.negative) # print ( test ) pred.append([op, test]) elif txt[0] == '(': # semantic concept check? # print ( "txt=\"" + txt +"\"" ) k = txt.find(')') # if so, look for closing parenthesis if k < 0: return _err('incomplete concept check') s = txt[1:k].strip().upper() # normalize concepts p = s.split(',') # allow for multiple disjunctive checks # print ( "p=\"" + p + "\"" ) op = semanticCommand.Crhtc if side == 'r' else semanticCommand.Clftc pred.append([op, p]) else: _err('unknown test in clause=' + side + txt) return None txt = txt[k + 1:].lstrip() # advance to next predicate # print ( "NEXT" ) return pred
# This information is redundant because every rule will be listed under its # respective Y type. The parsing algorithm implemented for Elly parse trees # will have all the information it needs. ########################################################################### # # unit test # if __name__ == '__main__': import symbolTable sym = symbolTable.SymbolTable() fs = featureSpecification.FeatureSpecification(sym, '[:f0,f1,-f2]') pf = fs.positive nf = fs.negative nf.complement() print('features=', pf, nf) r = [] for i in range(4): ru = ExtendingRule(0, pf, nf) r.append(ru) for i in range(4): ru = SplittingRule(0, pf, nf) r.append(ru) rr = ExtendingRule(0, pf) r.append(rr)
def __init__(self, syms, dfls): """ initialization arguments: self - syms - Elly grammatical symbol table dfls - definition elements in list exceptions: FormatFailure on error """ # print 'dfls=' , dfls ne = len(dfls) # print 'ne=' , ne if 3 > ne or ne > 5: # must have 3 to 5 elements raise ellyException.FormatFailure else: if dfls[0] == '\\0': self.patn = u'\x00' # special nul pattern elif ellyWildcard.numSpaces(list(dfls[0])) > 0: print >> sys.stderr, '** link pattern includes space:', dfls[0] raise ellyException.FormatFailure else: # print 'do conversion' self.patn = ellyWildcard.convert( dfls[0]) # encode Elly pattern # print 'patn=' , self.patn if dfls[0] != '$': if self.patn == None or ellyWildcard.minMatch(self.patn) == 0: print >> sys.stderr, '** bad link pattern:', dfls[0] raise ellyException.FormatFailure # print 'appended patn=' , list(self.patn) , '=' , len(self.patn) lastat = dfls[-1] self.catg = None # defaults self.synf = None # self.semf = None # self.bias = 0 # sss = dfls[1].lower() # assumed not to be Unicode # print 'sss=' , sss if sss != '-': # allow for no category syx = syntaxSpecification.SyntaxSpecification(syms, sss) if syx != None: if not lastat in ['-1', '-2' ]: # not a stop state for matching raise ellyException.FormatFailure # cannot have syntax here self.catg = syx.catg # syntactic category self.synf = syx.synf.positive # syntactic features if ne > 3: if lastat != '-1': # not a stop state for matching raise ellyException.FormatFailure # cannot have semantics here sss = None if dfls[2] == '-' else dfls[2].lower() else: sss = None # print 'semantic features=' , sss sem = featureSpecification.FeatureSpecification(syms, sss, True) self.semf = sem.positive # get semantic features # print 'semf=' , self.semf if ne > 4: try: self.bias = int(dfls[3]) except ValueError: raise ellyException.FormatFailure # unrecognizable bias try: n = int(lastat) # next state for link except ValueError: raise ellyException.FormatFailure # unrecognizable number # print 'transition=' , n if n < 0: # final transition? if self.patn == u'\x00': raise ellyException.FormatFailure # final state not allowed here if n == -1: pe = self.patn[-1] # if so, get last pattern element if (pe != ellyWildcard.cALL and # final pattern must end with * or $ pe != ellyWildcard.cEND): self.patn += ellyWildcard.cEND # default is $ print >> sys.stderr, '** final $ added to pattern', list( self.patn) self.nxts = n # specify next state