From 1fa50e0387672f30a0483bdb05c4ba8e0479b8a7 Mon Sep 17 00:00:00 2001 From: Kevin Matz Date: Fri, 26 Oct 2018 15:26:18 -0400 Subject: [PATCH] use rule labeling to simplify parser --- CommentMacro.g4 | 4 -- OscCommentMacroListener.py | 42 ++++---------- OscMacroDefinitions.py | 111 ++++++++++++++++++------------------- 3 files changed, 63 insertions(+), 94 deletions(-) diff --git a/CommentMacro.g4 b/CommentMacro.g4 index b15b662..41abb13 100644 --- a/CommentMacro.g4 +++ b/CommentMacro.g4 @@ -72,7 +72,6 @@ macro | op='RK' t=target (dev=device)? // Stop Keystroke Macro ; -master : (target | CURRENT) ; time : TIME n=number ; device : ntype=nodeType n=number ; @@ -101,10 +100,7 @@ number : NUMBER ; fragment DIGIT : [0-9] ; NUMBER : DIGIT+ ('.' DIGIT+)? ; -SLASH : '/' ; THRU : '>' ; -NEXT : '+' ; -PREV : '-' ; CURRENT : '*' ; TIME : 't' ; diff --git a/OscCommentMacroListener.py b/OscCommentMacroListener.py index 9fd66c9..b87085f 100644 --- a/OscCommentMacroListener.py +++ b/OscCommentMacroListener.py @@ -48,40 +48,29 @@ class OscCommentMacroListener(CommentMacroListener): def __init__(self, servers): self.osc = OscMacroDefinitions.HogDevice(servers) - def enterMacro(self, ctx: CommentMacroParser.MacroContext): - ctx.device = None - ctx.number = None - ctx.master = None - ctx.targets = [] - ctx.time = None - def exitMacro(self, ctx: CommentMacroParser.MacroContext): # print the lisp tree of this macro lisp_tree_str = ctx.toStringTree(recog=ctx.parser) logger.info(beautify_lisp_string(lisp_tree_str)) # disallow duplicate targets - ctx.targets = set(ctx.targets) + if ctx.t is not None: + ctx.t.targets = set(ctx.t.targets) # execute macro from name - name = ctx.children[0].getText() + name = ctx.op.text try: self.osc.command[name](self, ctx) except KeyError: print(name + " macro is not compatable with OSC.") logger.debug("Exiting Macro") - def enterMaster(self, ctx: CommentMacroParser.MasterContext): - ctx.targets = [] - - def exitMaster(self, ctx: CommentMacroParser.MasterContext): - ctx.parentCtx.master = ctx - def enterTarget(self, ctx: CommentMacroParser.TargetContext): ctx.targets = [] def exitTarget(self, ctx: CommentMacroParser.TargetContext): - ctx.parentCtx.targets.extend(ctx.targets) # add to parent targets + if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext): + ctx.parentCtx.targets.extend(ctx.targets) # add to parent targets def exitNumber(self, ctx: CommentMacroParser.NumberContext): try: @@ -91,25 +80,14 @@ class OscCommentMacroListener(CommentMacroListener): if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext): ctx.parentCtx.targets.append(ctx.value) - else: - ctx.parentCtx.number = ctx def exitSpan(self, ctx: CommentMacroParser.SpanContext): - number1 = ctx.children[0].value - number2 = ctx.children[2].value - if (isinstance(number1, int) and isinstance(number2, int)): - minimum = min(number1, number2) - maximum = max(number1, number2) + n1 = ctx.n1.value + n2 = ctx.n2.value + if (isinstance(n1, int) and isinstance(n2, int)): + minimum = min(n1, n2) + maximum = max(n1, n2) for i in (range(minimum, maximum + 1)): ctx.parentCtx.targets.append(i) else: logger.error("ERROR: Spans must be ranged with intigers.") - - def exitTime(self, ctx: CommentMacroParser.TimeContext): - ctx.parentCtx.time = ctx - - def exitDevice(self, ctx: CommentMacroParser.DeviceContext): - ctx.parentCtx.device = ctx - - def exitNodeType(self, ctx: CommentMacroParser.NodeTypeContext): - ctx.parentCtx.type = ctx.getText() diff --git a/OscMacroDefinitions.py b/OscMacroDefinitions.py index 80469d7..b0bfb5e 100644 --- a/OscMacroDefinitions.py +++ b/OscMacroDefinitions.py @@ -47,14 +47,14 @@ class HogDevice(): if device is None: osc = list(self.servers.values())[0] else: - if (device.type != 'h'): + if (device.ntype.getText().lower() != 'h'): logger.error("ERROR: Only Hog type devices are supported.") return else: try: - osc = self.servers[device.number.value] + osc = self.servers[device.n.value] except KeyError: - logger.error("ERROR: Net# " + str(device.number.value) + + logger.error("ERROR: Net# " + str(device.n.value) + " not found.") return try: @@ -63,15 +63,15 @@ class HogDevice(): logger.error(e) def _master_go(self, ctx): - if ctx.number is not None: + if ctx.n is not None: logger.warn("GO MASTER doesn't support goto. " + - "Cue number "+str(ctx.number.value)+" is ignored.") - if (len(ctx.master.targets) == 0): + "Cue number "+str(ctx.n.value)+" is ignored.") + if ctx.t is None: logger.info("Main GO") - self.osc.button_press(ctx.device, "/hog/hardware/maingo") + self.osc.button_press(ctx.dev, "/hog/hardware/maingo") return else: - for i in ctx.master.targets: + for i in ctx.t.targets: if isinstance(i, int) is not True: logger.warn("GO MASTER macro targets must be intigers. " + str(i) + " is not an intigers.") @@ -81,15 +81,15 @@ class HogDevice(): continue master = str(i) logger.info("GO on master " + master) - self.osc.button_press(ctx.device, "/hog/hardware/go/" + master) + self.osc.button_press(ctx.dev, "/hog/hardware/go/" + master) def _master_halt(self, ctx): - if (len(ctx.master.targets) == 0): + if ctx.t is None: logger.info("Main HALT") - self.osc.button_press(ctx.device, "/hog/hardware/mainhalt") + self.osc.button_press(ctx.dev, "/hog/hardware/mainhalt") return else: - for i in ctx.master.targets: + for i in ctx.t.targets: if isinstance(i, int) is not True: logger.warn("GO MASTER macro targets must be intigers. " + str(i) + " is not an intigers.") @@ -99,29 +99,25 @@ class HogDevice(): continue master = str(i) logger.info("HALT on master " + master) - self.osc.button_press(ctx.device, + self.osc.button_press(ctx.dev, "/hog/hardware/pause/" + master) def _master_assert(self, ctx): - if (len(ctx.master.targets) != 0): + if ctx.t is None: logger.error("ERROR: limited to asserting current master only.") return logger.info("ASSERT on current master.") - self.osc.button_press(ctx.device, "/hog/hardware/assert") + self.osc.button_press(ctx.dev, "/hog/hardware/assert") def _master_release(self, ctx): - if (len(ctx.master.targets) != 0): + if ctx.t is None: logger.error("ERROR: limited to releasing current master only.") return logger.info("RELEASE on current master.") - self.osc.button_press(ctx.device, "/hog/hardware/release") + self.osc.button_press(ctx.dev, "/hog/hardware/release") def _master_fade(self, ctx): - if (ctx.number) is None: - logger.error("ERROR: Missing required argument for LEVEL") - return - else: - level = ctx.number.value + level = ctx.n.value if (level < 0 or level > 100): logger.error("Level must be between 0 and 100.") return @@ -129,7 +125,7 @@ class HogDevice(): logger.error("MASTER FADE doesn't support * current master.") return else: - for i in ctx.master.targets: + for i in ctx.t.targets: if isinstance(i, int) is not True: logger.warn("FADE MASTER macro targets must be intigers. " + str(i) + " is not an intigers.") @@ -140,95 +136,94 @@ class HogDevice(): master = str(i) logger.info("Fade Master "+master+" to "+str(level)+"%") level *= 255 / 100 # percent in Macro, 0>255 in OSC - self.osc.send_message(ctx.device, + self.osc.send_message(ctx.dev, "/hog/hardware/fader/" + master, level) def _master_fade_grand(self, ctx): - level = ctx.number.value + level = ctx.n.value if (level < 0 or level > 100): logger.error("Level must be between 0 and 100.") return logger.info("Fading Grand Master to " + str(level) + "%") level *= 255 / 100 # percent in Macro, 0>255 in OSC - self.osc.send_message(ctx.device, "/hog/hardware/fader/0", level) + self.osc.send_message(ctx.dev, "/hog/hardware/fader/0", level) def _master_choose(self, ctx): - if (ctx.number.value < 0): + if (ctx.n.value < 0): logger.error("Master must be greater than 0.") return - master = str(ctx.number.value) + master = str(ctx.n.value) logger.info("Choose Master " + master) - self.osc.button_press(ctx.device, "/hog/hardware/choose/" + master) + self.osc.button_press(ctx.dev, "/hog/hardware/choose/" + master) def _release_all(self, ctx): logger.info("Release All") - self.osc.send_message(ctx.device, "/hog/hardware/pig", + self.osc.send_message(ctx.dev, "/hog/hardware/pig", HogDevice.buttonDOWN) - self.osc.button_press(ctx.device, "/hog/hardware/release") - self.osc.send_message(ctx.device, "/hog/hardware/pig", + self.osc.button_press(ctx.dev, "/hog/hardware/release") + self.osc.send_message(ctx.dev, "/hog/hardware/pig", HogDevice.buttonUP) def _list_go(self, ctx): - for i in ctx.targets: - if ctx.number is not None: - list = str(i) + "." + str(ctx.number.value) + for i in ctx.t.targets: + if ctx.n is not None: + list = str(i) + "." + str(ctx.n.value) else: list = i logger.info("Go on List " + str(list)) - self.osc.send_message(ctx.device, "/hog/playback/go/0", list) + self.osc.send_message(ctx.dev, "/hog/playback/go/0", list) def _list_halt(self, ctx): - for i in ctx.targets: + for i in ctx.t.targets: logger.info("Halting List " + str(i)) - self.osc.send_message(ctx.device, "/hog/playback/halt/0", i) + self.osc.send_message(ctx.dev, "/hog/playback/halt/0", i) def _list_release(self, ctx): - for i in ctx.targets: + for i in ctx.t.targets: logger.info("Releasing List " + str(i)) - self.osc.send_message(ctx.device, "/hog/playback/release/0", i) + self.osc.send_message(ctx.dev, "/hog/playback/release/0", i) def _scene_go(self, ctx): - for i in ctx.targets: + for i in ctx.t.targets: logger.info("Go on Scene " + str(i)) - self.osc.send_message(ctx.device, "/hog/playback/go/1", i) + self.osc.send_message(ctx.dev, "/hog/playback/go/1", i) def _scene_halt(self, ctx): - for i in ctx.targets: + for i in ctx.t.targets: logger.info("Halt Scene " + str(i)) - self.osc.send_message(ctx.device, "/hog/playback/halt/1", i) + self.osc.send_message(ctx.dev, "/hog/playback/halt/1", i) def _scene_release(self, ctx): - for i in ctx.targets: + for i in ctx.t.targets: logger.info("Release Scene " + str(i)) - self.osc.send_message(ctx.device, "/hog/playback/release/1", i) + self.osc.send_message(ctx.dev, "/hog/playback/release/1", i) def _macro_go(self, ctx): - for i in ctx.targets: + for i in ctx.t.targets: logger.info("Go on Macro " + str(i)) - self.osc.send_message(ctx.device, "/hog/playback/go/2", i) + self.osc.send_message(ctx.dev, "/hog/playback/go/2", i) def _macro_halt(self, ctx): - for i in ctx.targets: + for i in ctx.t.targets: logger.info("Pause Macro " + str(i)) - self.osc.send_message(ctx.device, "/hog/playback/halt/2", i) + self.osc.send_message(ctx.dev, "/hog/playback/halt/2", i) def _macro_release(self, ctx): - for i in ctx.targets: + for i in ctx.t.targets: logger.info("Stop Macro " + str(i)) - self.osc.send_message(ctx.device, "/hog/playback/release/2", i) + self.osc.send_message(ctx.dev, "/hog/playback/release/2", i) def _page_change(self, ctx): - if ctx.number is not None: + if ctx.d is None: logger.error("ERROR: changing page by number is unsupported.") return - dir = ctx.children[1].getText() - if dir == '+': + if ctx.d.text == '+': logger.info("Next Page") - self.osc.button_press(ctx.device, "/hog/hardware/nextpage") - elif dir == '-': + self.osc.button_press(ctx.dev, "/hog/hardware/nextpage") + elif ctx.d.text == '-': logger.info("Previous Page") - self.osc.button_press(ctx.device, "/hog/hardware/backpage") + self.osc.button_press(ctx.dev, "/hog/hardware/backpage") command = {"GM": _master_go, "HM": _master_halt,