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:

- `prettify_parsetree` –
- `value` –

  Utility function for evaluating something…

## `` 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:

- `postParse` –
- `setEvalFn` –

Attributes:

- `evalfn` (`Optional[Callable[[Any, Any], Any]]`) –
- `expr` –

Source code in `rdflib/plugins/sparql/parserutils.py`

    238
    239
    240
    241
    242

    def __init__(self, name: str, expr: ParserElement):
        self.expr = expr
        TokenConverter.__init__(self, expr)
        self.set_name(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`

    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272

    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 = original_text_for(self.expr)
                service_string = sgp.search_string(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`

    274
    275
    276

    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:

- `__getattr__` –
- `__getitem__` –
- `__repr__` –
- `__setattr__` –
- `__str__` –
- `clone` –
- `get` –

Attributes:

- `name` –

Source code in `rdflib/plugins/sparql/parserutils.py`

    157
    158
    159
    160

    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`

    187
    188
    189
    190
    191
    192
    193
    194
    195

    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`

    179
    180

    def __getitem__(self, a):
        return self._value(OrderedDict.__getitem__(self, a))

### `` __repr__

    __repr__() -> str

Source code in `rdflib/plugins/sparql/parserutils.py`

    168
    169

    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`

    199

    def __setattr__(self, __name: str, __value: Any) -> None: ...

### `` __str__

    __str__() -> str

Source code in `rdflib/plugins/sparql/parserutils.py`

    165
    166

    def __str__(self) -> str:
        return self.name + "_" + OrderedDict.__str__(self)

### `` clone

    clone() -> CompValue

Source code in `rdflib/plugins/sparql/parserutils.py`

    162
    163

    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`

    184
    185

    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:

- `eval` –

Source code in `rdflib/plugins/sparql/parserutils.py`

    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217

    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`

    219
    220
    221
    222
    223
    224
    225
    226
    227

    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:

- `postParse2` –

Attributes:

- `isList` –

Source code in `rdflib/plugins/sparql/parserutils.py`

    128
    129
    130
    131
    132

    def __init__(self, name: str, expr, isList: bool = False):
        self.isList = isList
        TokenConverter.__init__(self, expr)
        self.set_name(name)
        self.add_parse_action(self.postParse2)

### `` isList `instance-attribute`

    isList = isList

### `` postParse2

    postParse2(tokenList: Union[List[Any], ParseResults]) -> ParamValue

Source code in `rdflib/plugins/sparql/parserutils.py`

    134
    135

    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`

    143
    144

    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:

- `__str__` –

Attributes:

- `isList` –
- `name` –
- `tokenList` –

Source code in `rdflib/plugins/sparql/parserutils.py`

    107
    108
    109
    110
    111
    112
    113
    114
    115

    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`

    117
    118

    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`

    279
    280
    281
    282
    283
    284
    285
    286

    def prettify_parsetree(t: ParseResults, indent: str = "", depth: int = 0) -> str:
        out: List[str] = []
        for e in t.as_list():
            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`

    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97

    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