"""comment.py: Hog 4 comment macro interpreter and OSC bridge.""" import configparser import logging from typing import Dict from antlr4 import CommonTokenStream, InputStream, ParseTreeWalker from antlr4.error.ErrorListener import ErrorListener from pythonosc import udp_client from .commentmacro.CommentMacroLexer import CommentMacroLexer from .commentmacro.CommentMacroParser import CommentMacroParser from .OscListener import OscCommentMacroListener __all__ = [ "SyntaxErrorListener", "load_config", "comment", ] class SyntaxErrorListener(ErrorListener): """An error listener that raises SyntaxError exceptions.""" def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): raise SyntaxError("line {}:{} {}".format(line, column, msg)) def load_config(file: str = 'server.cfg') -> Dict[int, object]: """Load an ini style configuration file.""" # empty server dictionary servers: Dict[int, object] = {} # open config file config = configparser.ConfigParser(allow_no_value=True) config.read(file) # set up each hog device for name in config.get('network', 'hogs').split(','): try: # move to config section server = config[name.strip().strip('\"')] # read settings addr = server.get("ip", fallback="127.0.0.1") port = server.getint("port", fallback=7001) net = server.getint("net", fallback=1) # osc clients are added to the dictionary with the net # as the key logging.info("Adding Hog device at net# %d", str(net)) servers[net] = udp_client.SimpleUDPClient(addr, port) except KeyError as exception: print('Error configuring net#', net, exception) continue return servers # init reusable walker and listener WALKER: ParseTreeWalker = ParseTreeWalker() LISTENER: OscCommentMacroListener = OscCommentMacroListener() def comment(text: str) -> None: """Process comment macro input.""" # force upper case text = text.upper() # generate text stream input_stream = InputStream(text) # lex the text stream lexer = CommentMacroLexer(input_stream) # get token stream from lexer stream = CommonTokenStream(lexer) # parse the token steam parser = CommentMacroParser(stream) # attach an error handler to the parser parser._listeners.append(SyntaxErrorListener()) try: # get tree from parser tree = parser.prog() # walk the tree WALKER.walk(LISTENER, tree) except SyntaxError as exception: logging.debug(exception) # antlr internal listener prints the error # # log it to the debug logging anyway