Replies: 1 comment 3 replies
-
I thought that @ptmcg (author of PyParsing) might have something to say about this. class WrapperPyparsing(PyParsing):
def __init__(keyword_name: str): pass
def add_parse_element(ParseElement: arg_parse_element):
"""
Construct the Pyparsing token tree with EBNF details of its configuration setting
:param: arg_parse_element - A `ParseElement` class containing details about a specific EBNF
"""
pass
def load_parse_elements(self, arg_parse_elements: dict):
"""
:param: arg_parse_elements - A dict type variable containing tokenized content of
named.conf configuration settings
""""
pass
def load_text_config(arg_text_named_conf: str):
"""
A shortcut to load a snippet of named.conf configuration file, but it requires a prior knowledge
of what keyword it contains before calling this method using the correct EBNF declarator class.
Useful for unit testing and those who possess a config file that
uses `include` pragma statement(s).
:param: arg_text_named_conf - A text-based ISC Bind9 configuration string or portion thereof
"""
pass
def output_text_config(self, filename: str, arg_parse_elements: dict):
"""
Basically formats the output string of the final `named.conf` configuration settings based
on the current holding of class-specific token variable that it currently holds within its class.
:param: filespec: str - a string containing the file path specification in which to write
the named.conf configuration settings into
:param: arg_parse_elements: dict - a dict type variable containing tokenized
content of named.conf configuration settings
"""
pass And the top-level parent class is: class ParentWrapperPyparsing(WrapperPyparsing):
def __init__():
"""
Initialize and builds all the `ParseElement` classes together.
"""
pass
def desired_config_version(self, arg_desired_config_version: str): pass
def encountered_config_version(self) -> str: pass
def read_config_file(self, arg_filespec: str): pass
def get_token_elements(self) -> dict: pass
def set_token_elements(self, arg_token_elements: dict): pass
def output_config_file(self, arg_filespec: str): pass |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I am exploring ways to craft a super wrapper class around
PyParsing
forbind9_parser
.Design Patterns (Python-based)
Factory Pattern
Now for the wrapper of each EBNF.
Given that
PyParsing
portion ofnamed.conf
EBNF is 100% completed, it would make most sense to wrap each individualParseElement
(aka EBNF) of each clause and statement with a new Python wrapper class so that each EBNF will have their own:named.conf
dict
/list
) variableWrapping around EBNF as a syntax unit makes maintenance much easier for all things specific to that clause or statement keyword.
Hence, it is imperative to prototype all of the above carefully before engaging in massive wrapping of some 2,400-odd EBNFs.
Parser - Factory Pattern
Need to weight in on whether to break-up the existing ParseElement classes and re-integrate into a master wrapper class, one has to ask the following:
Pros of a Master Wrapper Class
ParseElement
s were broken up and reintegrated into a wrapper class covering its additional methods?ParserElement
classes for handling of joiningParseElement
into the new wrapper class just to construct its master parser.Cons of a Master Wrapper Class
PyParsing
alone? Are there any benefits to having this standalone Python token variable containing manydict
/list
elements?Pros of keeping
ParseElement
classes togetherCons of keeping
ParseElement
classes togetherLoader - Factory Pattern
Outputter - Factory Pattern
Versioning - Factory Pattern
Nested-Class Pattern
Inner-class or nested-class pattern is useful for bunching up a set of similar methods into using the same IscBoolean
class. (DONE)
Builder Pattern
Builder pattern is useful for doing things like
namedconf().view('red').recursion().get()
(a form of Python method-chaining). May be possible to extend to be using a more simplified variant ofnamedconf.view['red'].recursion.get()
, but this is NOT important now as getting the generated output ofnamed.conf
from its token variable.Dataclass Pattern
Dataclass is useful for nesting ISC Bind9
zone
statement(s) into either underview
or underoptions
clause.Polymorphic Pattern
Polymorphic class is useful for overextending a class to having additional feature set (such as non-binary values along
with
IscBoolean
class'True
/False
andyes
/no
.)Versioning
Because the configuration file of
named.conf
comes in various syntax due to evolution of new and obsoleted features, versioning support must be incorporated.There is several orthogonal aspects of versioning here:
Free-Floating Versioning
The
PyParsing
handles all versions of ISC Bind9 from8.1
to9.19.1
but version-specific defaulting is discussed under laterDefault Values
section.Minimum and maximum version variables are in the parent class along with
get_supported_version_range
method.Fixed Versioning
The user may specify a specific version before loading of the
named.conf
thus may cause error due to version-mismatch, but it would assure the user of its correct version needed for their end-use (such as analysis or validation). This is not fully-implemented.Would have a
set_desired_version()
andget_desired_version()
methods in the parent class to be made accessible and readable by all of its subclasses.Reversioning
A future capability set may allow for reversioning of the
named.conf
in form of either upgrade or downgrade.Such reversioning would entail reading the
named.conf
file at a specific or free-floating version, then outputting at a specific version.This calls for a reconstruction of
PyParsing
given a specific version. We hope to be able to do the following:Beta Was this translation helpful? Give feedback.
All reactions