Exemplo n.º 1
0
def _parse_funcs(text, is_output=False):
    if is_output:
        text = text[text.index(FUNCTION_START):text.index(FUNCTION_END)]
    funcs = {}
    # syntax we don't want to see in the final parse tree
    LPAR, RPAR, LBRACE, RBRACE, COMMA, SEMICOLON = map(Suppress, "(){},;")
    const = Keyword("const")
    static = Keyword("static")
    inline = Keyword("inline")
    dtype = Word(alphanums + "_*")
    identifier = Word(alphanums + "_")
    argDecl = Group(
        Optional(const("const")) + dtype("dtype") +
        Optional(identifier("name")) + Optional(COMMA))
    args = Group(ZeroOrMore(argDecl))
    if not is_output:
        func = Optional(Suppress("DVZ_EXPORT")) + \
            Optional(Suppress("DVZ_INLINE"))
    else:
        func = Empty()
    signature = Optional(static("static")) + \
        Optional(inline("inline")) + \
        dtype("out") + \
        identifier("name") + \
        LPAR + args("args") + RPAR + \
        Optional(SEMICOLON)
    func = cStyleComment("docstring") + func + \
        signature("signature")
    for item, start, stop in func.scanString(text):
        args = []
        # for i, entry in enumerate(item.args):
        #     args.append((entry.const, entry.dtype, entry.name))
        funcs[item.name] = item
    return funcs
def parse(liberty_string):
    # _p.ParserElement.enablePackrat() <- dont, kills memory - and slower...
    identifier = _p.Word(_p.alphanums + "._")  # a name for..
    EOL = _p.LineEnd().suppress()  # end of line
    ws = " \t"
    _p.ParserElement.setDefaultWhitespaceChars(ws)
    linebreak = _p.Suppress("\\" + _p.LineEnd())
    o_linebreak = _p.Optional(linebreak)
    library_name = identifier
    b_left = _p.Suppress("(")
    b_right = _p.Suppress(")")
    cb_left = _p.Suppress("{")
    cb_right = _p.Suppress("}")
    semicolon = _p.Suppress(";")
    colon = _p.Suppress(":")
    quote = _p.Suppress('"')
    emptyquote = '""'
    comma = _p.Suppress(",")
    comment = _p.Suppress(_p.cStyleComment())
    valuestring = _p.Word(_p.alphanums + "'=&_-+*/.$:!| ")
    valuestring_quoted = emptyquote | quote + _p.Word(_p.alphanums + "'=&_-+*/.$:! ()|") + quote
    valuelist = _p.Group(quote + valuestring + _p.OneOrMore(comma + valuestring) + quote)
    value = valuestring | valuestring_quoted | valuelist
    key_value_pair = _p.Group(identifier + colon + value) + semicolon + EOL
    named_list = (
        identifier
        + b_left
        + _p.Group(o_linebreak + value + _p.ZeroOrMore(comma + o_linebreak + value))
        + o_linebreak
        + b_right
        + (semicolon + EOL | EOL)
    )
    group = _p.Forward()
    group << _p.Group(
        _p.Group(
            identifier
            + b_left
            + _p.Optional(
                (identifier + _p.ZeroOrMore(comma + identifier))
                | valuestring_quoted + _p.ZeroOrMore(comma + valuestring_quoted)
            )
        )
        + b_right
        + cb_left
        + EOL
        + _p.Group(_p.ZeroOrMore(key_value_pair | named_list | group | EOL | comment))
        + cb_right
        + EOL
    )

    library = _p.Suppress(_p.ZeroOrMore(comment | EOL)) + group + _p.Suppress(_p.ZeroOrMore(comment | EOL))

    key_value_pair.setParseAction(handle_parameters)
    named_list.setParseAction(handle_list)
    group.setParseAction(handle_groups)
    valuestring.setParseAction(parse_string_if_possible)

    return library.parseString(liberty_string)[0]["library"]
Exemplo n.º 3
0
def _parse_struct(text):
    structs = {}
    # syntax we don't want to see in the final parse tree
    LBRACE, RBRACE, COMMA, SEMICOLON = map(Suppress, "{},;")
    _struct = Literal("struct") ^ Literal("union")
    dtype = Word(alphanums + "_*")
    identifier = Word(alphanums + "_[]")
    structDecl = Group(
        dtype("dtype") + identifier("name") + SEMICOLON +
        Optional(cStyleComment("desc")))
    structList = Group(structDecl + ZeroOrMore(structDecl))
    struct = _struct('struct') + identifier("struct_name") + LBRACE + \
        structList("names") + RBRACE + SEMICOLON
    for item, start, stop in struct.scanString(text):
        l = []
        for i, entry in enumerate(item.names):
            l.append((entry.dtype, entry.name, entry.desc))
        structs[item.struct_name] = (item.struct, l)
    return structs
