Skip to content

Commit e04821e

Browse files
committed
Python: Allow use of match as an identifier
This previously only worked in certain circumstances. In particular, assignments such as `match[1] = ...` or even just `match[1]` would fail to parse correctly. Fixing this turned out to be less trivial than anticipated. Consider the fact that ``` match [1]: case (...) ``` can either look the start of a `match` statement, or it could be a type ascription, ascribing the value of `case(...)` (a call) to the item at index 1 of `match`. To fix this, then, we give `match` the identifier and `match` the statement the same precendence in the grammar, and additionally also mark a conflict between `match_statement` and `primary_expression`. This causes the conflict to be resolved dynamically, and seems to do the right thing in all cases.
1 parent ec09d36 commit e04821e

File tree

3 files changed

+160
-2
lines changed

3 files changed

+160
-2
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
Module: [1, 0] - [21, 0]
2+
body: [
3+
Expr: [1, 0] - [1, 8]
4+
value:
5+
Subscript: [1, 0] - [1, 8]
6+
value:
7+
Name: [1, 0] - [1, 5]
8+
variable: Variable('match', None)
9+
ctx: Load
10+
index:
11+
Num: [1, 6] - [1, 7]
12+
n: 1
13+
text: '1'
14+
ctx: Load
15+
Assign: [2, 0] - [2, 12]
16+
targets: [
17+
Subscript: [2, 0] - [2, 8]
18+
value:
19+
Name: [2, 0] - [2, 5]
20+
variable: Variable('match', None)
21+
ctx: Load
22+
index:
23+
Num: [2, 6] - [2, 7]
24+
n: 2
25+
text: '2'
26+
ctx: Store
27+
]
28+
value:
29+
Num: [2, 11] - [2, 12]
30+
n: 3
31+
text: '3'
32+
Assign: [4, 0] - [4, 13]
33+
targets: [
34+
Attribute: [4, 0] - [4, 9]
35+
value:
36+
Name: [4, 0] - [4, 5]
37+
variable: Variable('match', None)
38+
ctx: Load
39+
attr: 'foo'
40+
ctx: Store
41+
]
42+
value:
43+
Num: [4, 12] - [4, 13]
44+
n: 4
45+
text: '4'
46+
Expr: [6, 0] - [6, 7]
47+
value:
48+
Call: [6, 0] - [6, 7]
49+
func:
50+
Name: [6, 0] - [6, 5]
51+
variable: Variable('match', None)
52+
ctx: Load
53+
positional_args: []
54+
named_args: []
55+
AnnAssign: [8, 0] - [8, 15]
56+
value: None
57+
annotation:
58+
Name: [8, 11] - [8, 15]
59+
variable: Variable('case', None)
60+
ctx: Load
61+
target:
62+
Subscript: [8, 0] - [8, 8]
63+
value:
64+
Name: [8, 0] - [8, 5]
65+
variable: Variable('match', None)
66+
ctx: Load
67+
index:
68+
Num: [8, 6] - [8, 7]
69+
n: 5
70+
text: '5'
71+
ctx: Store
72+
Match: [12, 0] - [14, 12]
73+
subject:
74+
List: [12, 6] - [12, 9]
75+
elts: [
76+
Num: [12, 7] - [12, 8]
77+
n: 6
78+
text: '6'
79+
]
80+
ctx: Load
81+
cases: [
82+
Case: [13, 4] - [14, 12]
83+
pattern:
84+
MatchLiteralPattern: [13, 9] - [13, 10]
85+
literal:
86+
Num: [13, 9] - [13, 10]
87+
n: 7
88+
text: '7'
89+
guard: None
90+
body: [
91+
Pass: [14, 8] - [14, 12]
92+
]
93+
]
94+
Print: [17, 0] - [17, 19]
95+
dest:
96+
Num: [17, 9] - [17, 10]
97+
n: 8
98+
text: '8'
99+
values: [
100+
Str: [17, 12] - [17, 19]
101+
s: 'hello'
102+
prefix: '"'
103+
implicitly_concatenated_parts: None
104+
]
105+
nl: True
106+
Expr: [18, 0] - [18, 19]
107+
value:
108+
Tuple: [18, 0] - [18, 19]
109+
elts: [
110+
BinOp: [18, 0] - [18, 10]
111+
left:
112+
Name: [18, 0] - [18, 5]
113+
variable: Variable('pront', None)
114+
ctx: Load
115+
op: RShift
116+
right:
117+
Num: [18, 9] - [18, 10]
118+
n: 9
119+
text: '9'
120+
Str: [18, 12] - [18, 19]
121+
s: 'world'
122+
prefix: '"'
123+
implicitly_concatenated_parts: None
124+
]
125+
ctx: Load
126+
Expr: [20, 0] - [20, 10]
127+
value:
128+
Await: [20, 0] - [20, 10]
129+
value:
130+
List: [20, 6] - [20, 10]
131+
elts: [
132+
Num: [20, 7] - [20, 9]
133+
n: 10
134+
text: '10'
135+
]
136+
ctx: Load
137+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
match[1]
2+
match[2] = 3
3+
4+
match.foo = 4
5+
6+
match()
7+
8+
match[5] : case
9+
10+
11+
# match used "properly"
12+
match [6]:
13+
case 7:
14+
pass
15+
16+
17+
print >> 8, "hello" # Python 2-style print
18+
pront >> 9, "world" # How this would be interpreted in Python 3
19+
20+
await [10] # In Python 2 this would be an indexing operation, but it's more likely to be an await.

python/extractor/tsg-python/tsp/grammar.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module.exports = grammar({
3636
[$.tuple, $.tuple_pattern],
3737
[$.list, $.list_pattern],
3838
[$.with_item, $._collection_elements],
39+
[$.match_statement, $.primary_expression],
3940
],
4041

4142
supertypes: $ => [
@@ -349,7 +350,7 @@ module.exports = grammar({
349350
))
350351
)),
351352

352-
match_statement: $ => seq(
353+
match_statement: $ => prec(-3, seq(
353354
'match',
354355
field('subject',
355356
choice(
@@ -359,7 +360,7 @@ module.exports = grammar({
359360
),
360361
':',
361362
field('cases', $.cases)
362-
),
363+
)),
363364

364365
cases: $ => repeat1($.case_block),
365366

0 commit comments

Comments
 (0)