Skip to content

Commit 88813d5

Browse files
committed
Allow production lists to refer to tokens from other production groups.
Outside production lists, syntax "`foo:bar`" already makes it possible to refer to the production "bar" of group "foo". This commit offers the same feature inside production lists. Similarly to the reference syntax, prefixing with a tilde prevents the group from being displayed. This commit also makes it possible to use "`:bar`" to refer to production "bar" from a production list without a group name. This is especially useful when one has a main (unnamed) grammar and one or several named extensions that need to refer to it.
1 parent 3f58415 commit 88813d5

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

doc/usage/restructuredtext/directives.rst

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,20 +1199,29 @@ the definition of the symbol. There is this directive:
11991199
the following definition. If the definition spans multiple lines, each
12001200
continuation line must begin with a colon placed at the same column as in
12011201
the first line.
1202+
Blank lines are not allowed within ``productionlist`` directive arguments.
1203+
1204+
The definition can contain token names which are marked as interpreted text
1205+
(e.g., "``sum ::= `integer` "+" `integer```") -- this generates
1206+
cross-references to the productions of these tokens. Outside of the
1207+
production list, you can reference to token productions using
1208+
:rst:role:`token`.
12021209

12031210
The *productionGroup* argument to :rst:dir:`productionlist` serves to
12041211
distinguish different sets of production lists that belong to different
12051212
grammars. Multiple production lists with the same *productionGroup* thus
12061213
define rules in the same scope.
12071214

1208-
Blank lines are not allowed within ``productionlist`` directive arguments.
1215+
Inside of the production list, tokens implicitly refer to productions
1216+
from the current group. You can refer to the production of another
1217+
grammar by prefixing the token with its group name and a colon, e.g,
1218+
"``otherGroup:sum``". If the group of the token should not be shown in
1219+
the production, it can be prefixed by a tilde, e.g.,
1220+
"``~otherGroup:sum``". To refer to a production from an unnamed
1221+
grammar, the token should be prefixed by a colon, e.g., "``:sum``".
12091222

1210-
The definition can contain token names which are marked as interpreted text
1211-
(e.g. "``sum ::= `integer` "+" `integer```") -- this generates
1212-
cross-references to the productions of these tokens. Outside of the
1213-
production list, you can reference to token productions using
1214-
:rst:role:`token`.
1215-
However, if you have given a *productionGroup* argument you must prefix the
1223+
Outside of the production list,
1224+
if you have given a *productionGroup* argument you must prefix the
12161225
token name in the cross-reference with the group name and a colon,
12171226
e.g., "``myGroup:sum``" instead of just "``sum``".
12181227
If the group should not be shown in the title of the link either

sphinx/domains/std.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
# RE for option descriptions
4646
option_desc_re = re.compile(r'((?:/|--|-|\+)?[^\s=[]+)(=?\s*.*)')
4747
# RE for grammar tokens
48-
token_re = re.compile(r'`(\w+)`', re.U)
48+
token_re = re.compile(r'`((~?\w*:)?\w+)`', re.U)
4949

5050

5151
class GenericObject(ObjectDescription):
@@ -459,9 +459,23 @@ def token_xrefs(text: str, productionGroup: str = '') -> List[Node]:
459459
if m.start() > pos:
460460
txt = text[pos:m.start()]
461461
retnodes.append(nodes.Text(txt, txt))
462-
refnode = pending_xref(m.group(1), reftype='token', refdomain='std',
463-
reftarget=productionGroup + m.group(1))
464-
refnode += nodes.literal(m.group(1), m.group(1), classes=['xref'])
462+
token = m.group(1)
463+
if ':' in token:
464+
if token[0] == '~':
465+
_, title = token.split(':')
466+
target = token[1:]
467+
elif token[0] == ':':
468+
title = token[1:]
469+
target = title
470+
else:
471+
title = token
472+
target = token
473+
else:
474+
title = token
475+
target = productionGroup + token
476+
refnode = pending_xref(title, reftype='token', refdomain='std',
477+
reftarget=target)
478+
refnode += nodes.literal(token, title, classes=['xref'])
465479
retnodes.append(refnode)
466480
pos = m.end()
467481
if pos < len(text):

0 commit comments

Comments
 (0)