Skip to content

parserutils

NOTE: PyParsing setResultName/call provides a very similar solution to this I didn’t realise at the time of writing and I will remove a lot of this code at some point

Utility classes for creating an abstract-syntax tree out with pyparsing actions

Lets you label and group parts of parser production rules

For example:

[5] BaseDecl ::= ‘BASE’ IRIREF

BaseDecl = Comp(‘Base’, Keyword(‘BASE’) + Param(‘iri’,IRIREF))

After parsing, this gives you back an CompValue object, which is a dict/object with the parameters specified. So you can access the parameters are attributes or as keys:

baseDecl.iri

Comp lets you set an evalFn that is bound to the eval method of the resulting CompValue

Classes:

  • Comp

    A pyparsing token for grouping together things with a label

  • CompValue

    The result of parsing a Comp

  • Expr

    A CompValue that is evaluatable

  • Param

    A pyparsing token for labelling a part of the parse-tree

  • ParamList

    A shortcut for a Param with isList=True

  • ParamValue

    The result of parsing a Param

Functions:

Comp

Comp(name: str, expr: ParserElement)

Bases: TokenConverter

A pyparsing token for grouping together things with a label Any sub-tokens that are not Params will be ignored.

Returns CompValue / Expr objects - depending on whether evalFn is set.

Methods:

Attributes:

  • evalfn (Optional[Callable[[Any, Any], Any]]) –
  • expr
Source code in rdflib/plugins/sparql/parserutils.py
def __init__(self, name: str, expr: ParserElement):
    self.expr = expr
    TokenConverter.__init__(self, expr)
    self.setName(name)
    self.evalfn: Optional[Callable[[Any, Any], Any]] = None

evalfn instance-attribute

evalfn: Optional[Callable[[Any, Any], Any]] = None

expr instance-attribute

expr = expr

postParse

postParse(instring: str, loc: int, tokenList: ParseResults) -> Union[Expr, CompValue]
Source code in rdflib/plugins/sparql/parserutils.py
def postParse(
    self, instring: str, loc: int, tokenList: ParseResults
) -> Union[Expr, CompValue]:
    res: Union[Expr, CompValue]
    if self.evalfn:
        res = Expr(self.name)
        res._evalfn = MethodType(self.evalfn, res)
    else:
        res = CompValue(self.name)
        if self.name == "ServiceGraphPattern":
            # Then this must be a service graph pattern and have
            # already matched.
            # lets assume there is one, for now, then test for two later.
            sgp = originalTextFor(self.expr)
            service_string = sgp.searchString(instring)[0][0]
            res["service_string"] = service_string

    for t in tokenList:
        if isinstance(t, ParamValue):
            if t.isList:
                if t.name not in res:
                    res[t.name] = []
                res[t.name].append(t.tokenList)
            else:
                res[t.name] = t.tokenList
            # res.append(t.tokenList)
        # if isinstance(t,CompValue):
        #    res.update(t)
    return res

setEvalFn

setEvalFn(evalfn: Callable[[Any, Any], Any]) -> Comp
Source code in rdflib/plugins/sparql/parserutils.py
def setEvalFn(self, evalfn: Callable[[Any, Any], Any]) -> Comp:
    self.evalfn = evalfn
    return self

CompValue

CompValue(name: str, **values)

Bases: OrderedDict

The result of parsing a Comp Any included Params are available as Dict keys or as attributes

Methods:

Attributes:

Source code in rdflib/plugins/sparql/parserutils.py
def __init__(self, name: str, **values):
    OrderedDict.__init__(self)
    self.name = name
    self.update(values)

name instance-attribute

name = name

__getattr__

__getattr__(a: str) -> Any
Source code in rdflib/plugins/sparql/parserutils.py
def __getattr__(self, a: str) -> Any:
    # Hack hack: OrderedDict relies on this
    if a in ("_OrderedDict__root", "_OrderedDict__end"):
        raise AttributeError()
    try:
        return self[a]
    except KeyError:
        # raise AttributeError('no such attribute '+a)
        return None

__getitem__

__getitem__(a)
Source code in rdflib/plugins/sparql/parserutils.py
def __getitem__(self, a):
    return self._value(OrderedDict.__getitem__(self, a))

__repr__

__repr__() -> str
Source code in rdflib/plugins/sparql/parserutils.py
def __repr__(self) -> str:
    return self.name + "_" + dict.__repr__(self)

__setattr__

__setattr__(__name: str, __value: Any) -> None
Source code in rdflib/plugins/sparql/parserutils.py
def __setattr__(self, __name: str, __value: Any) -> None: ...

__str__

__str__() -> str
Source code in rdflib/plugins/sparql/parserutils.py
def __str__(self) -> str:
    return self.name + "_" + OrderedDict.__str__(self)

clone

clone() -> CompValue
Source code in rdflib/plugins/sparql/parserutils.py
def clone(self) -> CompValue:
    return CompValue(self.name, **self)

get

