#
root/livinglogic.python.xist/src/ll/UL4.g
@
5312:9a98178e4483

Revision 5312:9a98178e4483, 10.1 KB (checked in by Walter Doerwald <walter@…>, 7 years ago) |
---|

Line | |
---|---|

1 | grammar UL4; |

2 | |

3 | options |

4 | { |

5 | language=Python; |

6 | backtrack=true; |

7 | } |

8 | |

9 | @lexer::header |

10 | { |

11 | from ll import ul4c |

12 | } |

13 | |

14 | @header |

15 | { |

16 | import datetime, ast |

17 | from ll import ul4c, color |

18 | } |

19 | |

20 | @lexer::members { |

21 | def reportError(self, e): |

22 | raise e |

23 | } |

24 | |

25 | @members { |

26 | def mismatch(self, input, ttype, follow): |

27 | raise MismatchedTokenException(ttype, input) |

28 | |

29 | def recoverFromMismatchedSet(self, input, e, follow): |

30 | raise e |

31 | } |

32 | |

33 | @rulecatch { |

34 | except RecognitionException as e: |

35 | raise |

36 | } |

37 | |

38 | NONE |

39 | : 'None' |

40 | ; |

41 | |

42 | TRUE |

43 | : 'True' |

44 | ; |

45 | |

46 | FALSE |

47 | : 'False' |

48 | ; |

49 | |

50 | NAME |

51 | : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* |

52 | ; |

53 | |

54 | fragment |

55 | DIGIT |

56 | : '0'..'9' |

57 | ; |

58 | |

59 | fragment |

60 | BIN_DIGIT |

61 | : ('0'|'1') |

62 | ; |

63 | |

64 | fragment |

65 | OCT_DIGIT |

66 | : '0'..'7' |

67 | ; |

68 | |

69 | fragment |

70 | HEX_DIGIT |

71 | : ('0'..'9'|'a'..'f'|'A'..'F') |

72 | ; |

73 | |

74 | /* We don't have negative ints (as this would lex "1-2" wrong) */ |

75 | INT |

76 | : DIGIT+ |

77 | | '0' ('b'|'B') BIN_DIGIT+ |

78 | | '0' ('o'|'O') OCT_DIGIT+ |

79 | | '0' ('x'|'X') HEX_DIGIT+ |

80 | ; |

81 | |

82 | fragment |

83 | EXPONENT |

84 | : ('e'|'E') ('+'|'-')? DIGIT+ |

85 | ; |

86 | |

87 | FLOAT |

88 | : DIGIT+ '.' DIGIT* EXPONENT? |

89 | | '.' DIGIT+ EXPONENT? |

90 | | DIGIT+ EXPONENT |

91 | ; |

92 | |

93 | fragment |

94 | TIME |

95 | : DIGIT DIGIT ':' DIGIT DIGIT ( ':' DIGIT DIGIT ( '.' DIGIT DIGIT DIGIT DIGIT DIGIT DIGIT)?)?; |

96 | |

97 | DATE |

98 | : '@' '(' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT ('T' TIME?)? ')'; |

99 | |

100 | COLOR |

101 | : '#' HEX_DIGIT HEX_DIGIT HEX_DIGIT |

102 | | '#' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT |

103 | | '#' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT |

104 | | '#' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT |

105 | ; |

106 | |

107 | WS |

108 | : (' '|'\t'|'\r'|'\n') { $channel=HIDDEN; } |

109 | ; |

110 | |

111 | STRING |

112 | : '"' ( ESC_SEQ | ~('\\'|'"'|'\r'|'\n') )* '"' |

113 | | '\'' ( ESC_SEQ | ~('\\'|'\''|'\r'|'\n') )* '\'' |

114 | ; |

115 | |

116 | fragment |

117 | ESC_SEQ |

118 | : '\\' ('a'|'b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') |

119 | | UNICODE1_ESC |

120 | | UNICODE2_ESC |

121 | | UNICODE4_ESC |

122 | ; |

123 | |

124 | fragment |

125 | UNICODE1_ESC |

126 | : '\\' 'x' HEX_DIGIT HEX_DIGIT |

127 | ; |

128 | |

129 | fragment |

130 | UNICODE2_ESC |

131 | : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT |

132 | ; |

133 | |

134 | fragment |

135 | UNICODE4_ESC |

136 | : '\\' 'U' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT |

137 | ; |

138 | |

139 | |

140 | /* Rules common to all tags */ |

141 | |

142 | none returns [node] |

143 | : NONE { $node = ul4c.Const(None); } |

144 | ; |

145 | |

146 | true_ returns [node] |

147 | : TRUE { $node = ul4c.Const(True); } |

148 | ; |

149 | |

150 | false_ returns [node] |

