Package gavo :: Package adql :: Module tree
[frames] | no frames]

Source Code for Module gavo.adql.tree

 1  """ 
 2  Trees of ADQL expressions and operations on them. 
 3  """ 
 4   
 5  #c Copyright 2008-2019, the GAVO project 
 6  #c 
 7  #c This program is free software, covered by the GNU GPL.  See the 
 8  #c COPYING file in the source distribution. 
 9   
10   
11  from __future__ import print_function 
12   
13  from gavo import utils 
14  from gavo.adql import grammar 
15  from gavo.adql import nodes 
16   
17  _grammarCache = None 
18   
19   
20  _additionalNodes = [] 
21 -def registerNode(node):
22 """registers a node class or a symbolAction from a module other than node. 23 24 This is a bit of magic -- some module can call this to register a node 25 class that is then bound to some parse action as if it were in nodes. 26 27 I'd expect this to be messy in the presence of chaotic imports (when 28 classes are not necessarily singletons and a single module can be 29 imported more than once. For now, I ignore this potential bomb. 30 """ 31 _additionalNodes.append(node)
32 33
34 -def getTreeBuildingGrammar():
35 """returns a pyparsing symbol that can parse ADQL expressions into 36 simple trees of ADQLNodes. 37 38 This symbol is shared, so don't change anything on it. 39 """ 40 # To do the bindings, we iterate over the names in the node module, look for 41 # all children classes derived from nodes.ADQLNode (but not ADQLNode itself) and 42 # first check for a bindings attribute and then their type attribute. These 43 # are then used to add actions to the corresponding symbols. 44 45 global _grammarCache 46 if _grammarCache: 47 return _grammarCache 48 syms, root = grammar.getADQLGrammarCopy() 49 50 def bind(symName, nodeClass): 51 try: 52 if getattr(nodeClass, "collapsible", False): 53 syms[symName].addParseAction(lambda s, pos, toks: 54 nodes.autocollapse(nodeClass, toks)) 55 else: 56 syms[symName].addParseAction(lambda s, pos, toks: 57 nodeClass.fromParseResult(toks)) 58 except KeyError: 59 raise utils.logOldExc( 60 KeyError("%s asks for non-existing symbol %s"%( 61 nodeClass.__name__ , symName)))
62 63 def bindObject(ob): 64 if isinstance(ob, type) and issubclass(ob, nodes.ADQLNode): 65 for binding in getattr(ob, "bindings", [ob.type]): 66 if binding: 67 bind(binding, ob) 68 if hasattr(ob, "parseActionFor"): 69 for sym in ob.parseActionFor: 70 bind(sym, ob) 71 72 for name in dir(nodes): 73 bindObject(getattr(nodes, name)) 74 75 for ob in _additionalNodes: 76 bindObject(ob) 77 78 _grammarCache = syms, root 79 return syms, root 80 81 82 if __name__=="__main__": 83 print(getTreeBuildingGrammar()[1].parseString( 84 "select UCDCOL('phys.mass') from misc" 85 )[0].asTree()) 86