pygments-pss
A Pygments lexer for the Accellera Portable Test and Stimulus Standard (PSS), packaged as a plugin. Installing it is the entire configuration step:
pip install pygments-pss
After that, pss is a language Pygments knows about everywhere it looks — no
conf.py entry, no mkdocs.yml entry, no registration call:
pygmentize -l pss my_test.pss
```pss
component pss_top {
action entry {
activity {
do mem_write;
}
}
}
```
Targets PSS 3.1 (Draft 19), including annotations, monitors, behavioral coverage and triple-quoted target templates, and lexes earlier revisions unchanged.
Why
Pygments ships no PSS lexer, so every documentation pipeline that shows PSS either renders it as plain text or hand-rolls a lexer. This is that lexer, once, with tests.
Usage
Sphinx — nothing to configure; the entry point is enough.
.. code-block:: pss
component pss_top { }
MyST/Markdown fences (```pss) work the same way. Options go through
highlight_options:
highlight_options = {"pss": {"builtins": False}}
MkDocs — install the package; pymdownx.highlight picks it up. No mkdocs.yml
change is needed beyond whatever highlighting extension you already use.
Command line
pygmentize -l pss -f html -O full,style=friendly -o out.html my_test.pss
pygmentize -S friendly -f html > pygments.css # stylesheet for fragments
pygmentize -l pss -f terminal256 my_test.pss # 256-colour terminal
Python
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import get_lexer_by_name
print(highlight(source, get_lexer_by_name("pss"), HtmlFormatter()))
Options
| Option | Type | Default | Effect |
|---|---|---|---|
docstrings |
bool | True |
Highlight ///, //!, /** */ and /*! */ as Comment.Special. A psstools convention rather than a PSS one; costs nothing for projects that do not use it. |
builtins |
bool | True |
Highlight core-library names (Annex C: std_pkg, executor_pkg, addr_reg_pkg, sync_pkg) as Name.Builtin. |
Two further options — dialect (standard versus pssparser extensions) and
target_lexers (lex a exec body C = """…""" body as C/C++/SystemVerilog) — are
designed but not implemented in this release.
What gets highlighted
| Construct | Token |
|---|---|
// …, /* … */ |
Comment.Single, Comment.Multiline |
/// …, //! …, /** … */ |
Comment.Special |
compile if / has / assert |
Comment.Preproc |
| Type-declaring and qualifier keywords | Keyword.Declaration |
| Built-in types | Keyword.Type |
true, false, null |
Keyword.Constant |
this, super |
Name.Builtin.Pseudo |
@ann, .field in its parameters |
Name.Decorator, Name.Attribute |
| Declared name after a declaration keyword, and its base type | Name.Class |
package a::b, import a::b::* |
Name.Namespace |
foo( |
Name.Function |
| Core-library names | Name.Builtin |
8'hFF, 0xFF, 0b1010, 0755, 42 |
Number.Hex / Bin / Oct / Integer, by base |
1.5, 2e6 |
Number.Float |
"…" / """…""" |
String.Double / String.Heredoc |
{{expr}} / {% … %} in a template |
String.Interpol / Comment.Preproc, with PSS tokens inside |
Known deviations and false positives
Kept short and honest rather than absent:
- Whitespace-separated based literals are not supported. The LRM permits
8'h FF; supporting it costs a lookahead and risks mis-lexing8'hfollowed by an unrelated identifier.8'hFFis the supported form. - An escaped identifier runs to whitespace, so
\net1;includes the semicolon. That is Clause 4.3's rule, not a defect — the terminator is white space and nothing else. Write\net1 ;if you want the semicolon back. - A user-defined name that shadows a core-library name is highlighted as a builtin.
A
RegexLexerhas no scope information. Turn it off withbuiltins=False. numericis not treated as a keyword. It appears inpssparser's token list and in a damaged cell of the LRM's keyword table, but nowhere in the Annex B grammar. Highlighting a non-keyword is a visible error; missing one is mild.- Tool extensions are not keywords:
pyimport,pyobj,from,init,optionarepssparserreservations, not PSS. - Template parameter brackets are not special.
<and>stayOperator; distinguishing them from comparison needs a parser. One consequence: a templated declaration's base type (struct s<type T> : base_s) is not highlighted as a class. - A
typedef's declared name is an ordinaryName, because intypedef bit[3:0] nibble_t;the name comes after an arbitrary type expression.
Requirements
Python 3.9+ and Pygments 2.14+. No other runtime dependency: no parser, no ANTLR, no compiler.
License
Apache-2.0. See LICENSE.
Metadata
Release files for pygments-pss 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pygments_pss-0.1.1.tar.gz | 23.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pygments_pss-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.9 kB
Release files / pygments_pss-0.1.1.tar.gz
| Download URL | pygments_pss-0.1.1.tar.gz |
|---|---|
| Size | 23.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
719d07fd2c7d75a70316e6fb371f61ee6e156696eb449ee75d82b9df279a2163
|
|
BLAKE2b-256 checksum How to use checksums |
1a7f0b53c448d50706f14033ff89573c7edf050e22cd088507ec48061be48e3c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / pygments_pss-0.1.1-py3-none-any.whl
| Download URL | pygments_pss-0.1.1-py3-none-any.whl |
|---|---|
| Size | 22.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
09f625066443ea9c332eda4d4047c79b5471094c8748d718b9d7af5a5c26a264
|
|
BLAKE2b-256 checksum How to use checksums |
ea9803f7f81c9ff482bc3458fd8eb80926811bec38b78da0d754dd2bf5f470f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|