151 | : FALSE { $node = ul4c.Const(False); } |

152 | ; |

153 | |

154 | int_ returns [node] |

155 | : INT { $node = ul4c.Const(int($INT.text, 0)); } |

156 | ; |

157 | |

158 | float_ returns [node] |

159 | : FLOAT { $node = ul4c.Const(float($FLOAT.text)); } |

160 | ; |

161 | |

162 | string returns [node] |

163 | : STRING { $node = ul4c.Const(ast.literal_eval($STRING.text)); } |

164 | ; |

165 | |

166 | date returns [node] |

167 | : DATE { $node = ul4c.Const(datetime.datetime(*map(int, [f for f in ul4c.datesplitter.split($DATE.text[2:-1]) if f]))); } |

168 | ; |

169 | |

170 | color returns [node] |

171 | : COLOR { $node = ul4c.Const(color.Color.fromrepr($COLOR.text)); } |

172 | ; |

173 | |

174 | name returns [node] |

175 | : NAME { $node = ul4c.Var($NAME.text); } |

176 | ; |

177 | |

178 | literal returns [node] |

179 | : e_none=none { $node = $e_none.node; } |

180 | | e_false=false_ { $node = $e_false.node; } |

181 | | e_true=true_ { $node = $e_true.node; } |

182 | | e_int=int_ { $node = $e_int.node; } |

183 | | e_float=float_ { $node = $e_float.node; } |

184 | | e_string=string { $node = $e_string.node; } |

185 | | e_date=date { $node = $e_date.node; } |

186 | | e_color=color { $node = $e_color.node; } |

187 | | e_name=name { $node = $e_name.node; } |

188 | ; |

189 | |

190 | /* List literals */ |

191 | list returns [node] |

192 | : |

193 | '[' |

194 | ']' { $node = ul4c.List(); } |

195 | | |

196 | '[' {$node = ul4c.List(); } |

197 | e1=expr1 { $node.items.append($e1.node); } |

198 | ( |

199 | ',' |

200 | e2=expr1 { $node.items.append($e2.node); } |

201 | )* |

202 | ','? |

203 | ']' |

204 | ; |

205 | |

206 | listcomprehension returns [node] |

207 | @init |

208 | { |

209 | _condition = None; |

210 | } |

211 | : |

212 | '[' |

213 | item=expr1 |

214 | 'for' |

215 | n=nestedname |

216 | 'in' |

217 | container=expr1 |

218 | ( |

219 | 'if' |

220 | condition=expr1 { _condition = $condition.node; } |

221 | )? |

222 | ']' { $node = ul4c.ListComp($item.node, $n.varname, $container.node, _condition); } |

223 | ; |

224 | |

225 | /* Dict literal */ |

226 | fragment |

227 | dictitem returns [node] |

228 | : |

229 | k=expr1 |

230 | ':' |

231 | v=expr1 { $node = ($k.node, $v.node); } |

232 | | |

233 | '**' |

234 | d=expr1 { $node = ($d.node,); } |

235 | ; |

236 | |

237 | dict returns [node] |

238 | : |

239 | '{' |

240 | '}' { $node = ul4c.Dict(); } |

241 | | |

242 | '{' { $node = ul4c.Dict(); } |

243 | i1=dictitem { $node.items.append($i1.node); } |

244 | ( |

245 | ',' |

246 | i2=dictitem { $node.items.append($i2.node); } |

247 | )* |

248 | ','? |

249 | '}' |

250 | ; |

251 | |

252 | dictcomprehension returns [node] |

253 | @init |

254 | { |

255 | _condition = None; |

256 | } |

257 | : |

258 | '{' |

259 | key=expr1 |

260 | ':' |

261 | value=expr1 |

262 | 'for' |

263 | n=nestedname |

264 | 'in' |

265 | container=expr1 |

266 | ( |

267 | 'if' |

268 | condition=expr1 { _condition = $condition.node; } |

269 | )? |

270 | '}' { $node = ul4c.DictComp($key.node, $value.node, $n.varname, $container.node, _condition); } |

271 | ; |

272 | |

273 | generatorexpression returns [node] |

274 | @init |

275 | { |

276 | _condition = None; |

277 | } |

278 | : |

279 | item=expr1 |

280 | 'for' |

281 | n=nestedname |

282 | 'in' |

283 | container=expr1 |

284 | ( |

285 | 'if' |

286 | condition=expr1 { _condition = $condition.node; } |

287 | )? { $node = ul4c.GenExpr($item.node, $n.varname, $container.node, _condition); } |

288 | ; |

289 | |

290 | atom returns [node] |

291 | : e_literal=literal { $node = $e_literal.node; } |

292 | | e_list=list { $node = $e_list.node; } |

