xref: /aosp_15_r20/external/starlark-go/syntax/testdata/errors.star (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faust# Tests of parse errors.
2*4947cdc7SCole Faust# This is a "chunked" file; each "---" line demarcates a new parser input.
3*4947cdc7SCole Faust#
4*4947cdc7SCole Faust# TODO(adonovan): lots more tests.
5*4947cdc7SCole Faust
6*4947cdc7SCole Faustx = 1 +
7*4947cdc7SCole Faust2 ### "got newline, want primary expression"
8*4947cdc7SCole Faust
9*4947cdc7SCole Faust---
10*4947cdc7SCole Faust
11*4947cdc7SCole Faust_ = *x ### `got '\*', want primary`
12*4947cdc7SCole Faust
13*4947cdc7SCole Faust---
14*4947cdc7SCole Faust# trailing comma is ok
15*4947cdc7SCole Faust
16*4947cdc7SCole Faustdef f(a, ): pass
17*4947cdc7SCole Faustdef f(*args, ): pass
18*4947cdc7SCole Faustdef f(**kwargs, ): pass
19*4947cdc7SCole Faust
20*4947cdc7SCole Faust---
21*4947cdc7SCole Faust
22*4947cdc7SCole Faust# Parameters are validated later.
23*4947cdc7SCole Faustdef f(**kwargs, *args, *, b=1, a, **kwargs, *args, *, b=1, a):
24*4947cdc7SCole Faust  pass
25*4947cdc7SCole Faust
26*4947cdc7SCole Faust---
27*4947cdc7SCole Faust
28*4947cdc7SCole Faustdef f(a, *-b, c): # ### `got '-', want ','`
29*4947cdc7SCole Faust  pass
30*4947cdc7SCole Faust
31*4947cdc7SCole Faust---
32*4947cdc7SCole Faust
33*4947cdc7SCole Faustdef f(**kwargs, *args, b=1, a, **kwargs, *args, b=1, a):
34*4947cdc7SCole Faust  pass
35*4947cdc7SCole Faust
36*4947cdc7SCole Faust---
37*4947cdc7SCole Faust
38*4947cdc7SCole Faustdef pass(): ### "not an identifier"
39*4947cdc7SCole Faust  pass
40*4947cdc7SCole Faust
41*4947cdc7SCole Faust---
42*4947cdc7SCole Faust
43*4947cdc7SCole Faustdef f : ### `got ':', want '\('`
44*4947cdc7SCole Faust
45*4947cdc7SCole Faust---
46*4947cdc7SCole Faust# trailing comma is ok
47*4947cdc7SCole Faust
48*4947cdc7SCole Faustf(a, )
49*4947cdc7SCole Faustf(*args, )
50*4947cdc7SCole Faustf(**kwargs, )
51*4947cdc7SCole Faust
52*4947cdc7SCole Faust---
53*4947cdc7SCole Faust
54*4947cdc7SCole Faustf(a=1, *, b=2) ### `got ',', want primary`
55*4947cdc7SCole Faust
56*4947cdc7SCole Faust---
57*4947cdc7SCole Faust
58*4947cdc7SCole Faust_ = {x:y for y in z} # ok
59*4947cdc7SCole Faust_ = {x for y in z}   ### `got for, want ':'`
60*4947cdc7SCole Faust
61*4947cdc7SCole Faust---
62*4947cdc7SCole Faust
63*4947cdc7SCole Faustdef f():
64*4947cdc7SCole Faust  pass
65*4947cdc7SCole Faust pass ### `unindent does not match any outer indentation level`
66*4947cdc7SCole Faust
67*4947cdc7SCole Faust---
68*4947cdc7SCole Faustdef f(): pass
69*4947cdc7SCole Faust---
70*4947cdc7SCole Faust# Blank line after pass => outdent.
71*4947cdc7SCole Faustdef f():
72*4947cdc7SCole Faust	pass
73*4947cdc7SCole Faust
74*4947cdc7SCole Faust---
75*4947cdc7SCole Faust# No blank line after pass; EOF acts like a newline.
76*4947cdc7SCole Faustdef f():
77*4947cdc7SCole Faust	pass
78*4947cdc7SCole Faust---
79*4947cdc7SCole Faust# This is a well known parsing ambiguity in Python.
80*4947cdc7SCole Faust# Python 2.7 accepts it but Python3 and Starlark reject it.
81*4947cdc7SCole Faust_ = [x for x in lambda: True, lambda: False if x()] ### "got lambda, want primary"
82*4947cdc7SCole Faust
83*4947cdc7SCole Faust_ = [x for x in (lambda: True, lambda: False) if x()] # ok in all dialects
84*4947cdc7SCole Faust
85*4947cdc7SCole Faust---
86*4947cdc7SCole Faust# Starlark, following Python 3, allows an unparenthesized
87*4947cdc7SCole Faust# tuple after 'in' only in a for statement but not in a comprehension.
88*4947cdc7SCole Faust# (Python 2.7 allows both.)
89*4947cdc7SCole Faustfor x in 1, 2, 3:
90*4947cdc7SCole Faust      print(x)
91*4947cdc7SCole Faust
92*4947cdc7SCole Faust_ = [x for x in 1, 2, 3] ### `got ',', want ']', for, or if`
93*4947cdc7SCole Faust---
94*4947cdc7SCole Faust# Unparenthesized tuple is not allowed as operand of 'if' in comprehension.
95*4947cdc7SCole Faust_ = [a for b in c if 1, 2] ### `got ',', want ']', for, or if`
96*4947cdc7SCole Faust
97*4947cdc7SCole Faust---
98*4947cdc7SCole Faust# Lambda is ok though.
99*4947cdc7SCole Faust_ = [a for b in c if lambda: d] # ok
100*4947cdc7SCole Faust
101*4947cdc7SCole Faust# But the body of such a lambda may not be a conditional:
102*4947cdc7SCole Faust_ = [a for b in c if (lambda: d if e else f)] # ok
103*4947cdc7SCole Faust_ = [a for b in c if lambda: d if e else f]   ### "got else, want ']'"
104*4947cdc7SCole Faust
105*4947cdc7SCole Faust---
106*4947cdc7SCole Faust# A lambda is not allowed as the operand of a 'for' clause.
107*4947cdc7SCole Faust_ = [a for b in lambda: c] ### `got lambda, want primary`
108*4947cdc7SCole Faust
109*4947cdc7SCole Faust---
110*4947cdc7SCole Faust# Comparison operations are not associative.
111*4947cdc7SCole Faust
112*4947cdc7SCole Faust_ = (0 == 1) == 2 # ok
113*4947cdc7SCole Faust_ = 0 == (1 == 2) # ok
114*4947cdc7SCole Faust_ = 0 == 1 == 2 ### "== does not associate with =="
115*4947cdc7SCole Faust
116*4947cdc7SCole Faust---
117*4947cdc7SCole Faust
118*4947cdc7SCole Faust_ = (0 <= i) < n   # ok
119*4947cdc7SCole Faust_ = 0 <= (i < n) # ok
120*4947cdc7SCole Faust_ = 0 <= i < n ### "<= does not associate with <"
121*4947cdc7SCole Faust
122*4947cdc7SCole Faust---
123*4947cdc7SCole Faust
124*4947cdc7SCole Faust_ = (a in b) not in c  # ok
125*4947cdc7SCole Faust_ = a in (b not in c)  # ok
126*4947cdc7SCole Faust_ = a in b not in c    ### "in does not associate with not in"
127*4947cdc7SCole Faust
128*4947cdc7SCole Faust---
129*4947cdc7SCole Faust# shift/reduce ambiguity is reduced
130*4947cdc7SCole Faust_ = [x for x in a if b else c] ### `got else, want ']', for, or if`
131*4947cdc7SCole Faust---
132*4947cdc7SCole Faust[a for b in c else d] ### `got else, want ']', for, or if`
133*4947cdc7SCole Faust---
134*4947cdc7SCole Faust_ = a + b not c ### "got identifier, want in"
135*4947cdc7SCole Faust---
136*4947cdc7SCole Faustf(1+2 = 3) ### "keyword argument must have form name=expr"
137*4947cdc7SCole Faust---
138*4947cdc7SCole Faustprint(1, 2, 3
139*4947cdc7SCole Faust### `got end of file, want '\)'`
140*4947cdc7SCole Faust---
141*4947cdc7SCole Faust_ = a if b ### "conditional expression without else clause"
142*4947cdc7SCole Faust---
143*4947cdc7SCole Faustload("") ### "load statement must import at least 1 symbol"
144*4947cdc7SCole Faust---
145*4947cdc7SCole Faustload("", 1) ### `load operand must be "name" or localname="name" \(got int literal\)`
146*4947cdc7SCole Faust---
147*4947cdc7SCole Faustload("a", "x") # ok
148*4947cdc7SCole Faust---
149*4947cdc7SCole Faustload(1, 2) ### "first operand of load statement must be a string literal"
150*4947cdc7SCole Faust---
151*4947cdc7SCole Faustload("a", x) ### `load operand must be "x" or x="originalname"`
152*4947cdc7SCole Faust---
153*4947cdc7SCole Faustload("a", x2=x) ### `original name of loaded symbol must be quoted: x2="originalname"`
154*4947cdc7SCole Faust---
155*4947cdc7SCole Faust# All of these parse.
156*4947cdc7SCole Faustload("a", "x")
157*4947cdc7SCole Faustload("a", "x", y2="y")
158*4947cdc7SCole Faustload("a", x2="x", "y") # => positional-before-named arg check happens later (!)
159*4947cdc7SCole Faust---
160*4947cdc7SCole Faust# 'load' is not an identifier
161*4947cdc7SCole Faustload = 1 ### `got '=', want '\('`
162*4947cdc7SCole Faust---
163*4947cdc7SCole Faust# 'load' is not an identifier
164*4947cdc7SCole Faustf(load()) ### `got load, want primary`
165*4947cdc7SCole Faust---
166*4947cdc7SCole Faust# 'load' is not an identifier
167*4947cdc7SCole Faustdef load(): ### `not an identifier`
168*4947cdc7SCole Faust  pass
169*4947cdc7SCole Faust---
170*4947cdc7SCole Faust# 'load' is not an identifier
171*4947cdc7SCole Faustdef f(load): ### `not an identifier`
172*4947cdc7SCole Faust  pass
173*4947cdc7SCole Faust---
174*4947cdc7SCole Faust# A load statement allows a trailing comma.
175*4947cdc7SCole Faustload("module", "x",)
176*4947cdc7SCole Faust---
177*4947cdc7SCole Faustx = 1 +
178*4947cdc7SCole Faust2 ### "got newline, want primary expression"
179*4947cdc7SCole Faust---
180*4947cdc7SCole Faustdef f():
181*4947cdc7SCole Faust    pass
182*4947cdc7SCole Faust# this used to cause a spurious indentation error
183*4947cdc7SCole Faust---
184*4947cdc7SCole Faustprint 1 2 ### `got int literal, want newline`
185*4947cdc7SCole Faust
186*4947cdc7SCole Faust---
187*4947cdc7SCole Faust# newlines are not allowed in raw string literals
188*4947cdc7SCole Faustraw = r'a ### `unexpected newline in string`
189*4947cdc7SCole Faustb'
190*4947cdc7SCole Faust
191*4947cdc7SCole Faust---
192*4947cdc7SCole Faust# The parser permits an unparenthesized tuple expression for the first index.
193*4947cdc7SCole Faustx[1, 2:] # ok
194*4947cdc7SCole Faust---
195*4947cdc7SCole Faust# But not if it has a trailing comma.
196*4947cdc7SCole Faustx[1, 2,:] ### `got ':', want primary`
197*4947cdc7SCole Faust---
198*4947cdc7SCole Faust# Trailing tuple commas are permitted only within parens; see b/28867036.
199*4947cdc7SCole Faust(a, b,) = 1, 2 # ok
200*4947cdc7SCole Faustc, d = 1, 2 # ok
201*4947cdc7SCole Faust---
202*4947cdc7SCole Fausta, b, = 1, 2 ### `unparenthesized tuple with trailing comma`
203*4947cdc7SCole Faust---
204*4947cdc7SCole Fausta, b = 1, 2, ### `unparenthesized tuple with trailing comma`
205*4947cdc7SCole Faust
206*4947cdc7SCole Faust---
207*4947cdc7SCole Faust# See github.com/google/starlark-go/issues/48
208*4947cdc7SCole Fausta = max(range(10))) ### `unexpected '\)'`
209*4947cdc7SCole Faust
210*4947cdc7SCole Faust---
211*4947cdc7SCole Faust# github.com/google/starlark-go/issues/85
212*4947cdc7SCole Fausts = "\x-0" ### `invalid escape sequence`
213