Module tf.search.syntax

Syntax of search templates

Functions

def cleanParent(atom, parentName)
Expand source code Browse git
def cleanParent(atom, parentName):
    (kind, data) = parseLine(atom)
    (indent, op, name, otype, features) = data
    if name == "":
        name = parentName
    return _genLine(kind, (indent, None, name, otype, features))
def deContext(quantifier, parentName)
Expand source code Browse git
def deContext(quantifier, parentName):
    (quKind, quTemplates, ln) = quantifier

    # choose a name for the parent
    # either the given name
    if not parentName:
        # or make a new name
        # collect all used names
        # to avoid choosing a name that is already used
        usedNames = set()
        for template in quTemplates:
            for line in template:
                for name in namesRe.findall(line):
                    usedNames.add(name)
        parentName = "parent"
        while parentName in usedNames:
            parentName += "x"

    newQuTemplates = []
    newQuantifier = (quKind, newQuTemplates, parentName, ln)

    # replace .. (PARENT_REF) by parentName
    # wherever it is applicable
    for template in quTemplates:
        newLines = []
        for line in template:
            (kind, data) = parseLine(line)
            newLine = line
            if kind == "rel":
                (indent, f, op, t) = data
                if f == PARENT_REF or t == PARENT_REF:
                    newF = parentName if f == PARENT_REF else f
                    newT = parentName if t == PARENT_REF else t
                    newData = (indent, newF, op, newT)
                    newLine = _genLine(kind, newData)
            elif kind == "atom":
                (indent, op, name, otype, features) = data
                if name == "" and otype == PARENT_REF:
                    newData = (indent, op, name, parentName, features)
                    newLine = _genLine(kind, newData)
            newLines.append(newLine)
        templateStr = "\n".join(newLines)
        newQuTemplates.append(templateStr)
    return newQuantifier
def parseFeatureVals(searchExe, featStr, features, i, asEdge=False)
Expand source code Browse git
def parseFeatureVals(searchExe, featStr, features, i, asEdge=False):
    if asEdge:
        if not (
            (featStr[0] == "-" and featStr[-1] == ">")
            or (featStr[0] == "<" and featStr[-1] == "-")
            or (featStr[0] == "<" and featStr[-1] == ">")
        ):
            return True
        feat = featStr[1:-1]
    else:
        feat = featStr.replace(chr(1), " ")
    good = True
    for x in [True]:
        match = trueRe.match(feat)
        if match:
            (featN,) = match.groups()
            featName = _unesc(featN)
            featVals = (None, True)
            break
        match = noneRe.match(feat)
        if match:
            (featN, unequal) = match.groups()
            featName = _unesc(featN)
            featVals = None if unequal else True
            break
        match = identRe.match(feat)
        if match:
            (featN, comp, featValStr) = match.groups()
            featName = _unesc(featN)
            featValSet = frozenset(_unesc(featVal) for featVal in featValStr.split("|"))
            featVals = (comp == "=", featValSet)
            break
        match = compRe.match(feat)
        if match:
            (featN, comp, limit) = match.groups()
            featName = _unesc(featN)
            if not numRe.match(limit):
                searchExe.badSyntax.append((i, f'Limit is non numeric "{limit}"'))
                good = False
                featVals = None
            else:
                featVals = _makeLimit(int(limit), comp == ">")
            break
        match = reRe.match(feat)
        if match:
            (featN, valRe) = match.groups()
            featName = _unesc(featN)
            valRe = _unesc(valRe, inRe=True)
            try:
                featVals = re.compile(valRe)
            except Exception as err:
                searchExe.badSyntax.append(
                    (i, f'Wrong regular expression "{valRe}": "{err}"')
                )
                good = False
                featVals = None
            break
        searchExe.badSyntax.append((i, f'Unrecognized feature condition "{feat}"'))
        good = False
        featVals = None
    if good:
        features[featName] = featVals
    return good
def parseLine(line)
Expand source code Browse git
def parseLine(line):
    for x in [True]:
        escLine = _esc(line)

        match = opLineRe.match(escLine)
        if match:
            (indent, op) = match.groups()
            if op != ".":
                kind = "op"
                data = (indent, op)
                break

        match = relRe.match(escLine)
        if match:
            (indent, f, op, t) = match.groups()
            kind = "rel"
            data = (indent, f, op, t)
            break

        matchOp = atomOpRe.match(escLine)
        if matchOp:
            (indent, op, atom, features) = matchOp.groups()
        if matchOp and op == "." or not matchOp:
            match = atomRe.match(escLine)
            if match:
                op = None
                (indent, atom, features) = match.groups()
        if matchOp or match:
            atomComps = atom.split(":", 1)
            if len(atomComps) == 1:
                name = ""
                otype = atomComps[0]
            else:
                name = atomComps[0]
                otype = atomComps[1]
            kind = "atom"
            if features is None:
                features = ""
            data = (indent, op, name, otype, features)
            break

        kind = "feat"
        data = (escLine,)

    return (kind, data)
def syntax(searchExe)
Expand source code Browse git
def syntax(searchExe):
    error = searchExe.api.TF.error
    _msgCache = searchExe._msgCache
    searchExe.good = True
    searchExe.badSyntax = []
    searchExe.searchLines = searchExe.searchTemplate.split("\n")
    offset = searchExe.offset

    _tokenize(searchExe)

    if not searchExe.good:
        searchExe.showOuterTemplate(_msgCache)
        for (i, line) in enumerate(searchExe.searchLines):
            error(f"{i + offset:>2} {line}", tm=False, cache=_msgCache)
        for (ln, eline) in searchExe.badSyntax:
            txt = eline if ln is None else f"line {ln + offset}: {eline}"
            error(txt, tm=False, cache=_msgCache)