293 | | e_listcomp=listcomprehension { $node = $e_listcomp.node; } |

294 | | e_dict=dict { $node = $e_dict.node; } |

295 | | e_dictcomp=dictcomprehension { $node = $e_dictcomp.node; } |

296 | | '(' e_genexpr=generatorexpression ')' { $node = $e_genexpr.node; } |

297 | | '(' e_bracket=expr1 ')' { $node = $e_bracket.node; } |

298 | ; |

299 | |

300 | /* For variable unpacking in assignments and for loops */ |

301 | nestedname returns [varname] |

302 | : |

303 | n=name { $varname = $n.text; } |

304 | | |

305 | '(' n0=nestedname ',' ')' { $varname = ($n0.varname,); } |

306 | | |

307 | '(' |

308 | n1=nestedname |

309 | ',' |

310 | n2=nestedname { $varname = ($n1.varname, $n2.varname); } |

311 | ( |

312 | ',' |

313 | n3=nestedname { $varname += ($n3.varname,); } |

314 | )* |

315 | ','? |

316 | ')' |

317 | ; |

318 | |

319 | /* Function/method call, attribute access, item access, slice access */ |

320 | expr9 returns [node] |

321 | @init |

322 | { |

323 | callmeth = False |

324 | index1 = None |

325 | index2 = None |

326 | slice = False |

327 | } |

328 | : |

329 | e1=atom { $node = $e1.node; } |

330 | ( |

331 | /* Attribute access */ |

332 | '.' |

333 | n=name { $node = ul4c.GetAttr($node, $n.text); } |

334 | | |

335 | /* Function/method call */ |

336 | '(' { $node = ul4c.CallMeth($node.obj, $node.attrname) if isinstance($node, ul4c.GetAttr) else ul4c.CallFunc($node); } |

337 | ( |

338 | /* No arguments */ |

339 | | |

340 | /* "**" argument only */ |

341 | '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; } |

342 | ','? |

343 | | |

344 | /* "*" argument only (and maybe **) */ |

345 | '*' rargs=exprarg { $node.remargs = $rargs.node; } |

346 | ( |

347 | ',' |

348 | '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; } |

349 | )? |

350 | ','? |

351 | | |

352 | /* At least one positional argument */ |

353 | a1=exprarg { $node.args.append($a1.node); } |

354 | ( |

355 | ',' |

356 | a2=exprarg { $node.args.append($a2.node); } |

357 | )* |

358 | ( |

359 | ',' |

360 | an3=name '=' av3=exprarg { $node.kwargs.append(($an3.text, $av3.node)); } |

361 | )* |

362 | ( |

363 | ',' |

364 | '*' rargs=exprarg { $node.remargs = $rargs.node; } |

365 | )? |

366 | ( |

367 | ',' |

368 | '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; } |

369 | )? |

370 | ','? |

371 | | |

372 | /* Keyword arguments only */ |

373 | an1=name '=' av1=exprarg { $node.kwargs.append(($an1.text, $av1.node)); } |

374 | ( |

375 | ',' |

376 | an2=name '=' av2=exprarg { $node.kwargs.append(($an2.text, $av2.node)); } |

377 | )* |

378 | ( |

379 | ',' |

380 | '*' rargs=exprarg { $node.remargs = $rargs.node; } |

381 | )? |

382 | ( |

383 | ',' |

384 | '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; } |

385 | )? |

386 | ','? |

387 | ) |

388 | ')' |

389 | | |

390 | /* Item/slice access */ |

391 | '[' |

392 | ( |

393 | ':' |

394 | ( |

395 | e2=expr1 { index2 = $e2.node; } |

396 | )? { $node = ul4c.GetSlice($node, None, index2); } |

397 | | |

398 | e2=expr1 { index1 = $e2.node; } |

399 | ( |

400 | ':' { slice = True; } |

401 | ( |

402 | e3=expr1 { index2 = $e3.node; } |

403 | )? |

404 | )? { $node = ul4c.GetSlice($node, index1, index2) if slice else ul4c.GetItem($node, index1); } |

405 | ) |

406 | ']' |

407 | )* |

408 | ; |

409 | |

410 | /* Negation */ |

411 | expr8 returns [node] |

412 | @init |

413 | { |

414 | count = 0; |

415 | } |

416 | : |

417 | ( |

418 | '-' { count += 1; } |

419 | )* |

420 | e=expr9 { |

421 | $node = $e.node; |

422 | for i in range(count): |

423 | $node = ul4c.Neg($node); |

424 | } |

425 | ; |

426 | |

427 | /* Multiplication, division, modulo */ |

428 | expr7 returns [node] |

429 | : |

430 | e1=expr8 { $node = $e1.node; } |

