Python pyparsing 模块,OneOrMore() 实例源码
我们从Python开源项目中,提取了以下32个代码示例,用于说明如何使用pyparsing.OneOrMore()。
def parser(self):
join_type = (pp.Literal("LEFT") | pp.Literal("RIGHT") | pp.Literal("INNER") | pp.Literal("OUTER"))
node_name = pp.Word(pp.alphas, pp.alphanums + "_$")
col_name = pp.Word(pp.alphas, pp.alphanums + "_$")
col_name_list = pp.Group(pp.delimitedList(col_name, delim=","))
l_brac = pp.Suppress("[")
r_brac = pp.Suppress("]")
single_join = (join_type + pp.Suppress("(") + node_name + l_brac +
col_name_list + r_brac + pp.Suppress("==>") + node_name +
l_brac + col_name_list + r_brac + pp.Suppress(")"))
single_join.addParseAction(lambda x: self._add_join(join_type=x[0],
child_node_name=x[1],
child_cols=x[2],
parent_node_name=x[3],
parent_cols=x[4]))
join_block = pp.OneOrMore(single_join)
return join_block
def lexical_analysis(self, src):
delimited = re.sub(r'\s+', ' ', ' '.join(src.strip().split('\n'))).split(';')
result = []
for stmt in delimited:
if stmt == '':
return result
string = pp.Regex('[a-zA-Z0-9=_]+')
nums = pp.Regex('[0-9]+')
ws = pp.OneOrMore(pp.White()).suppress()
lp = pp.Regex('[(]').suppress()
rp = pp.Regex('[)]').suppress()
c = pp.Regex('[,]').suppress()
q = pp.Regex("[']").suppress()
table_name = string.setResultsName('table_name')
create_table = (pp.Keyword('CREATE', caseless = True) + ws + pp.Keyword('TABLE', caseless = True) + ws + pp.Optional(pp.Keyword('IF', caseless = True) + ws + pp.Keyword('NOT', caseless = True) + ws + pp.Keyword('EXISTS', caseless = True))).suppress() + table_name + lp
column_name = string.setResultsName('column_name')
data_type = string.setResultsName('data_type')
length = lp + nums.setResultsName('length') + rp
nullable = (pp.Optional(pp.Keyword('NOT', caseless = True) + ws) + pp.Keyword('NULL', caseless = True)).setResultsName('nullable')
default_value = pp.Keyword('DEFAULT', caseless = True).suppress() + ws + string.setResultsName('default_value')
auto_increment = pp.Keyword('AUTO_INCREMENT', caseless = True).setResultsName('auto_increment')
column = pp.Optional(ws) + column_name + ws + data_type + pp.Optional(pp.MatchFirst([length, ws + nullable, ws + default_value, ws + auto_increment])) + pp.Optional(pp.MatchFirst([ws + nullable, ws + auto_increment])) + pp.Optional(pp.MatchFirst([ws + default_value, ws + auto_increment])) + pp.Optional(ws + auto_increment) + pp.Optional(ws) + c
primary_key = pp.Keyword('PRIMARY KEY', caseless = True).suppress() + lp + pp.OneOrMore(q + string.setResultsName('primary_key') + q + pp.Optional(c)) + rp + pp.Optional(c)
key = pp.Keyword('KEY', caseless = True).suppress() + lp + q + string.setResultsName('key') + q + pp.Optional(c) + rp + pp.Optional(c)
parser = create_table + pp.OneOrMore(pp.Group(column)) + pp.Optional(primary_key) + pp.Optional(key) + rp + pp.OneOrMore(ws + string).suppress()
result.append(parser.parseString(stmt, parseAll=True))
return result
def _parse_atat_lattice(lattice_in):
"""Parse an ATAT-style `lat.in` string.
The parsed string will be in three groups: (Coordinate system) (lattice) (atoms)
where the atom group is split up into subgroups,each describing the position and atom name
"""
float_number = Regex(r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?').setParseAction(lambda t: [float(t[0])])
vector = Group(float_number + float_number + float_number)
angles = vector
vector_line = vector + Suppress(LineEnd())
coord_sys = Group((vector_line + vector_line + vector_line) | (vector + angles + Suppress(LineEnd())))
lattice = Group(vector + vector + vector)
atom = Group(vector + Group(OneOrMore(Word(alphas + '_'))))
atat_lattice_grammer = coord_sys + lattice + Group(OneOrMore(atom))
# parse the input string and convert it to a POSCAR string
return atat_lattice_grammer.parseString(lattice_in)
def parser(self):
connector_name = pp.Word(pp.alphas, pp.alphanums + "_$")
connector_type = pp.Word(pp.alphas)
connector_kwarg = (pp.Word(pp.alphas, pp.alphanums + "_$") + pp.Suppress("=") + pp.QuotedString(quoteChar="'"))
connector_kwarg.setParseAction(lambda x: {x[0]: x[1]})
conn_kwarg_list = pp.delimitedList(connector_kwarg)
conn_kwarg_list.setParseAction(lambda x: dict(pair for d in x for pair in d.items()))
single_connector = (connector_name + pp.Suppress("<-") + connector_type +
pp.Suppress("(") + conn_kwarg_list + pp.Suppress(")"))
single_connector.setParseAction(lambda x: self._add_connector(conn_name=x[0],
conn_type=x[1],
conn_kwargs=x[2]))
connector_block = pp.OneOrMore(single_connector)
return connector_block
def expression(self):
expression = pyparsing.Forward()
# (1 + (2 + 3))
nested_expression = pyparsing.nestedExpr(
"(", ")", expression).setParseAction(self._combine_lists)
# FOO(2,3)
function_call = (
_TOKEN().setResultsName("function")
+ _OPEN_PARENTHESIS()
+ pyparsing.delimitedList(
pyparsing.Combine(expression, adjacent=False, joinString=" "),
delim=",").setResultsName("func_args")
+ _CLOSE_PARENTHESIS()
)
expression << pyparsing.OneOrMore(
function_call.setParseAction(self._is_kNown_function)
| pyparsing.Group(nested_expression)
| _TOKEN()
| _NOT_TOKEN()
)
return pyparsing.Combine(expression, joinString=" ")
def lexical_analysis(self, src):
string = pp.Regex('[a-zA-Z0-9_{}"=+\-*/\.:;&%@$#<>? ?-??-??-???-???????-?]+')
blank = pp.Linestart() + pp.LineEnd()
start = '['
end = ']' + pp.LineEnd()
graph_tag = pp.Linestart() + '@'
graph = graph_tag + start + string + end
view_tag = pp.Linestart() + '#'
view = view_tag + start + string + end
server_process_tag = pp.Linestart() + '$'
server_process = server_process_tag + start + string + end
client_process_tag = pp.Linestart() + '%'
client_process = client_process_tag + start + string + end
view_transition_identifier = pp.Linestart() + '-->'
view_transition = view_transition_identifier + string
process_transition_identifier = pp.Linestart() + '==>'
process_transition = process_transition_identifier + string
state_machine = pp.OneOrMore(graph | view | server_process | client_process | view_transition | process_transition | string | blank)
return state_machine.parseString(src)
def make_grammar():
"""Creates the grammar to be used by a spec matcher."""
# This is apparently how pyparsing recommends to be used,
# as http://pyparsing.wikispaces.com/share/view/644825 states that
# it is not thread-safe to use a parser across threads.
unary_ops = (
# Order matters here (so that '=' doesn't match before '==')
Literal("==") | Literal("=") |
Literal("!=") | Literal("<in>") |
Literal(">=") | Literal("<=") |
Literal(">") | Literal("<") |
Literal("s==") | Literal("s!=") |
# Order matters here (so that '<' doesn't match before '<=')
Literal("s<=") | Literal("s<") |
# Order matters here (so that '>' doesn't match before '>=')
Literal("s>=") | Literal("s>"))
or_ = Literal("<or>")
# An atom is anything not an keyword followed by anything but whitespace
atom = ~(unary_ops | or_) + Regex(r"\S+")
unary = unary_ops + atom
disjunction = OneOrMore(or_ + atom)
# Even-numbered tokens will be '<or>',so we drop them
disjunction.setParseAction(lambda _s, _l, t: ["<or>"] + t[1::2])
expr = disjunction | unary | atom
return expr
def getchunk():
"""
Using pyparsing,create chunk reader for chunk strings.
"""
slot = pp.Word("".join([pp.alphas, "_"]), "".join([pp.alphanums, "_"]))
special_value = pp.Group(pp.oneOf([ACTRVARIABLE, "".join([ACTRNEG, ACTRVARIABLE]), ACTRNEG, VISIONGREATER, VISIONSMALLER, "".join([VISIONGREATER, "".join([VISIONSMALLER, ACTRVARIABLE])])\
+ pp.Word("".join([pp.alphanums, "_", '"', "'"])))
strvalue = pp.QuotedString('"', unquoteResults=False)
strvalue2 = pp.QuotedString("'", unquoteResults=False)
varvalue = pp.Word("".join([pp.alphanums, "_"]))
value = varvalue | special_value | strvalue | strvalue2
chunk_reader = pp.OneOrMore(pp.Group(slot + value))
return chunk_reader
def getrule():
"""
Using pyparsing,get rule out of a string.
"""
arrow = pp.Literal("==>")
buff = pp.Word(pp.alphas, "_"]))
special_valueLHS = pp.oneOf([x for x in _LHSCONVENTIONS.keys()])
end_buffer = pp.Literal(">")
special_valueRHS = pp.oneOf([x for x in _RHSCONVENTIONS.keys()])
chunk = getchunk()
rule_reader = pp.Group(pp.OneOrMore(pp.Group(special_valueLHS + buff + end_buffer + pp.Group(pp.Optional(chunk))))) + arrow + pp.Group(pp.OneOrMore(pp.Group(special_valueRHS + buff + end_buffer + pp.Group(pp.Optional(chunk)))))
return rule_reader
def parse_search_query(query):
unicode_printables = u''.join(unichr(c) for c in xrange(65536) if not unichr(c).isspace())
word = TextNode.group(Word(unicode_printables))
exact = ExactNode.group(QuotedString('"', unquoteResults=True, escChar='\\'))
term = exact | word
comparison_name = Word(unicode_printables, excludeChars=':')
comparison = ComparisonNode.group(comparison_name + Literal(':') + term)
content = OneOrMore(comparison | term)
return content.parseString(query)
def __init__(self, rule):
self.rule = rule
self.opener = self.rule['opener']
self.closer = self.rule['closer']
self.columns = self.rule.get('columns', -1)
nested = nestedExpr(opener=self.opener, closer=self.closer,
content=Charsnotin(self.opener + self.closer))
if self.columns < 0:
self.nested = OneOrMore(nested)
else:
self.nested = nested * self.columns + Or([Charsnotin('\n'), Empty()])
def __init__(self):
nest = pypar.nestedExpr
g = pypar.Forward()
nestedParens = nest('(', ')')
nestedBrackets = nest('[', ']')
nestedCurlies = nest('{', '}')
nest_grammar = nestedParens | nestedBrackets | nestedCurlies
parens = "(){}[]"
letters = ''.join([x for x in pypar.printables
if x not in parens])
word = pypar.Word(letters)
g = pypar.OneOrMore(word | nest_grammar)
self.grammar = g
def __init__(self):
real_word_dashes = Word(pyparsing.alphas + '-')
punctuation = Word('.!?:,;-')
punctuation_no_dash = Word('.!?:,;')
punctuation_reference_letter = Word('.:,;-')
printable = Word(pyparsing.printables, exact=1)
letter = Word(pyparsing.alphas, exact=1)
letter_reference = punctuation_reference_letter + letter
nums = Word(pyparsing.nums) + Optional(letter) + \
ZeroOrMore(letter_reference)
word_end = pyparsing.ZeroOrMore(Word(')') | Word('}') | Word(']')) + \
WordEnd()
self.single_number = (
WordStart() +
real_word_dashes +
nums +
word_end
)
self.single_number_parens = (
printable +
letter +
Optional(punctuation_no_dash) +
pyparsing.OneOrMore(
Word('([{', exact=1) +
pyparsing.OneOrMore(nums | Word('-')) +
Word(')]}', exact=1)
) +
word_end
)
self.number_then_punctuation = (
printable +
letter +
nums +
punctuation +
pyparsing.ZeroOrMore(nums | punctuation) +
word_end
)
self.punctuation_then_number = (
printable +
letter +
punctuation_no_dash +
nums +
pyparsing.ZeroOrMore(punctuation | nums) +
word_end
)
def __init__(self):
nest = pypar.nestedExpr
g = pypar.Forward()
nestedParens = nest('(', '}')
nest_grammar = nestedParens | nestedBrackets | nestedCurlies
parens = "(){}[]"
letters = ''.join([x for x in pypar.printables
if x not in parens])
word = pypar.Word(letters)
g = pypar.OneOrMore(word | nest_grammar)
self.grammar = g
def main():
word = Word(alphanums)
command = Group(OneOrMore(word))
token = Suppress("->")
device = Group(OneOrMore(word))
argument = Group(OneOrMore(word))
event = command + token + device + Optional(token + argument)
gate = Gate()
garage = Garage()
airco = Aircondition()
heating = Heating()
boiler = Boiler()
fridge = Fridge()
tests = ('open -> gate',
'close -> garage',
'turn on -> aircondition',
'turn off -> heating',
'increase -> boiler temperature -> 5 degrees',
'decrease -> fridge temperature -> 2 degrees')
open_actions = {'gate':gate.open, 'garage':garage.open, 'aircondition':airco.turn_on,
'heating':heating.turn_on, 'boiler temperature':boiler.increase_temperature,
'fridge temperature':fridge.increase_temperature}
close_actions = {'gate':gate.close, 'garage':garage.close, 'aircondition':airco.turn_off,
'heating':heating.turn_off, 'boiler temperature':boiler.decrease_temperature,
'fridge temperature':fridge.decrease_temperature}
for t in tests:
if len(event.parseString(t)) == 2: # no argument
cmd, dev = event.parseString(t)
cmd_str, dev_str = ' '.join(cmd), ' '.join(dev)
if 'open' in cmd_str or 'turn on' in cmd_str:
open_actions[dev_str]()
elif 'close' in cmd_str or 'turn off' in cmd_str:
close_actions[dev_str]()
elif len(event.parseString(t)) == 3: # argument
cmd, dev, arg = event.parseString(t)
cmd_str, dev_str, arg_str = ' '.join(cmd), ' '.join(dev), ' '.join(arg)
num_arg = 0
try:
num_arg = int(arg_str.split()[0]) # extract the numeric part
except ValueError as err:
print("expected number but got: '{}'".format(arg_str[0]))
if 'increase' in cmd_str and num_arg > 0:
open_actions[dev_str](num_arg)
elif 'decrease' in cmd_str and num_arg > 0:
close_actions[dev_str](num_arg)
def build_parser(self):
parsed_term = pyparsing.Group(pyparsing.Combine(pyparsing.Word(pyparsing.alphanums) + \
pyparsing.Suppress('*'))).setResultsName('wildcard') | \
pyparsing.Group(pyparsing.Combine(pyparsing.Word(pyparsing.alphanums+"._") + \
pyparsing.Word(':') + pyparsing.Group(pyparsing.Optional("\"") + \
pyparsing.Optional("<") + pyparsing.Optional(">") + pyparsing.Optional("=") + \
pyparsing.Optional("-") + pyparsing.Word(pyparsing.alphanums+"._/") + \
pyparsing.Optional("&") + pyparsing.Optional("<") + pyparsing.Optional(">") + \
pyparsing.Optional("=") + pyparsing.Optional("-") + \
pyparsing.Optional(pyparsing.Word(pyparsing.alphanums+"._/")) + \
pyparsing.Optional("\"")))).setResultsName('fields') | \
pyparsing.Group(pyparsing.Combine(pyparsing.Suppress('-')+ \
pyparsing.Word(pyparsing.alphanums+"."))).setResultsName('not_term') | \
pyparsing.Group(pyparsing.Word(pyparsing.alphanums)).setResultsName('term')
parsed_or = pyparsing.Forward()
parsed_quote_block = pyparsing.Forward()
parsed_quote_block << ((parsed_term + parsed_quote_block) | parsed_term )
parsed_quote = pyparsing.Group(pyparsing.Suppress('"') + parsed_quote_block + \
pyparsing.Suppress('"')).setResultsName("quotes") | parsed_term
parsed_parenthesis = pyparsing.Group((pyparsing.Suppress("(") + parsed_or + \
pyparsing.Suppress(")"))).setResultsName("parenthesis") | parsed_quote
parsed_and = pyparsing.Forward()
parsed_and << (pyparsing.Group(parsed_parenthesis + pyparsing.Suppress(pyparsing.Keyword("and")) + \
parsed_and).setResultsName("and") | \
pyparsing.Group(parsed_parenthesis + pyparsing.OneOrMore(~pyparsing.oneOf("or and") + \
parsed_and)).setResultsName("and") | parsed_parenthesis)
parsed_or << (pyparsing.Group(parsed_and + pyparsing.Suppress(pyparsing.Keyword("or")) + \
parsed_or).setResultsName("or") | parsed_and)
return parsed_or.parseString
def OperationsSchema(v):
if isinstance(v, six.text_type):
try:
v = pyparsing.OneOrMore(
pyparsing.nestedExpr()).parseString(v).asList()[0]
except pyparsing.ParseException as e:
api.abort(400, {"cause": "Invalid operations",
"reason": "Fail to parse the operations string",
"detail": six.text_type(e)})
return voluptuous.Schema(voluptuous.Any(*OperationsSchemaBase),
required=True)(v)
def parser(self):
query_key = pp.Keyword("QUERY")
query_value = pp.Suppress("|") + pp.SkipTo(pp.Suppress(";"), include=True)
fields_key = pp.Keyword("FIELDS")
field_name = common_parsers.column
field_name_list = pp.Group(pp.delimitedList(field_name,")).setParseAction(lambda x: x.asList())
fields_block = (pp.Suppress(fields_key) + field_name_list)
connector_name = pp.Word(pp.alphas, pp.alphanums + "_$")
using_block = pp.Suppress("USING") + connector_name
then_key = pp.Suppress("THEN")
manipulation_set = pp.Suppress("|") + pp.SkipTo(pp.Suppress(";"), include=True)
then_block = then_key + manipulation_set
as_key = pp.Suppress("AS")
node_name = pp.Word(pp.alphas, pp.alphanums + "_$")
as_block = as_key + node_name
query_node_block = (pp.Suppress(query_key) + query_value + pp.Optional(fields_block, default=None) + using_block + pp.Optional(then_block, default=None) + as_block)
query_node_block.setParseAction(lambda x: self._add_query_node(query_value=x[0],
connector_name=x[2],
node_name=x[4],
fields=x[1],
manipulation_set=x[3]))
single_query_node = query_node_block + pp.Optional(pp.Suppress("---"))
retrieve_block = pp.OneOrMore(single_query_node)
return retrieve_block
def _element(self):
"""The parser for all elements."""
self.element = pyparsing.Forward()
self.element << (
(~_TYPEDEF) + (
# e.g. int x;
self._type_name_with_fields()
# e.g. struct s {};
| self._struct_deFinition_possibly_with_fields()
# e.g. enum foo { OPTION = 1 + 2; };
| self._enum_deFinition()
| pyparsing.OneOrMore(_SEMICOLON)
)
)
return self.element.setName("element")
def __init__(self):
real_word_dashes = Word(pyparsing.alphas + '-')
punctuation = Word('.!?:, exact=1)
) +
word_end
)
self.number_then_punctuation = (
printable +
letter +
nums +
punctuation +
pyparsing.ZeroOrMore(nums | punctuation) +
word_end
)
self.punctuation_then_number = (
printable +
letter +
punctuation_no_dash +
nums +
pyparsing.ZeroOrMore(punctuation | nums) +
word_end
)
def main():
word = Word(alphanums)
command = Group(OneOrMore(word))
token = Suppress("->")
device = Group(OneOrMore(word))
argument = Group(OneOrMore(word))
event = command + token + device + Optional(token + argument)
gate = Gate()
garage = Garage()
airco = Aircondition()
heating = Heating()
boiler = Boiler()
fridge = Fridge()
tests = ('open -> gate',
'increase -> boiler temperature -> 20 degrees',
'decrease -> fridge temperature -> 6 degree')
open_actions = {'gate':gate.open, ' '.join(arg)
num_arg = 0
try:
num_arg = int(arg_str.split()[0]) # extract the numeric part
except ValueError as err:
print("expected number but got: '{}'".format(arg_str[0]))
if 'increase' in cmd_str and num_arg > 0:
open_actions[dev_str](num_arg)
elif 'decrease' in cmd_str and num_arg > 0:
close_actions[dev_str](num_arg)
def main():
word = Word(alphanums)
command = Group(OneOrMore(word))
token = Suppress("->")
device = Group(OneOrMore(word))
argument = Group(OneOrMore(word))
event = command + token + device + Optional(token + argument)
gate = Gate()
garage = Garage()
airco = Aircondition()
heating = Heating()
boiler = Boiler()
fridge = Fridge()
tests = ('open -> gate',
'decrease -> fridge temperature -> 2 degrees')
open_actions = {'gate': gate.open,
'garage': garage.open,
'aircondition': airco.turn_on,
'heating': heating.turn_on,
'boiler temperature': boiler.increase_temperature,
'fridge temperature': fridge.increase_temperature}
close_actions = {'gate': gate.close,
'garage': garage.close,
'aircondition': airco.turn_off,
'heating': heating.turn_off,
'boiler temperature': boiler.decrease_temperature,
'fridge temperature': fridge.decrease_temperature}
for t in tests:
if len(event.parseString(t)) == 2: # ????
cmd, ' '.join(dev)
if 'open' in cmd_str or 'turn on' in cmd_str:
open_actions[dev_str]()
elif 'close' in cmd_str or 'turn off' in cmd_str:
close_actions[dev_str]()
elif len(event.parseString(t)) == 3: # ???
cmd, ' '.join(arg)
num_arg = 0
try:
num_arg = int(arg_str.split()[0]) # ??????
except ValueError as err:
print("expected number but got: '{}'".format(arg_str[0]))
if 'increase' in cmd_str and num_arg > 0:
open_actions[dev_str](num_arg)
elif 'decrease' in cmd_str and num_arg > 0:
close_actions[dev_str](num_arg)
def strings_section():
return pyparsing.Group(
pyparsing.Literal("strings") +
_COLON +
pyparsing.OneOrMore(statement()).setResultsName("statements")
).setResultsName("strings")
def rule():
return (_RULE +
_IDENTIFIER.setResultsName("name") +
_LEFT_CURLY +
pyparsing.OneOrMore(section()) +
_RIGHT_CURLY)
def static_function(self):
return (
(pyparsing.Keyword("static") | pyparsing.Keyword("inline"))
+ pyparsing.OneOrMore(pyparsing.Word(pyparsing.alphanums + "_*&"))
+ parsers.anything_in_parentheses()
+ parsers.anything_in_curly()
).suppress()
def grammar():
"""Define the query grammar.
Backus-Naur form (BNF) of the grammar::
<grammar> ::= "*" | <items>
<items> ::= <item> | <item> <whitespace> <items>
<item> ::= <key>:<value>
Given that the pyparsing library defines the grammar in a BNF-like style,for the details of the tokens not
specified above check directly the source code.
Returns:
pyparsing.ParserElement: the grammar parser.
"""
quoted_string = pp.quotedString.copy().addParseAction(pp.removeQuotes) # Both single and double quotes are allowed
# Key-value tokens: key:value
# Lowercase key,all printable characters except the parentheses that are part of the global grammar for the value
key = pp.Word(pp.srange('[a-z0-9-_.]"'), min=2)('key')
all_but_par = ''.join([c for c in pp.printables if c not in ('(', ')', '{', '}')])
value = (quoted_string | pp.Word(all_but_par))('value')
item = pp.Combine(key + ':' + value)
# Final grammar,see the docstring for its BNF based on the tokens defined above
# Groups are used to split the parsed results for an easy access
return pp.Group(pp.Literal('*')('all')) | pp.OneOrMore(pp.Group(item))
def parse_table(attribute, string):
Line = OneOrMore(Float)('data') + Literal(';') + Optional(Comments, default='')('name')
Grammar = Suppress(Keyword('mpc.{}'.format(attribute)) + Keyword('=') + Keyword('[') + Optional(Comments)) + OneOrMore(Group(Line)) + Suppress(Keyword(']') + Optional(Comments))
result, i, j = Grammar.scanString(string).next()
_list = list()
for r in result:
_list.append([int_else_float_except_string(s) for s in r['data'].asList()])
return _list
def __init__(self, comm_file_path):
expression_spaced = Forward()
expression = Forward()
args_spaced = Forward()
cb = Optional(',') + ')' # closing_brackets might include a ','
ob = Optional(' ') + '(' + Optional(' ') # closing_brackets might include a ' '
value = (Or([pyparsing_common.identifier.copy().setResultsName('id'),
pyparsing_common.number.copy().setResultsName('number'),
QuotedString("'").setResultsName('string')])).setParseAction(Value).setResultsName('value')
values = (ZeroOrMore(value.setResultsName('valueList', listAllMatches=True) + Optional(','))).setParseAction(
Values)
keyword = pyparsing_common.identifier.copy()
keyword_argument = (
keyword.setResultsName('keyword') + '=' + expression_spaced.setResultsName('expression')
).setParseAction(Keyword_argument)
keyword_arguments = (
keyword_argument.setResultsName('keyword_argument', listAllMatches=True) +
ZeroOrMore(',' + keyword_argument.setResultsName('keyword_argument', listAllMatches=True))
).setParseAction(Keyword_arguments)
expression << (Or([
value, (ob + values.setResultsName('values') + cb),
'_F' + ob + keyword_arguments.setResultsName('keyword_arguments') + cb,
ob + expression.setResultsName('expression') + cb
])).setParseAction(Expression)
expression_spaced << (Or([expression, ob + expression_spaced + cb]))
left_side = pyparsing_common.identifier.setResultsName('left_side')
operator_name = pyparsing_common.identifier.setResultsName('operator_name')
paragraph = (Optional(left_side + "=") + operator_name + ob + Optional(keyword_arguments
.setResultsName(
'keyword_arguments')) + cb + Optional(';')).setParseAction(Paragraph)
file = OneOrMore(paragraph).setResultsName('paragraphs').setParseAction(File)
self.beam_data_model = file.parseFile(comm_file_path)
def parseSelector(selectorstring):
# *select = @attr1 | /tf1/@attr | @attr1//objtype
"""
def enumtype(*args,**kwargs): #s,l,t,selectortype=None):
print(args)
selectortype = kwargs['selectortype']
if selectortype is None or not isinstance(selectortype,str):
raise ValueError('enumtype requires a selectortype string but got a',type(selectortype))
return selectortype
"""
def attrtype():
return AttrSelector() # 'ATTRTYPE'
def fullpathtype():
return FullPathSelector() #'FULLPATH'
def attrbyobjtype():
return AttrByObjectSelector() #'ATTRBYOBJECT'
def attrexpr(selectorstring=None):
attrmatch = p.Combine(p.Literal('@').suppress() + p.Word(p.alphanums))
return attrmatch.searchString(selectorstring)[0][0]
def expr(selectorstring=None, returntype=False):
attrmatch = p.Combine(p.Literal('@').suppress() + p.Word(p.alphanums))
fullpathmatch = p.Combine(p.OneOrMore(p.Literal('/') + p.Word(p.alphanums))) + p.Literal(
'/').suppress() + p.Combine(p.Literal('@').suppress() + p.Word(p.alphanums))
attrbyobjmatch = p.Combine(p.Literal('@').suppress() + p.Word(p.alphanums)) + p.Literal('//').suppress() + p.Word(p.alphanums)
matchgroup = (fullpathmatch | attrbyobjmatch | attrmatch)
if returntype:
attrmatch.setParseAction(attrtype)
fullpathmatch.setParseAction(fullpathtype)
attrbyobjmatch.setParseAction(attrbyobjtype)
return matchgroup.parseString(selectorstring)
_selectorconfig = expr(selectorstring=selectorstring)
_selectortype = expr(selectorstring=selectorstring, returntype=True)
_selectorattr = attrexpr(selectorstring=selectorstring)
return {
'type': _selectortype[0],
'config': _selectorconfig[:2], #Todo unclear why [0] returns only a subset of the matches
'attribute': _selectorattr
}
def __init__(self, obj, config=str()):
def process(config):
pathexpr = p.Literal("'").suppress() + \
p.Optional(
p.Combine(
p.OneOrMore(p.Literal("/") + p.Word(p.alphanums)) + p.Literal("/").suppress()
)
).setResultsName('path') + \
p.Combine(
(p.Literal('@').suppress() | p.Literal('!').suppress()) +
p.Word(p.alphanums) +
p.Literal("'").suppress()
).setResultsName('attrib')
expr = p.Group(pathexpr).setResultsName('search')
match = expr.parseString(config)
_ret = []
if 'search' in match:
if 'path' in match['search']:
_ret.append(match['search']['path'])
if 'attrib' in match['search']:
_ret.append(match['search']['attrib'])
return _ret
super(Xattrib, self).__init__(obj, config=config, defer=True)
if self.config is None or len(self.config) < 1 or not isinstance(self.config, str):
raise ValueError('Xattrib plugin function requires a config string')
try:
_result = process("'%s'" % self.config)
if len(_result) == 2:
self.targetobject, self.targetattribute = _result
elif len(_result) == 1:
_config = getattr(obj, _result[0], None)
if _config is None:
raise ValueError('Xattrib plugin received an attribute name that does not exist')
# Todo len check only required for attributes,but not method plugins
if len(_config) > 1:
raise ValueError('Xattrib plugin received a attribute name that contains multiple values')
self.targetobject, self.targetattribute = process("'%s'" % _config[0])
else:
raise Exception()
except:
raise ValueError('An error occured when processing the search string for the Xattrib plugin function')