2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-11-26 03:19:48 +00:00
confluent/confluent/noderange.py
2013-08-16 16:37:19 -04:00

66 lines
2.6 KiB
Python

# this will implement noderange grammar
# considered ast, but a number of things violate python grammar like [] in
# the middle of strings and use of @ for anything is not in their syntax
#construct custom grammer with pyparsing
#>>> grammar = pyparsing.Word(pyparsing.alphanums+'/', pyparsing.alphanums+'[]-.*') | ',-' | ',' | '@'
#>>> parser = pyparsing.nestedExpr('(',')',content=grammar)
#>>> parser.parseString("(n1-n4,compute,(foo@bar),-bob,bob)").asList()
#[['n1-n4', ',', 'compute', ',', ['foo', '@', 'bar'], ',-', 'bob', ',', 'bob']]
import pyparsing
import re
class NodeRange(object):
"""Iterate over a noderange
:param noderange: string representing a noderange to evaluate
:param verify: whether or not to perform lookups in the config
"""
_grammar = \
pyparsing.Word(
pyparsing.alphanums + '=', pyparsing.alphanums + '[]-.*+') | \
',-' | ',' | '@'
_parser = pyparsing.nestedExpr(content=_grammar)
def __init__(self, noderange, verify=True):
self.verify = verify
elements = self._parser.parseString("(" + noderange + ")").asList()
self._noderange = self._evaluate(elements)
print self._noderange
def _evaluate(self, parsetree):
current_op = 0 # enum, 0 union, 1 subtract, 2 intersect
current_range = set([])
if not isinstance(parsetree,list): # down to a plain text thing
return self._expandstring(parsetree)
for elem in parsetree:
if elem == ',-':
current_op = 1
elif elem == ',':
current_op = 0
elif elem == '@':
current_op = 2
elif current_op == 0:
current_range |= self._evaluate(elem)
elif current_op == 1:
current_range -= self._evaluate(elem)
elif current_op == 2:
current_range &= self._evaluate(elem)
return current_range
def _expandstring(self, element):
if self.verify:
#this is where we would check for exactly this
raise Exception("TODO: link with actual config")
#this is where we would check for a literal groupname
#ok, now time to understand the various things
if '[' in element: #[] style expansion
raise Exception("TODO: [] in expression")
elif '-' in element: # *POSSIBLE* range, could just be part of name
raise Exception("TODO: ranged expression")
elif ':' in element: # : range for less ambiguity
raise Exception("TODO: ranged expression")
if not self.verify:
return set([element])