Using nested rules with Dragonfly
# A proof of concept for implementing re-usable nested rules in Dragonfly. | |
# | |
# See http://simon.podhajsky.net/blog/2017/executing-nested-rules-with-dragonfly/ | |
# for the accompanying article. | |
try: | |
import pkg_resources | |
pkg_resources.require("dragonfly >= 0.6.5beta1.dev-r99") | |
except ImportError: | |
pass | |
from dragonfly import * | |
from execute_factory import executeFactory, multipleExecuteFactory | |
print 'Test grammar accessed.' | |
config = Config("test") | |
config.cmd = Section("Language section") | |
namespace = config.load() | |
# Debug functions | |
def inspectFunctionCall(**kwargs): | |
print "I was called with", len(kwargs), "kwarguments:", kwargs | |
# Rules proper | |
class RuleA(MappingRule): | |
exported = False | |
mapping = { | |
"add <n>": Text('RuleA %(n)s'), | |
} | |
extras = [ | |
IntegerRef("n", 1, 10), | |
] | |
class RuleB(MappingRule): | |
exported = False | |
mapping = { | |
"bun <n>": Text("RuleB %(n)s") , | |
} | |
extras = [ | |
IntegerRef("n", 1, 10), | |
] | |
class RuleMain(MappingRule): | |
name = "rule_main" | |
exported = True | |
mapping = { | |
"boo <rule_b> and <rule_a>": Text("Rule matched: B and A!") + multipleExecuteFactory(['rule_b', 'rule_a']), | |
"fair <rule_a> and <rule_b>": Text("Rule matched: A and B!") + executeFactory('rule_a') + executeFactory('rule_b'), | |
} | |
extras = [ | |
RuleRef(rule = RuleA(), name = "rule_a"), | |
RuleRef(rule = RuleB(), name = "rule_b") | |
] | |
grammar = Grammar("Test grammar") | |
grammar.add_rule(RuleMain()) | |
grammar.load() | |
def unload(): | |
global grammar | |
if grammar: grammar.unload() | |
grammar = None |
# Use in mapping of nested rules. | |
# | |
# mapping = { | |
# "do <rule_a> <rule_b>": execute_rule("rule_b") + execute_rule("rule_a"), | |
# "boo <rule_a> <rule_b>": execute_rule("rule_b", "rule_a"), | |
# } | |
# | |
# extras = [ | |
# RuleRef(rule = RuleA(), name = "rule_a"), | |
# RuleRef(rule = RuleB(), name = "rule_b"), | |
# ] | |
from dragonfly import Function, ActionBase | |
def _executeRecursive(executable): | |
if isinstance(executable, ActionBase): | |
executable.execute() | |
elif hasattr(executable, '__iter__'): | |
for item in executable: | |
_executeRecursive(item) | |
else: | |
print "Neither executable nor a list: ", executable | |
def execute_rule(*rule_names): | |
def _exec_function(**kwargs): | |
for name in rule_names: | |
executable = kwargs.get(name) | |
_executeRecursive(executable) | |
return Function(_exec_function) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment