Replies: 3 comments 1 reply
-
Perhaps something like a highly-customized
Of course, to do all that, I need to start deploying one Python class for each aspect of the EBNF and use some form of Seems like my biggest hangup is the following:
I've trashed some 8-odd prototypings on Mixin and still pouring over the READTHEDOCS. |
Beta Was this translation helpful? Give feedback.
-
I finally got to put some time into this late last evening, to do some experimenting with a mixin class, to support enhancing the imported pyparsing classes using a pretty intrusive monkeypatch. I didn't really follow what it was you wanted to add to the pyparsing classes themselves, so I added parent, next, and previous pointers as an experiment. [EDIT - the pointers are not included in this example, instead I just added a function to the base ParserElement class.] In doing so, I found that I was doing another bad practice in the So here is my "working" mixin example: import pyparsing as pp
class EnhancedParserElement(pp.ParserElement):
def added_function(self):
return repr(f"{self} - {hex(id(self))}")
orig_parser_element = pp.ParserElement
pp.ParserElement = EnhancedParserElement
def type_with_modified_mro(cls):
cur_mro = cls.__mro__
# don't patch if already patched
if EnhancedParserElement in cur_mro:
return cls
# compose new MRO replacing ParserElement with EnhancedParserElement
new_mro = tuple(EnhancedParserElement if klass is orig_parser_element else klass for klass in cur_mro)
return type(cls.__name__, new_mro, {})
def monkeypatch_all_parserelement_classes():
from collections import deque
# use deque instead of recursion to process inheritance tree
to_patch = deque(orig_parser_element.__subclasses__())
while to_patch:
klass = to_patch.popleft()
# print(klass.__name__)
# monkeypatch pyparsing module, replacing types with modified types
setattr(pp, klass.__name__, type_with_modified_mro(klass))
to_patch.extend(klass.__subclasses__())
# print(pp.Word.__mro__)
monkeypatch_all_parserelement_classes()
# print(pp.Word.__mro__)
# try it out!
integer = pp.Word(pp.nums)
string = pp.Word(pp.alphas, pp.alphas + ".")
# this won't work, must use OneOrMore explicitly
# street_name = string[1, ...]
street_name = pp.OneOrMore(string)
street_address = integer + street_name
for e in street_address.exprs:
print(e.added_function()) To do more work like adding a pointer to the parent element, things get a little trickier, but still mostly manageable. The point of the mixin is to minimize the impact to your actual grammar, and hack the underlying pyparsing classes. Is this something that might work for you? (Let me know when you get to adding the parent pointer - I'm still working on cleaning that up.) -- Paul P.S. - Why are you subclassing from |
Beta Was this translation helpful? Give feedback.
-
I created a design doc in #41 in attempt to narrow down the goal of creating outputters/dumpers. some insight might be helpful there. |
Beta Was this translation helpful? Give feedback.
-
I attempted to explore and implement a
Mixin
Design Pattern as suggested in #37 . In the long continuum of trying to incorporate additional support into Pyparsing the following:dict
/list
results.get
/.set
its value settings in each of its own Pyparsing-specific Python classI took
recursion
statement, a simple boolean setting found inoptions
clause ofnamed.conf
configuration file for ISC Bind9.A working snippet of Mixin-class for
recursion
(boolean) setting.resulted in demonstrating the holding of Pyparsing (ParserElement) string:
The only problem I have is how to store that boolean result back into the class so that various user interface (UI) and graphical unser interface (UX) can then make suitable retrieval and settings by end-users. @ptmcg
Where does one extract the info so that these
.get
and.set
methods can be supported? set_parse_action ?I've got some 2,400 str elements to retrofit so prototyping is paramount before deployment.
Beta Was this translation helpful? Give feedback.
All reactions