python - How to parse F5 bigip.conf using pyparsing -
am trying figure out how use nifty lib parse bigip config files... grammar should,be this:
stanza :: name { content } name :: several words, might contain alphas nums dot dash underscore or slash content:: stanza or zeroormore(printable characters)
to make things more complicated, 1 exception:
if name starts "rule ", content cannot "stanza"
i started this:
from pyparsing import * def parse(config): def bnf(): """ example: ... ltm virtual /common/vdi.uis.test.com_80_vs { destination /common/1.2.3.4:80 http-class { /common/http2https } ip-protocol tcp mask 255.255.255.255 profiles { /common/http { } /common/tcp { } } vlans-disabled } ... """ lcb, rcb, slash, dot, underscore, dash = [c c in '{}/._-'] name_word = word(alphas + nums + dot + underscore + slash + dash) name = oneormore(name_word).setresultsname("name") stanza = forward() content = oneormore(stanza | zeroormore(oneormore(word(printables)))).setresultsname("content") stanza << group(name + lcb + content + rcb).setresultsname("stanza") return stanza return [x x in bnf().scanstring(config)]
the code above seems lock in infinite loop. missing requirement excluding looking 'stanza" if "name" starts "rule ".
oneormore(zeroormore(oneormore(word(printables))) match, leading infinite loop.
also, printables includes closing curly bracket, gets consumed content term, , no longer available stanza. (if content can including closing bracket, need define escape it, distinguish content bracket stanza bracket.)
to address name rule, need content definition, 1 doesn't include stanza, , "rule rule".
def parse(config): def bnf(): lcb, rcb, slash, dot, underscore, dash = [c c in '{}/._-'] printables_no_rcb = word(printables, excludechars=rcb) name_word = word(alphas + nums + dot + underscore + slash + dash) name = oneormore(name_word).setresultsname("name") rule = group(literal('rule') + name).setresultsname("name") rule_content = oneormore(printables_no_rcb).setresultsname("content") stanza = forward() content = oneormore(stanza | oneormore(printables_no_rcb)).setresultsname("content") stanza << group(rule + lcb + rule_content + rcb | name + lcb + content + rcb).setresultsname("stanza") return stanza return [x x in bnf().scanstring(config)]
Comments
Post a Comment