Exemplo n.º 4
0
    def parse(self, s):
        ats = []
        parser = pyparsing.cStyleComment('lalala')
        parser.parseWithTabs()
        for p in parser.scanString(s):
            c = p[0][0]
            if c.startswith('/**'):
                ats.extend(parse_comment(c, s, p[2]))

        if debug:
            print 'LIST DUMP'
            import pprint
            pprint.pprint(ats)

        # build tree starting from flat ats
        self.classes = []
        cursor = self.classes # where to append nodes
        for at in ats:
            level, _, class_ = command_option[at.name]
            try:
                node = class_(at.name, at.lines)
            except InvalidDocNode as e:
                print e
                continue

            if level == 0:
                self.classes.append(node)
                cursor = node
            elif level == 1:
                self.classes[-1].append(node)
                cursor = node
            else:
                cursor.append(node)

        if debug:
            print 'TREE DUMP'
            for class_ in self.classes:
                class_.dump()
Exemplo n.º 5
0
def _setup_QASMParser():
    """
    Routine to initialise and return parsing blocks
    """
    class _Op:
        """ Class to set up quantum operations """
        def __init__(self,
                     name,
                     argParser,
                     version="OPENQASM 2.0",
                     qop=False,
                     keyOverride=None):
            global cops
            global qops
            global _reservedKeys
            if name in qops or name in cops:
                raise IOError(dupTokenWarning.format("Operation", name))
            self.operation = name
            if keyOverride is not None:
                self.parser = (keyOverride + argParser).addParseAction(
                    lambda s, l, t: _override_keyword(t, name))
            else:
                self.parser = CaselessKeyword(name)("keyword") + argParser

            self.version = parse_version(version)
            self.parser.addParseAction(
                lambda s, l, t: _set_version(t, self.version))

            _reservedKeys.append(name)
            if qop:
                qops[name] = self
            else:
                cops[name] = self

    class _Routine():
        """ Class to set up quantum gates, circuits, etc. """
        def __init__(self,
                     name,
                     pargs=False,
                     spargs=False,
                     gargs=False,
                     qargs=False,
                     returnables=False,
                     prefixes=None,
                     version="OPENQASM 2.0"):
            global blocks
            global _reservedKeys
            if name in qops or name in cops:
                raise IOError(dupTokenWarning.format("Routine", name))
            self.operation = name

            self.parser = Keyword(name)("keyword") + validName("gateName")

            if prefixes:
                localPrefixParser = Each(map(Optional, map(
                    Keyword, prefixes))).addParseAction(prefix_setter)
            else:
                localPrefixParser = prefixParser
            self.parser = localPrefixParser + self.parser

            # Handle different args
            req = []
            if pargs:
                req.append(Optional(pargParser)("pargs"))
            if spargs:
                req.append(Optional(spargParser)("spargs"))
            if gargs:
                req.append(Optional(gargParser)("gargs"))
            self.parser = self.parser + Each(req)
            if qargs:
                self.parser = self.parser + qargParser("qargs")
            if returnables:
                self.parser = self.parser + Optional(returnParser)

            self.version = parse_version(version)
            self.parser.addParseAction(
                lambda s, l, t: _set_version(t, self.version))

            _reservedKeys.append(name)
            blocks[name] = self

    class _Block():
        """ Class to set up blocks such as if, for, etc. """
        def __init__(self, name, detParser, version="OPENQASM 2.0"):
            global blocks
            global _reservedKeys
            self.operation = name
            self.parser = Keyword(name)("keyword") + detParser

            self.version = parse_version(version)
            self.parser.addParseAction(
                lambda s, l, t: _set_version(t, self.version))

            _reservedKeys.append(name)
            blocks[name] = self

    sign = Word("+-", exact=1)
    number = Word(nums)
    expo = Combine(CaselessLiteral("e") + Optional(sign) +
                   number).setResultsName("exponent")

    pi = CaselessKeyword("pi")

    bitstring = Combine(OneOrMore(oneOf("0 1")) + Literal("b"))

    integer = Combine(number + Optional(expo))
    real = Combine(
        Optional(sign) + (("." + number) ^ (number + "." + Optional(number))) +
        Optional(expo))
    validName = Forward()
    lineEnd = Literal(";")

    _is_ = Keyword("to").suppress()
    _in_ = Keyword("in")
    _to_ = Literal("->").suppress()

    commentSyntax = "//"
    commentOpenStr = "/*"
    commentCloseStr = "*/"
    commentOpenSyntax = Literal(commentOpenStr)
    commentCloseSyntax = Literal(commentCloseStr)

    dirSyntax = "***"
    dirOpenStr = f"{dirSyntax} begin"
    dirCloseStr = f"{dirSyntax} end"

    dirSyntax = Keyword(dirSyntax)
    dirOpenSyntax = CaselessLiteral(dirOpenStr)
    dirCloseSyntax = CaselessLiteral(dirCloseStr)

    intFunc = oneOf("abs powrem countof fllog")
    realFunc = oneOf("abs powrem arcsin arccos arctan sin cos tan exp ln sqrt")
    boolFunc = oneOf("andof orof xorof")

    inL, inS, inR = map(Suppress, "[:]")
    vBar = Suppress("|")
    bSlash = Suppress("\\")
    brL, brR = map(Suppress, "()")

    intExp = Forward()
    realExp = Forward()
    boolExp = Forward()

    index = intExp.setResultsName("index")
    interval = Optional(intExp.setResultsName("start"), default=None) + inS \
        + Optional(intExp.setResultsName("end"), default=None) \
        + Optional(inS + Optional(intExp.setResultsName("step"), default=1))
    interRef = Group(inL + interval + inR)
    loopRef = Group(
        inL + intExp.setResultsName("start") + inS +
        intExp.setResultsName("end") +
        Optional(inS + Optional(intExp.setResultsName("step"), default=1)) +
        inR)
    ref = inL + Group(delimitedList(index ^ interval))("ref") + inR
    regNoRef = validName("var")
    regRef = Group(validName("var") + Optional(ref))
    regMustRef = Group(validName("var") + ref)
    regListNoRef = Group(delimitedList(regNoRef))
    regListRef = Group(delimitedList(regRef))

    inPlaceAlias = vBar + regListRef + vBar
    validQarg = regRef | inPlaceAlias
    aliasQarg = Group(regRef) | inPlaceAlias

    inPlaceCreg = bSlash + delimitedList(regRef | bitstring) + bSlash
    validCreg = (regRef | inPlaceCreg)

    def set_maths_type(toks, mathsType):
        """ Set logical or integer or floating point """
        toks["type"] = mathsType

    intVar = integer | regRef
    realVar = real | integer | pi | regRef
    boolVar = interRef | regRef | realExp | intExp | validCreg | bitstring
    intFuncVar = (intFunc + brL +
                  Group(Optional(delimitedList(intVar)))("args") +
                  brR).setParseAction(Function)
    realFuncVar = ((realFunc ^ intFunc) + brL +
                   Group(Optional(delimitedList(realVar)))("args") +
                   brR).setParseAction(Function)
    boolFuncVar = (boolFunc + brL +
                   Group(Optional(delimitedList(boolVar)))("args") +
                   brR).setParseAction(Function)

    mathOp = [(oneOf("- +"), 1, opAssoc.RIGHT, Binary),
              (oneOf("^"), 2, opAssoc.LEFT, Binary),
              (oneOf("* / div"), 2, opAssoc.LEFT, Binary),
              (oneOf("+ -"), 2, opAssoc.LEFT, Binary)]
    logOp = [(oneOf("! not"), 1, opAssoc.RIGHT, Binary),
             (oneOf("and or xor"), 2, opAssoc.LEFT, Binary),
             (oneOf("< <= == != >= >"), 2, opAssoc.LEFT, Binary),
             (oneOf("in"), 2, opAssoc.LEFT, Binary)]

    intExp <<= infixNotation(
        intFuncVar | intVar,
        mathOp).setParseAction(lambda s, l, t: set_maths_type(t, "int"))

    realExp <<= infixNotation(
        realFuncVar | realVar,
        mathOp).setParseAction(lambda s, l, t: set_maths_type(t, "float"))

    boolExp <<= infixNotation(
        boolFuncVar | boolVar,
        logOp).setParseAction(lambda s, l, t: set_maths_type(t, "bool"))

    mathExp = intExp ^ realExp ^ boolExp
    cregExp = bitstring("bit") ^ validCreg("reg")

    prefixes = ["unitary"]
    callMods = ["CTRL", "INV"]

    def prefix_setter(toks):
        """ Pull out prefixes of gate calls and add them into list """
        for prefix in prefixes:
            toks[prefix] = prefix in toks.asList()

    prefixParser = Each(map(Optional,
                            map(Keyword,
                                prefixes))).addParseAction(prefix_setter)

    pargParser = brL + delimitedList(validName)("pargs") + brR
    spargParser = inL + delimitedList(validName)("spargs") + inR
    gargParser = ungroup(
        nestedExpr("<", ">", delimitedList(ungroup(validName)), None))
    qargParser = delimitedList(regRef)

    callQargParser = delimitedList(validQarg)
    callPargParser = brL + delimitedList(realExp) + brR
    callSpargParser = inL + delimitedList(intExp) + inR

    fullArgParser = Each(
        (Optional(pargParser("pargs")), Optional(spargParser("spargs")),
         Optional(gargParser("gargs"))))

    callArgParser = Each(
        (Optional(callPargParser("pargs")),
         Optional(callSpargParser("spargs")), Optional(gargParser("gargs"))))

    returnParser = Optional(_to_ + validCreg("byprod"))

    modifiers = ZeroOrMore(Combine(oneOf(callMods) + Suppress("-")))

    commentLine = Literal(commentSyntax).suppress() + restOfLine("comment")
    commentBlock = cStyleComment("comment").addParseAction(
        removeQuotes).addParseAction(removeQuotes)
    comment = commentLine | commentBlock
    comment.addParseAction(lambda s, l, t: _set_version(t, (0, 0, 0)))

    directiveName = Word(alphas).setParseAction(downcaseTokens)
    directiveArgs = CharsNotIn(";")

    _Op("directive",
        directiveName("directive") + Suppress(White() * (1, )) +
        directiveArgs("args"),
        version="REQASM 1.0",
        keyOverride=(~dirOpenSyntax + ~dirCloseSyntax + dirSyntax))

    def split_args(toks):
        """ Split directive arguments out """
        toks[0]["keyword"] = "directive"
        toks[0]["args"] = toks[0]["args"].strip().split(" ")

    directiveStatement = directiveName("directive") + restOfLine("args") + \
        Group(ZeroOrMore(Combine(Optional(White(" ")) + ~dirCloseSyntax + Word(printables+" "))))("block")

    directiveBlock = ungroup(
        nestedExpr(
            dirOpenSyntax,
            dirCloseSyntax,
            content=directiveStatement,
            ignoreExpr=(comment | quotedString
                        )).setWhitespaceChars("\n").setParseAction(split_args))
    directiveBlock.addParseAction(lambda s, l, t: _set_version(t, (2, 1, 0)))

    # Programming lines
    _Op("version",
        Empty(),
        version=(0, 0, 0),
        keyOverride=Combine(
            oneOf(versions)("type") + White() +
            real("versionNumber"))("version"))
    _Op("include", quotedString("file").addParseAction(removeQuotes))

    # Gate-like structures
    _Op("opaque",
        validName("name") + fullArgParser + Optional(qargParser("qargs")) +
        returnParser,
        keyOverride=prefixParser + "opaque")
    _Routine("gate", pargs=True, qargs=True)
    _Routine("circuit",
             pargs=True,
             qargs=True,
             spargs=True,
             returnables=True,
             version="REQASM 1.0")

    # Variable-like structures
    _Op("creg", regRef("arg"))
    _Op("qreg", regRef("arg"))
    _Op("cbit", Group(regNoRef)("arg"), version="REQASM 1.0")
    _Op("qbit", Group(regNoRef)("arg"), version="REQASM 1.0")
    _Op("defAlias",
        regMustRef("alias"),
        keyOverride="alias",
        version="REQASM 1.0")

    # No more on-definition aliases
    _Op("alias",
        regRef("alias") + _is_ + aliasQarg("target"),
        keyOverride="set",
        version="REQASM 1.0")
    _Op("val",
        validName("var") + Literal("=").suppress() + mathExp("val"),
        version="REQASM 1.0")

    _Op("set", (Group(regRef)("var") ^ inPlaceCreg("var")) +
        Literal("=").suppress() + cregExp("val"),
        version="REQASM 1.0")

    # Operations-like structures
    _Op("measure", regRef("qreg") + _to_ + regRef("creg"), qop=True)
    _Op("barrier", regListNoRef("args"))
    _Op("output", regRef("value"), qop=True, version="REQASM 1.0")
    _Op("reset", regRef("qreg"))
    _Op("exit", Empty(), version="REQASM 1.0")

    _Op("free", validName("target"), version="REQASM 1.0")
    _Op("next", validName("loopVar"), qop=True, version="REQASM 1.0")
    _Op("finish", (Literal("quantum process") | validName)("loopVar"),
        qop=True,
        version="REQASM 1.0")
    _Op("end", validName("process"), qop=True, version="REQASM 1.0")

    # Special gate call handler
    callGate = Combine(Group(modifiers)("mods") + \
                       validName("gate")) + \
                       callArgParser + \
                       callQargParser("qargs").addParseAction(lambda s, l, t: _override_keyword(t, "call")) + \
                       returnParser
    callGate.addParseAction(lambda s, l, t: _set_version(t, (1, 2, 0)))

    # Block structures
    _Block("for",
           validName("var") + _in_ + loopRef("range"),
           version="REQASM 1.0")
    _Block("if", "(" + boolExp("cond") + ")", version="REQASM 1.0")
    _Block("while", "(" + boolExp("cond") + ")", version="OMEQASM 1.0")

    qopsParsers = list(map(lambda qop: qop.parser,
                           qops.values())) + [callGate, directiveBlock]
    blocksParsers = list(map(lambda block: block.parser, blocks.values()))

    _Op("if",
        blocks["if"].parser + Group(Group(Group(Or(qopsParsers))))("block"),
        version="OPENQASM 2.0",
        keyOverride=Empty())
    _Op("for",
        blocks["for"].parser + Group(Group(Group(Or(qopsParsers))))("block"),
        version="REQASM 1.0",
        keyOverride=Empty())
    _Op("while",
        blocks["while"].parser + Group(Group(Group(Or(qopsParsers))))("block"),
        version="OMEQASM 1.0",
        keyOverride=Empty())

    # Set-up line parsers
    reservedNames = Or(map(Keyword, _reservedKeys))
    validName <<= (~reservedNames) + Word(alphas, alphanums + "_")

    copsParsers = list(map(lambda cop: cop.parser, cops.values()))

    operations = ((
        (Or(copsParsers) ^ Or(qopsParsers)) |  # Classical/Quantum Operations
        callGate |  # Gate parsers
        White()  # Blank Line
    ) + lineEnd.suppress()) ^ directiveBlock  # ; or Directives

    validLine = Forward()
    codeBlock = nestedExpr("{", "}",
                           Suppress(White()) ^ Group(validLine),
                           (quotedString))

    validLine <<= (
        ((operations + Optional(comment)) ^
         (Or(blocksParsers) + codeBlock("block") + Optional(lineEnd))
         ^ comment))  # Whole line comment

    testLine = Forward()
    dummyCodeBlock = nestedExpr(
        "{", "}", testLine,
        (directiveBlock | quotedString | comment)) + Optional(lineEnd)

    ignoreSpecialBlocks = (~commentOpenSyntax + ~commentCloseSyntax +
                           ~dirOpenSyntax + ~dirCloseSyntax)

    testLine <<= (
        comment |  # Comments
        directiveBlock |  # Directives
        (ignoreSpecialBlocks + ZeroOrMore(CharsNotIn("{}")) + dummyCodeBlock)
        |  # Block operations
        (ignoreSpecialBlocks + ZeroOrMore(CharsNotIn("{};")) + lineEnd)
    )  # QASM Instructions

    testKeyword = (dirSyntax.setParseAction(
        lambda s, l, t: _override_keyword(t, "directive"))
                   | Word(alphas)("keyword"))

    code = (Group(directiveBlock)) | Group(validLine)

    return code, testLine, testKeyword, reservedNames, mathExp
