19 ) |
19 ) |
20 |
20 |
21 elements = { |
21 elements = { |
22 # token-type: binding-strength, primary, prefix, infix, suffix |
22 # token-type: binding-strength, primary, prefix, infix, suffix |
23 "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), |
23 "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), |
|
24 "[": (21, None, None, ("subscript", 1, "]"), None), |
|
25 "#": (21, None, None, ("relation", 21), None), |
24 "##": (20, None, None, ("_concat", 20), None), |
26 "##": (20, None, None, ("_concat", 20), None), |
25 "~": (18, None, None, ("ancestor", 18), None), |
27 "~": (18, None, None, ("ancestor", 18), None), |
26 "^": (18, None, None, ("parent", 18), "parentpost"), |
28 "^": (18, None, None, ("parent", 18), "parentpost"), |
27 "-": (5, None, ("negate", 19), ("minus", 5), None), |
29 "-": (5, None, ("negate", 19), ("minus", 5), None), |
28 "::": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"), |
30 "::": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"), |
37 "|": (4, None, None, ("or", 4), None), |
39 "|": (4, None, None, ("or", 4), None), |
38 "+": (4, None, None, ("or", 4), None), |
40 "+": (4, None, None, ("or", 4), None), |
39 "=": (3, None, None, ("keyvalue", 3), None), |
41 "=": (3, None, None, ("keyvalue", 3), None), |
40 ",": (2, None, None, ("list", 2), None), |
42 ",": (2, None, None, ("list", 2), None), |
41 ")": (0, None, None, None, None), |
43 ")": (0, None, None, None, None), |
|
44 "]": (0, None, None, None, None), |
42 "symbol": (0, "symbol", None, None, None), |
45 "symbol": (0, "symbol", None, None, None), |
43 "string": (0, "string", None, None, None), |
46 "string": (0, "string", None, None, None), |
44 "end": (0, None, None, None, None), |
47 "end": (0, None, None, None, None), |
45 } |
48 } |
46 |
49 |
47 keywords = {'and', 'or', 'not'} |
50 keywords = {'and', 'or', 'not'} |
48 |
51 |
49 _quoteletters = {'"', "'"} |
52 _quoteletters = {'"', "'"} |
50 _simpleopletters = set(pycompat.iterbytestr("():=,-|&+!~^%")) |
53 _simpleopletters = set(pycompat.iterbytestr("()[]#:=,-|&+!~^%")) |
51 |
54 |
52 # default set of valid characters for the initial letter of symbols |
55 # default set of valid characters for the initial letter of symbols |
53 _syminitletters = set(pycompat.iterbytestr( |
56 _syminitletters = set(pycompat.iterbytestr( |
54 string.ascii_letters.encode('ascii') + |
57 string.ascii_letters.encode('ascii') + |
55 string.digits.encode('ascii') + |
58 string.digits.encode('ascii') + |
329 return _fixops(('rangepost', post)) |
332 return _fixops(('rangepost', post)) |
330 elif op == 'or': |
333 elif op == 'or': |
331 # make number of arguments deterministic: |
334 # make number of arguments deterministic: |
332 # x + y + z -> (or x y z) -> (or (list x y z)) |
335 # x + y + z -> (or x y z) -> (or (list x y z)) |
333 return (op, _fixops(('list',) + x[1:])) |
336 return (op, _fixops(('list',) + x[1:])) |
|
337 elif op == 'subscript' and x[1][0] == 'relation': |
|
338 # x#y[z] ternary |
|
339 return _fixops(('relsubscript', x[1][1], x[1][2], x[2])) |
334 |
340 |
335 return (op,) + tuple(_fixops(y) for y in x[1:]) |
341 return (op,) + tuple(_fixops(y) for y in x[1:]) |
336 |
342 |
337 def _analyze(x, order): |
343 def _analyze(x, order): |
338 if x is None: |
344 if x is None: |
367 return (op, None, order) |
373 return (op, None, order) |
368 elif op in ('rangepre', 'rangepost', 'parentpost'): |
374 elif op in ('rangepre', 'rangepost', 'parentpost'): |
369 return (op, _analyze(x[1], defineorder), order) |
375 return (op, _analyze(x[1], defineorder), order) |
370 elif op == 'group': |
376 elif op == 'group': |
371 return _analyze(x[1], order) |
377 return _analyze(x[1], order) |
372 elif op in ('dagrange', 'range', 'parent', 'ancestor'): |
378 elif op in ('dagrange', 'range', 'parent', 'ancestor', 'relation', |
|
379 'subscript'): |
373 ta = _analyze(x[1], defineorder) |
380 ta = _analyze(x[1], defineorder) |
374 tb = _analyze(x[2], defineorder) |
381 tb = _analyze(x[2], defineorder) |
375 return (op, ta, tb, order) |
382 return (op, ta, tb, order) |
|
383 elif op == 'relsubscript': |
|
384 ta = _analyze(x[1], defineorder) |
|
385 tb = _analyze(x[2], defineorder) |
|
386 tc = _analyze(x[3], defineorder) |
|
387 return (op, ta, tb, tc, order) |
376 elif op == 'list': |
388 elif op == 'list': |
377 return (op,) + tuple(_analyze(y, order) for y in x[1:]) |
389 return (op,) + tuple(_analyze(y, order) for y in x[1:]) |
378 elif op == 'keyvalue': |
390 elif op == 'keyvalue': |
379 return (op, x[1], _analyze(x[2], order)) |
391 return (op, x[1], _analyze(x[2], order)) |
380 elif op == 'func': |
392 elif op == 'func': |
479 elif op in ('dagrange', 'range'): |
491 elif op in ('dagrange', 'range'): |
480 wa, ta = _optimize(x[1], small) |
492 wa, ta = _optimize(x[1], small) |
481 wb, tb = _optimize(x[2], small) |
493 wb, tb = _optimize(x[2], small) |
482 order = x[3] |
494 order = x[3] |
483 return wa + wb, (op, ta, tb, order) |
495 return wa + wb, (op, ta, tb, order) |
484 elif op in ('parent', 'ancestor'): |
496 elif op in ('parent', 'ancestor', 'relation', 'subscript'): |
485 w, t = _optimize(x[1], small) |
497 w, t = _optimize(x[1], small) |
486 order = x[3] |
498 order = x[3] |
487 return w, (op, t, x[2], order) |
499 return w, (op, t, x[2], order) |
|
500 elif op == 'relsubscript': |
|
501 w, t = _optimize(x[1], small) |
|
502 order = x[4] |
|
503 return w, (op, t, x[2], x[3], order) |
488 elif op == 'list': |
504 elif op == 'list': |
489 ws, ts = zip(*(_optimize(y, small) for y in x[1:])) |
505 ws, ts = zip(*(_optimize(y, small) for y in x[1:])) |
490 return sum(ws), (op,) + ts |
506 return sum(ws), (op,) + ts |
491 elif op == 'keyvalue': |
507 elif op == 'keyvalue': |
492 w, t = _optimize(x[2], small) |
508 w, t = _optimize(x[2], small) |