431 | ( |

432 | ( |

433 | '*' { cls = ul4c.Mul; } |

434 | | |

435 | '/' { cls = ul4c.TrueDiv; } |

436 | | |

437 | '//' { cls = ul4c.FloorDiv; } |

438 | | |

439 | '%' { cls = ul4c.Mod; } |

440 | ) |

441 | e2=expr8 { $node = cls($node, $e2.node); } |

442 | )* |

443 | ; |

444 | |

445 | /* Addition, substraction */ |

446 | expr6 returns [node] |

447 | : |

448 | e1=expr7 { $node = $e1.node; } |

449 | ( |

450 | ( |

451 | '+' { cls = ul4c.Add; } |

452 | | |

453 | '-' { cls = ul4c.Sub; } |

454 | ) |

455 | e2=expr7 { $node = cls($node, $e2.node) } |

456 | )* |

457 | ; |

458 | |

459 | /* Comparisons */ |

460 | expr5 returns [node] |

461 | : |

462 | e1=expr6 { $node = $e1.node; } |

463 | ( |

464 | ( |

465 | '==' { cls = ul4c.EQ; } |

466 | | |

467 | '!=' { cls = ul4c.NE; } |

468 | | |

469 | '<' { cls = ul4c.LT; } |

470 | | |

471 | '<=' { cls = ul4c.LE; } |

472 | | |

473 | '>' { cls = ul4c.GT; } |

474 | | |

475 | '>=' { cls = ul4c.GE; } |

476 | ) |

477 | e2=expr6 { $node = cls($node, $e2.node); } |

478 | )* |

479 | ; |

480 | |

481 | /* "in"/"not in" operator */ |

482 | expr4 returns [node] |

483 | : |

484 | e1=expr5 { $node = $e1.node; } |

485 | ( |

486 | { cls = ul4c.Contains; } |

487 | ( |

488 | 'not' { cls = ul4c.NotContains; } |

489 | )? |

490 | 'in' |

491 | e2=expr5 { $node = cls($node, $e2.node); } |

492 | )? |

493 | ; |

494 | |

495 | /* Not operator */ |

496 | expr3 returns [node] |

497 | : |

498 | 'not' |

499 | e=expr4 { $node = ul4c.Not($e.node); } |

500 | | |

501 | e=expr4 { $node = $e.node; } |

502 | ; |

503 | |

504 | |

505 | /* And operator */ |

506 | expr2 returns [node] |

507 | : |

508 | e1=expr3 { $node = $e1.node; } |

509 | ( |

510 | 'and' |

511 | e2=expr3 { $node = ul4c.And($node, $e2.node); } |

512 | )* |

513 | ; |

514 | |

515 | /* Or operator */ |

516 | expr1 returns [node] |

517 | : |

518 | e1=expr2 { $node = $e1.node; } |

519 | ( |

520 | 'or' |

521 | e2=expr2 { $node = ul4c.Or($node, $e2.node); } |

522 | )* |

523 | ; |

524 | |

525 | exprarg returns [node] |

526 | : ege=generatorexpression { $node = $ege.node; } |

527 | | e1=expr1 { $node = $e1.node; } |

528 | ; |

529 | |

530 | expression returns [node] |

531 | : ege=generatorexpression EOF { $node = $ege.node; } |

532 | | e=expr1 EOF { $node = $e.node; } |

533 | ; |

534 | |

535 | |

536 | /* Additional rules for "for" tag */ |

537 | |

538 | for_ returns [node] |

539 | : |

540 | n=nestedname |

541 | 'in' |

542 | e=expr1 { $node = ul4c.For(self.location, $n.varname, $e.node); } |

543 | EOF |

544 | ; |

545 | |

546 | |

547 | /* Additional rules for "code" tag */ |

548 | |

549 | statement returns [node] |

550 | : nn=nestedname '=' e=expr1 EOF { $node = ul4c.StoreVar(self.location, $nn.varname, $e.node); } |

551 | | n=name '+=' e=expr1 EOF { $node = ul4c.AddVar(self.location, $n.text, $e.node); } |

552 | | n=name '-=' e=expr1 EOF { $node = ul4c.SubVar(self.location, $n.text, $e.node); } |

553 | | n=name '*=' e=expr1 EOF { $node = ul4c.MulVar(self.location, $n.text, $e.node); } |

554 | | n=name '/=' e=expr1 EOF { $node = ul4c.TrueDivVar(self.location, $n.text, $e.node); } |

555 | | n=name '//=' e=expr1 EOF { $node = ul4c.FloorDivVar(self.location, $n.text, $e.node); } |

556 | | n=name '%=' e=expr1 EOF { $node = ul4c.ModVar(self.location, $n.text, $e.node); } |

557 | ; |

**Note:**See TracBrowser for help on using the browser.