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