get(a, variables: bool = False, errors: bool = False)
Source code in rdflib/plugins/sparql/parserutils.py
def get(self, a, variables: bool = False, errors: bool = False):  # type: ignore[override]
    return self._value(OrderedDict.get(self, a, a), variables, errors)

Expr

Expr(name: str, evalfn: Optional[Callable[[Any, Any], Any]] = None, **values)

Bases: CompValue

A CompValue that is evaluatable

Methods:

Source code in rdflib/plugins/sparql/parserutils.py
def __init__(
    self,
    name: str,
    evalfn: Optional[Callable[[Any, Any], Any]] = None,
    **values,
):
    super(Expr, self).__init__(name, **values)

    self._evalfn = None
    if evalfn:
        self._evalfn = MethodType(evalfn, self)

eval

eval(ctx: Any = {}) -> Union[SPARQLError, Any]
Source code in rdflib/plugins/sparql/parserutils.py
def eval(self, ctx: Any = {}) -> Union[SPARQLError, Any]:
    try:
        self.ctx: Optional[Union[Mapping, FrozenBindings]] = ctx
        # type error: "None" not callable
        return self._evalfn(ctx)  # type: ignore[misc]
    except SPARQLError as e:
        return e
    finally:
        self.ctx = None

Param

Param(name: str, expr, isList: bool = False)

Bases: TokenConverter

A pyparsing token for labelling a part of the parse-tree if isList is true repeat occurrences of ParamList have their values merged in a list

Methods:

Attributes:

Source code in rdflib/plugins/sparql/parserutils.py
def __init__(self, name: str, expr, isList: bool = False):
    self.isList = isList
    TokenConverter.__init__(self, expr)
    self.setName(name)
    self.addParseAction(self.postParse2)

isList instance-attribute

isList = isList

postParse2

postParse2(tokenList: Union[List[Any], ParseResults]) -> ParamValue
Source code in rdflib/plugins/sparql/parserutils.py
def postParse2(self, tokenList: Union[List[Any], ParseResults]) -> ParamValue:
    return ParamValue(self.name, tokenList, self.isList)

ParamList

ParamList(name: str, expr)

Bases: Param

A shortcut for a Param with isList=True

Source code in rdflib/plugins/sparql/parserutils.py
def __init__(self, name: str, expr):
    Param.__init__(self, name, expr, True)

ParamValue

ParamValue(name: str, tokenList: Union[List[Any], ParseResults], isList: bool)

The result of parsing a Param This just keeps the name/value All cleverness is in the CompValue

Methods:

Attributes:

Source code in rdflib/plugins/sparql/parserutils.py
def __init__(
    self, name: str, tokenList: Union[List[Any], ParseResults], isList: bool
):
    self.isList = isList
    self.name = name
    if isinstance(tokenList, (list, ParseResults)) and len(tokenList) == 1:
        tokenList = tokenList[0]

    self.tokenList = tokenList

isList instance-attribute

isList = isList

name instance-attribute

name = name

tokenList instance-attribute

tokenList = tokenList

__str__

__str__() -> str
Source code in rdflib/plugins/sparql/parserutils.py
def __str__(self) -> str:
    return "Param(%s, %s)" % (self.name, self.tokenList)

prettify_parsetree

prettify_parsetree(t: ParseResults, indent: str = '', depth: int = 0) -> str
Source code in rdflib/plugins/sparql/parserutils.py
def prettify_parsetree(t: ParseResults, indent: str = "", depth: int = 0) -> str:
    out: List[str] = []
    for e in t.asList():
        out.append(_prettify_sub_parsetree(e, indent, depth + 1))
    for k, v in sorted(t.items()):
        out.append("%s%s- %s:\n" % (indent, "  " * depth, k))
        out.append(_prettify_sub_parsetree(v, indent, depth + 1))
    return "".join(out)

value

value(ctx: FrozenBindings, val: Any, variables: bool = False, errors: bool = False) -> Any

Utility function for evaluating something…

Variables will be looked up in the context Normally, non-bound vars is an error, set variables=True to return unbound vars

Normally, an error raises the error, set errors=True to return error

Source code in rdflib/plugins/sparql/parserutils.py
def value(
    ctx: FrozenBindings,
    val: Any,
    variables: bool = False,
    errors: bool = False,
) -> Any:
    """Utility function for evaluating something...

    Variables will be looked up in the context
    Normally, non-bound vars is an error,
    set variables=True to return unbound vars

    Normally, an error raises the error,
    set errors=True to return error
    """

    if isinstance(val, Expr):
        return val.eval(ctx)  # recurse?
    elif isinstance(val, CompValue):
        raise Exception("What do I do with this CompValue? %s" % val)

    elif isinstance(val, list):
        return [value(ctx, x, variables, errors) for x in val]

    elif isinstance(val, (BNode, Variable)):
        r = ctx.get(val)
        if isinstance(r, SPARQLError) and not errors:
            raise r
        if r is not None:
            return r

        # not bound
        if variables:
            return val
        else:
            raise NotBoundError

    elif isinstance(val, ParseResults) and len(val) == 1:
        return value(ctx, val[0], variables, errors)
    else:
        return val