Exemplo n.º 6
0
def addToHeaderDict(headerName, structt):
    headerList[headerName] = structt.asDict()


def addToAnnotationDict(annotateName, annotate):
    s = annotate[1]
    # first remove the quotes
    if s.startswith("'''"): s = s[3:-3]
    if s.startswith('"'): s = s[1:-1]
    annotateDict[annotate['name']] = s


comment = '## ' + restOfLine
#comment       = '#' + restOfLine
CMNT = Optional(cStyleComment("comment"))
CMNT2 = Optional(
    (Suppress('//') +
     restOfLine("comment2")))  #Optional(cppStyleComment("comment2"))
STRQ3 = QuotedString("'''", multiline=True)
ANNOTSTR = (QuotedString("'''", multiline=True) | quotedString)
#IDENTIFIER = Regex(r'[a-zA-Z_][a-zA-Z_0-9]*')
#INTEGER    = Regex(r'([+-]?(([1-9][0-9]*)|0+))')
#IDENTIFIER       = Word(alphas+"_", alphas+nums+"_" )
INT_DECI = Regex('([+-]?(([1-9][0-9]*)|0+))')
INT_OCT = Regex('(0[0-7]*)')
INT_HEX = Regex('(0[xX][0-9a-fA-F]*)')
INT = INT_HEX | INT_OCT | INT_DECI
FLOAT = Regex(
    '[+-]?(((\d+\.\d*)|(\d*\.\d+))([eE][-+]?\d+)?)|(\d*[eE][+-]?\d+)')
SIZE = INT