Instantly share code, notes, and snippets.

Embed
What would you like to do?
from pyparsing import *
def plain_grammar():
return Word(printables + " ")
def command_grammar():
identifier = Word(alphas + '-_')
line_with_quotes = quotedString.setParseAction(removeQuotes)
plain_value = Word(alphanums + "-_")
value_with_bracket = "[" + Word(alphas + "-_") + "]"
line_with_parentheses = Suppress("(") + ZeroOrMore(Word(alphanums + '-_[]\/,;:|% ' + '\n')) + Suppress(")")
attr_value = (line_with_quotes | plain_value | value_with_bracket | line_with_parentheses) + ZeroOrMore(
",").suppress()
attribute = Group(identifier + Suppress(':') + attr_value)
command_group = Suppress('<%') + Dict(OneOrMore(attribute))("data") + Suppress('%>')
command_group.ignore(pythonStyleComment)
command_group.ignore(blankline_grammar())
return command_group
def unexpected_output_grammar():
identifier = Word(alphas + '-_')
line_with_parentheses = Suppress("(") + ZeroOrMore(Word(alphanums + "-_[]\/,;:|%^.'! " + '\n')) + Suppress(")")
attribute = Group(identifier + Suppress(':') + line_with_parentheses)
unexpected_output = Suppress('/*') + Dict(OneOrMore(attribute))("data") + Suppress('*/')
unexpected_output.ignore(blankline_grammar())
return unexpected_output
def extract_raw_command(original_content, start_location):
end_of_statement_marker = '%>'
end_location = original_content.find(end_of_statement_marker, start_location) + len(end_of_statement_marker)
raw_specialized_command = original_content[start_location:end_location]
return raw_specialized_command
def extract_unexpected(original_content, start_location):
end_of_statement_marker = '*/'
end_location = original_content.find(end_of_statement_marker, start_location) + len(end_of_statement_marker)
unexpected_output_statement = original_content[start_location:end_location]
return unexpected_output_statement
def convert_to_specialized_command(content, loc, toks):
return extract_raw_command(content, loc)
def convert_to_plain_command(content, loc, toks):
return toks[0]
def convert_to_unexpected_output(content, loc, toks):
return extract_unexpected(content, loc)
def blankline_grammar():
return LineStart().leaveWhitespace() + LineEnd()
def comment_grammar():
return ('#' + restOfLine).suppress()
def parse_data(content: str) -> ParseResults:
#
# Text file grammar
#
command = command_grammar().setParseAction(convert_to_specialized_command)
plain = plain_grammar().setParseAction(convert_to_plain_command)
unexpected_output = unexpected_output_grammar().setParseAction(convert_to_unexpected_output)
statement = unexpected_output | command.suppress() | plain.suppress() # `plain` has to be the last one because it's most general
body = OneOrMore(statement)
parser = body + StringEnd()
parser.ignore(blankline_grammar())
parser.ignore(comment_grammar())
#
# Text file parsing
#
results = parser.parseString(content)
return results
buffer = """
# This is applied for every single command, and has precedence in terms of checks
# Eg. it's checked before there's a file
/*
error: (
Error: Unrecognized command found at '^' position.
)
retryable: (
Info: The system is busy in collecting the current configuration. Please wait...
)
*/
# Huawei Model S2300
#
# BoD
#
system-view
interface [physical_interface]
<%
module: create-variable
variable-name: traffic_policy_name
command: "display this | i traffic-policy"
keyword: "traffic-policy"
position: 1
%>
undo traffic-policy inbound
quit
traffic behavior [circuit_id]
car cir [cir] cbs [cbs]
quit
interface [physical_interface]
traffic-policy {traffic_policy_name} inbound
return
<%
module: try-until-output-matched
commands-before-retry: (
save
Y/N]
)
retry-command: (
y
Info: Save the configuration successfully
)
seconds-until-retry: 6
%>
<%
module: expect-output
command: "display traffic behavior user-defined [circuit_id]"
keyword: "CIR"
at-position: 1
to-equal: [cir]
%>
"""
results = parse_data(buffer)
from pprint import pprint
for command in results:
print("*"*50)
print(command)
print("-"*50)
print("All done!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment