Source code for qslib.parser

import pyparsing as pp

pp.ParserElement.setDefaultWhitespaceChars("")
from pyparsing import pyparsing_common as ppc

we = (pp.White(" \t\r") | pp.StringEnd() | pp.FollowedBy("\n")).suppress()
nl = (pp.Literal("\n") + pp.Optional(pp.White(" \t\r"))).suppress().setName("<newline>")
fwe = pp.FollowedBy(we).suppress()


[docs]def make_multi_keyword(kwd_str, kwd_value): return pp.oneOf(kwd_str).setParseAction(pp.replaceWith(kwd_value))
pbool = make_multi_keyword("true True", True) | make_multi_keyword("False false", False) qs = pp.quotedString.setParseAction(lambda toks: toks[0][1:-1]) optvalue = ( (pbool + fwe) | (ppc.number + fwe) | (pp.Word(pp.alphanums + "_.,-") + fwe) | (qs + fwe) ).setParseAction(lambda toks: toks[0]) optkey = ppc.identifier("key") optpair = ( pp.Literal("-").suppress() + optkey + pp.Literal("=").suppress() + optvalue.setResultsName("value") ).setResultsName("opt", listAllMatches=True) arg = optvalue.setResultsName("arg", listAllMatches=True) arglist = (pp.delimitedList(optpair | arg, we))("arglist").setParseAction( lambda toks: { "opts": {k: v for k, v in toks.get("opt", [])}, "args": list(toks.get("arg", [])), } ) quote_content = pp.Word(pp.alphanums + "._") quote_open = pp.Combine("<" + quote_content + ">") quote_close = pp.Combine("</" + pp.matchPreviousExpr(quote_content) + ">") mlf = pp.Forward() quotedmultiline = ( quote_open.suppress() + nl + pp.delimitedList(mlf, nl) + nl + quote_close.suppress() ) command = ( ppc.identifier + we + pp.Optional(arglist + we, {}) + pp.Optional(quotedmultiline("body")) ).setParseAction( lambda toks: {"command": toks[0], **toks[1]} | ({"body": list(toks["body"])} if "body" in toks.keys() else {}) ) mlf << command