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