py-alpha-lib 0.1.0__cp311-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
alpha/lang/parser.py ADDED
@@ -0,0 +1,3572 @@
1
+ # The file was automatically generated by Lark v1.3.1
2
+ __version__ = "1.3.1"
3
+
4
+ #
5
+ #
6
+ # Lark Stand-alone Generator Tool
7
+ # ----------------------------------
8
+ # Generates a stand-alone LALR(1) parser
9
+ #
10
+ # Git: https://github.com/erezsh/lark
11
+ # Author: Erez Shinan (erezshin@gmail.com)
12
+ #
13
+ #
14
+ # >>> LICENSE
15
+ #
16
+ # This tool and its generated code use a separate license from Lark,
17
+ # and are subject to the terms of the Mozilla Public License, v. 2.0.
18
+ # If a copy of the MPL was not distributed with this
19
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
20
+ #
21
+ # If you wish to purchase a commercial license for this tool and its
22
+ # generated code, you may contact me via email or otherwise.
23
+ #
24
+ # If MPL2 is incompatible with your free or open-source project,
25
+ # contact me and we'll work it out.
26
+ #
27
+ #
28
+
29
+ from copy import deepcopy
30
+ from abc import ABC, abstractmethod
31
+ from types import ModuleType
32
+ from typing import (
33
+ TypeVar, Generic, Type, Tuple, List, Dict, Iterator, Collection, Callable, Optional, FrozenSet, Any,
34
+ Union, Iterable, IO, TYPE_CHECKING, overload, Sequence,
35
+ Pattern as REPattern, ClassVar, Set, Mapping
36
+ )
37
+
38
+
39
+ class LarkError(Exception):
40
+ pass
41
+
42
+
43
+ class ConfigurationError(LarkError, ValueError):
44
+ pass
45
+
46
+
47
+ def assert_config(value, options: Collection, msg='Got %r, expected one of %s'):
48
+ if value not in options:
49
+ raise ConfigurationError(msg % (value, options))
50
+
51
+
52
+ class GrammarError(LarkError):
53
+ pass
54
+
55
+
56
+ class ParseError(LarkError):
57
+ pass
58
+
59
+
60
+ class LexError(LarkError):
61
+ pass
62
+
63
+ T = TypeVar('T')
64
+
65
+ class UnexpectedInput(LarkError):
66
+ #--
67
+ line: int
68
+ column: int
69
+ pos_in_stream = None
70
+ state: Any
71
+ _terminals_by_name = None
72
+ interactive_parser: 'InteractiveParser'
73
+
74
+ def get_context(self, text: str, span: int=40) -> str:
75
+ #--
76
+ pos = self.pos_in_stream or 0
77
+ start = max(pos - span, 0)
78
+ end = pos + span
79
+ if not isinstance(text, bytes):
80
+ before = text[start:pos].rsplit('\n', 1)[-1]
81
+ after = text[pos:end].split('\n', 1)[0]
82
+ return before + after + '\n' + ' ' * len(before.expandtabs()) + '^\n'
83
+ else:
84
+ before = text[start:pos].rsplit(b'\n', 1)[-1]
85
+ after = text[pos:end].split(b'\n', 1)[0]
86
+ return (before + after + b'\n' + b' ' * len(before.expandtabs()) + b'^\n').decode("ascii", "backslashreplace")
87
+
88
+ def match_examples(self, parse_fn: 'Callable[[str], Tree]',
89
+ examples: Union[Mapping[T, Iterable[str]], Iterable[Tuple[T, Iterable[str]]]],
90
+ token_type_match_fallback: bool=False,
91
+ use_accepts: bool=True
92
+ ) -> Optional[T]:
93
+ #--
94
+ assert self.state is not None, "Not supported for this exception"
95
+
96
+ if isinstance(examples, Mapping):
97
+ examples = examples.items()
98
+
99
+ candidate = (None, False)
100
+ for i, (label, example) in enumerate(examples):
101
+ assert not isinstance(example, str), "Expecting a list"
102
+
103
+ for j, malformed in enumerate(example):
104
+ try:
105
+ parse_fn(malformed)
106
+ except UnexpectedInput as ut:
107
+ if ut.state == self.state:
108
+ if (
109
+ use_accepts
110
+ and isinstance(self, UnexpectedToken)
111
+ and isinstance(ut, UnexpectedToken)
112
+ and ut.accepts != self.accepts
113
+ ):
114
+ logger.debug("Different accepts with same state[%d]: %s != %s at example [%s][%s]" %
115
+ (self.state, self.accepts, ut.accepts, i, j))
116
+ continue
117
+ if (
118
+ isinstance(self, (UnexpectedToken, UnexpectedEOF))
119
+ and isinstance(ut, (UnexpectedToken, UnexpectedEOF))
120
+ ):
121
+ if ut.token == self.token: ##
122
+
123
+ logger.debug("Exact Match at example [%s][%s]" % (i, j))
124
+ return label
125
+
126
+ if token_type_match_fallback:
127
+ ##
128
+
129
+ if (ut.token.type == self.token.type) and not candidate[-1]:
130
+ logger.debug("Token Type Fallback at example [%s][%s]" % (i, j))
131
+ candidate = label, True
132
+
133
+ if candidate[0] is None:
134
+ logger.debug("Same State match at example [%s][%s]" % (i, j))
135
+ candidate = label, False
136
+
137
+ return candidate[0]
138
+
139
+ def _format_expected(self, expected):
140
+ if self._terminals_by_name:
141
+ d = self._terminals_by_name
142
+ expected = [d[t_name].user_repr() if t_name in d else t_name for t_name in expected]
143
+ return "Expected one of: \n\t* %s\n" % '\n\t* '.join(expected)
144
+
145
+
146
+ class UnexpectedEOF(ParseError, UnexpectedInput):
147
+ #--
148
+ expected: 'List[Token]'
149
+
150
+ def __init__(self, expected, state=None, terminals_by_name=None):
151
+ super(UnexpectedEOF, self).__init__()
152
+
153
+ self.expected = expected
154
+ self.state = state
155
+ from .lexer import Token
156
+ self.token = Token("<EOF>", "") ##
157
+
158
+ self.pos_in_stream = -1
159
+ self.line = -1
160
+ self.column = -1
161
+ self._terminals_by_name = terminals_by_name
162
+
163
+
164
+ def __str__(self):
165
+ message = "Unexpected end-of-input. "
166
+ message += self._format_expected(self.expected)
167
+ return message
168
+
169
+
170
+ class UnexpectedCharacters(LexError, UnexpectedInput):
171
+ #--
172
+
173
+ allowed: Set[str]
174
+ considered_tokens: Set[Any]
175
+
176
+ def __init__(self, seq, lex_pos, line, column, allowed=None, considered_tokens=None, state=None, token_history=None,
177
+ terminals_by_name=None, considered_rules=None):
178
+ super(UnexpectedCharacters, self).__init__()
179
+
180
+ ##
181
+
182
+ self.line = line
183
+ self.column = column
184
+ self.pos_in_stream = lex_pos
185
+ self.state = state
186
+ self._terminals_by_name = terminals_by_name
187
+
188
+ self.allowed = allowed
189
+ self.considered_tokens = considered_tokens
190
+ self.considered_rules = considered_rules
191
+ self.token_history = token_history
192
+
193
+ if isinstance(seq, bytes):
194
+ self.char = seq[lex_pos:lex_pos + 1].decode("ascii", "backslashreplace")
195
+ else:
196
+ self.char = seq[lex_pos]
197
+ self._context = self.get_context(seq)
198
+
199
+
200
+ def __str__(self):
201
+ message = "No terminal matches '%s' in the current parser context, at line %d col %d" % (self.char, self.line, self.column)
202
+ message += '\n\n' + self._context
203
+ if self.allowed:
204
+ message += self._format_expected(self.allowed)
205
+ if self.token_history:
206
+ message += '\nPrevious tokens: %s\n' % ', '.join(repr(t) for t in self.token_history)
207
+ return message
208
+
209
+
210
+ class UnexpectedToken(ParseError, UnexpectedInput):
211
+ #--
212
+
213
+ expected: Set[str]
214
+ considered_rules: Set[str]
215
+
216
+ def __init__(self, token, expected, considered_rules=None, state=None, interactive_parser=None, terminals_by_name=None, token_history=None):
217
+ super(UnexpectedToken, self).__init__()
218
+
219
+ ##
220
+
221
+ self.line = getattr(token, 'line', '?')
222
+ self.column = getattr(token, 'column', '?')
223
+ self.pos_in_stream = getattr(token, 'start_pos', None)
224
+ self.state = state
225
+
226
+ self.token = token
227
+ self.expected = expected ##
228
+
229
+ self._accepts = NO_VALUE
230
+ self.considered_rules = considered_rules
231
+ self.interactive_parser = interactive_parser
232
+ self._terminals_by_name = terminals_by_name
233
+ self.token_history = token_history
234
+
235
+
236
+ @property
237
+ def accepts(self) -> Set[str]:
238
+ if self._accepts is NO_VALUE:
239
+ self._accepts = self.interactive_parser and self.interactive_parser.accepts()
240
+ return self._accepts
241
+
242
+ def __str__(self):
243
+ message = ("Unexpected token %r at line %s, column %s.\n%s"
244
+ % (self.token, self.line, self.column, self._format_expected(self.accepts or self.expected)))
245
+ if self.token_history:
246
+ message += "Previous tokens: %r\n" % self.token_history
247
+
248
+ return message
249
+
250
+
251
+
252
+ class VisitError(LarkError):
253
+ #--
254
+
255
+ obj: 'Union[Tree, Token]'
256
+ orig_exc: Exception
257
+
258
+ def __init__(self, rule, obj, orig_exc):
259
+ message = 'Error trying to process rule "%s":\n\n%s' % (rule, orig_exc)
260
+ super(VisitError, self).__init__(message)
261
+
262
+ self.rule = rule
263
+ self.obj = obj
264
+ self.orig_exc = orig_exc
265
+
266
+
267
+ class MissingVariableError(LarkError):
268
+ pass
269
+
270
+
271
+ import sys, re
272
+ import logging
273
+ from dataclasses import dataclass
274
+ from typing import Generic, AnyStr
275
+
276
+ logger: logging.Logger = logging.getLogger("lark")
277
+ logger.addHandler(logging.StreamHandler())
278
+ ##
279
+
280
+ ##
281
+
282
+ logger.setLevel(logging.CRITICAL)
283
+
284
+
285
+ NO_VALUE = object()
286
+
287
+ T = TypeVar("T")
288
+
289
+
290
+ def classify(seq: Iterable, key: Optional[Callable] = None, value: Optional[Callable] = None) -> Dict:
291
+ d: Dict[Any, Any] = {}
292
+ for item in seq:
293
+ k = key(item) if (key is not None) else item
294
+ v = value(item) if (value is not None) else item
295
+ try:
296
+ d[k].append(v)
297
+ except KeyError:
298
+ d[k] = [v]
299
+ return d
300
+
301
+
302
+ def _deserialize(data: Any, namespace: Dict[str, Any], memo: Dict) -> Any:
303
+ if isinstance(data, dict):
304
+ if '__type__' in data: ##
305
+
306
+ class_ = namespace[data['__type__']]
307
+ return class_.deserialize(data, memo)
308
+ elif '@' in data:
309
+ return memo[data['@']]
310
+ return {key:_deserialize(value, namespace, memo) for key, value in data.items()}
311
+ elif isinstance(data, list):
312
+ return [_deserialize(value, namespace, memo) for value in data]
313
+ return data
314
+
315
+
316
+ _T = TypeVar("_T", bound="Serialize")
317
+
318
+ class Serialize:
319
+ #--
320
+
321
+ def memo_serialize(self, types_to_memoize: List) -> Any:
322
+ memo = SerializeMemoizer(types_to_memoize)
323
+ return self.serialize(memo), memo.serialize()
324
+
325
+ def serialize(self, memo = None) -> Dict[str, Any]:
326
+ if memo and memo.in_types(self):
327
+ return {'@': memo.memoized.get(self)}
328
+
329
+ fields = getattr(self, '__serialize_fields__')
330
+ res = {f: _serialize(getattr(self, f), memo) for f in fields}
331
+ res['__type__'] = type(self).__name__
332
+ if hasattr(self, '_serialize'):
333
+ self._serialize(res, memo)
334
+ return res
335
+
336
+ @classmethod
337
+ def deserialize(cls: Type[_T], data: Dict[str, Any], memo: Dict[int, Any]) -> _T:
338
+ namespace = getattr(cls, '__serialize_namespace__', [])
339
+ namespace = {c.__name__:c for c in namespace}
340
+
341
+ fields = getattr(cls, '__serialize_fields__')
342
+
343
+ if '@' in data:
344
+ return memo[data['@']]
345
+
346
+ inst = cls.__new__(cls)
347
+ for f in fields:
348
+ try:
349
+ setattr(inst, f, _deserialize(data[f], namespace, memo))
350
+ except KeyError as e:
351
+ raise KeyError("Cannot find key for class", cls, e)
352
+
353
+ if hasattr(inst, '_deserialize'):
354
+ inst._deserialize()
355
+
356
+ return inst
357
+
358
+
359
+ class SerializeMemoizer(Serialize):
360
+ #--
361
+
362
+ __serialize_fields__ = 'memoized',
363
+
364
+ def __init__(self, types_to_memoize: List) -> None:
365
+ self.types_to_memoize = tuple(types_to_memoize)
366
+ self.memoized = Enumerator()
367
+
368
+ def in_types(self, value: Serialize) -> bool:
369
+ return isinstance(value, self.types_to_memoize)
370
+
371
+ def serialize(self) -> Dict[int, Any]: ##
372
+
373
+ return _serialize(self.memoized.reversed(), None)
374
+
375
+ @classmethod
376
+ def deserialize(cls, data: Dict[int, Any], namespace: Dict[str, Any], memo: Dict[Any, Any]) -> Dict[int, Any]: ##
377
+
378
+ return _deserialize(data, namespace, memo)
379
+
380
+
381
+ try:
382
+ import regex
383
+ _has_regex = True
384
+ except ImportError:
385
+ _has_regex = False
386
+
387
+ if sys.version_info >= (3, 11):
388
+ import re._parser as sre_parse
389
+ import re._constants as sre_constants
390
+ else:
391
+ import sre_parse
392
+ import sre_constants
393
+
394
+ categ_pattern = re.compile(r'\\p{[A-Za-z_]+}')
395
+
396
+ def get_regexp_width(expr: str) -> Union[Tuple[int, int], List[int]]:
397
+ if _has_regex:
398
+ ##
399
+
400
+ ##
401
+
402
+ ##
403
+
404
+ regexp_final = re.sub(categ_pattern, 'A', expr)
405
+ else:
406
+ if re.search(categ_pattern, expr):
407
+ raise ImportError('`regex` module must be installed in order to use Unicode categories.', expr)
408
+ regexp_final = expr
409
+ try:
410
+ ##
411
+
412
+ return [int(x) for x in sre_parse.parse(regexp_final).getwidth()]
413
+ except sre_constants.error:
414
+ if not _has_regex:
415
+ raise ValueError(expr)
416
+ else:
417
+ ##
418
+
419
+ ##
420
+
421
+ c = regex.compile(regexp_final)
422
+ ##
423
+
424
+ ##
425
+
426
+ MAXWIDTH = getattr(sre_parse, "MAXWIDTH", sre_constants.MAXREPEAT)
427
+ if c.match('') is None:
428
+ ##
429
+
430
+ return 1, int(MAXWIDTH)
431
+ else:
432
+ return 0, int(MAXWIDTH)
433
+
434
+
435
+ @dataclass(frozen=True)
436
+ class TextSlice(Generic[AnyStr]):
437
+ #--
438
+ text: AnyStr
439
+ start: int
440
+ end: int
441
+
442
+ def __post_init__(self):
443
+ if not isinstance(self.text, (str, bytes)):
444
+ raise TypeError("text must be str or bytes")
445
+
446
+ if self.start < 0:
447
+ object.__setattr__(self, 'start', self.start + len(self.text))
448
+ assert self.start >=0
449
+
450
+ if self.end is None:
451
+ object.__setattr__(self, 'end', len(self.text))
452
+ elif self.end < 0:
453
+ object.__setattr__(self, 'end', self.end + len(self.text))
454
+ assert self.end <= len(self.text)
455
+
456
+ @classmethod
457
+ def cast_from(cls, text: 'TextOrSlice') -> 'TextSlice[AnyStr]':
458
+ if isinstance(text, TextSlice):
459
+ return text
460
+
461
+ return cls(text, 0, len(text))
462
+
463
+ def is_complete_text(self):
464
+ return self.start == 0 and self.end == len(self.text)
465
+
466
+ def __len__(self):
467
+ return self.end - self.start
468
+
469
+ def count(self, substr: AnyStr):
470
+ return self.text.count(substr, self.start, self.end)
471
+
472
+ def rindex(self, substr: AnyStr):
473
+ return self.text.rindex(substr, self.start, self.end)
474
+
475
+
476
+ TextOrSlice = Union[AnyStr, 'TextSlice[AnyStr]']
477
+ LarkInput = Union[AnyStr, TextSlice[AnyStr], Any]
478
+
479
+
480
+
481
+ class Meta:
482
+
483
+ empty: bool
484
+ line: int
485
+ column: int
486
+ start_pos: int
487
+ end_line: int
488
+ end_column: int
489
+ end_pos: int
490
+ orig_expansion: 'List[TerminalDef]'
491
+ match_tree: bool
492
+
493
+ def __init__(self):
494
+ self.empty = True
495
+
496
+
497
+ _Leaf_T = TypeVar("_Leaf_T")
498
+ Branch = Union[_Leaf_T, 'Tree[_Leaf_T]']
499
+
500
+
501
+ class Tree(Generic[_Leaf_T]):
502
+ #--
503
+
504
+ data: str
505
+ children: 'List[Branch[_Leaf_T]]'
506
+
507
+ def __init__(self, data: str, children: 'List[Branch[_Leaf_T]]', meta: Optional[Meta]=None) -> None:
508
+ self.data = data
509
+ self.children = children
510
+ self._meta = meta
511
+
512
+ @property
513
+ def meta(self) -> Meta:
514
+ if self._meta is None:
515
+ self._meta = Meta()
516
+ return self._meta
517
+
518
+ def __repr__(self):
519
+ return 'Tree(%r, %r)' % (self.data, self.children)
520
+
521
+ __match_args__ = ("data", "children")
522
+
523
+ def _pretty_label(self):
524
+ return self.data
525
+
526
+ def _pretty(self, level, indent_str):
527
+ yield f'{indent_str*level}{self._pretty_label()}'
528
+ if len(self.children) == 1 and not isinstance(self.children[0], Tree):
529
+ yield f'\t{self.children[0]}\n'
530
+ else:
531
+ yield '\n'
532
+ for n in self.children:
533
+ if isinstance(n, Tree):
534
+ yield from n._pretty(level+1, indent_str)
535
+ else:
536
+ yield f'{indent_str*(level+1)}{n}\n'
537
+
538
+ def pretty(self, indent_str: str=' ') -> str:
539
+ #--
540
+ return ''.join(self._pretty(0, indent_str))
541
+
542
+ def __rich__(self, parent:Optional['rich.tree.Tree']=None) -> 'rich.tree.Tree':
543
+ #--
544
+ return self._rich(parent)
545
+
546
+ def _rich(self, parent):
547
+ if parent:
548
+ tree = parent.add(f'[bold]{self.data}[/bold]')
549
+ else:
550
+ import rich.tree
551
+ tree = rich.tree.Tree(self.data)
552
+
553
+ for c in self.children:
554
+ if isinstance(c, Tree):
555
+ c._rich(tree)
556
+ else:
557
+ tree.add(f'[green]{c}[/green]')
558
+
559
+ return tree
560
+
561
+ def __eq__(self, other):
562
+ try:
563
+ return self.data == other.data and self.children == other.children
564
+ except AttributeError:
565
+ return False
566
+
567
+ def __ne__(self, other):
568
+ return not (self == other)
569
+
570
+ def __hash__(self) -> int:
571
+ return hash((self.data, tuple(self.children)))
572
+
573
+ def iter_subtrees(self) -> 'Iterator[Tree[_Leaf_T]]':
574
+ #--
575
+ queue = [self]
576
+ subtrees = dict()
577
+ for subtree in queue:
578
+ subtrees[id(subtree)] = subtree
579
+ queue += [c for c in reversed(subtree.children)
580
+ if isinstance(c, Tree) and id(c) not in subtrees]
581
+
582
+ del queue
583
+ return reversed(list(subtrees.values()))
584
+
585
+ def iter_subtrees_topdown(self):
586
+ #--
587
+ stack = [self]
588
+ stack_append = stack.append
589
+ stack_pop = stack.pop
590
+ while stack:
591
+ node = stack_pop()
592
+ if not isinstance(node, Tree):
593
+ continue
594
+ yield node
595
+ for child in reversed(node.children):
596
+ stack_append(child)
597
+
598
+ def find_pred(self, pred: 'Callable[[Tree[_Leaf_T]], bool]') -> 'Iterator[Tree[_Leaf_T]]':
599
+ #--
600
+ return filter(pred, self.iter_subtrees())
601
+
602
+ def find_data(self, data: str) -> 'Iterator[Tree[_Leaf_T]]':
603
+ #--
604
+ return self.find_pred(lambda t: t.data == data)
605
+
606
+
607
+ from functools import wraps, update_wrapper
608
+ from inspect import getmembers, getmro
609
+
610
+ _Return_T = TypeVar('_Return_T')
611
+ _Return_V = TypeVar('_Return_V')
612
+ _Leaf_T = TypeVar('_Leaf_T')
613
+ _Leaf_U = TypeVar('_Leaf_U')
614
+ _R = TypeVar('_R')
615
+ _FUNC = Callable[..., _Return_T]
616
+ _DECORATED = Union[_FUNC, type]
617
+
618
+ class _DiscardType:
619
+ #--
620
+
621
+ def __repr__(self):
622
+ return "lark.visitors.Discard"
623
+
624
+ Discard = _DiscardType()
625
+
626
+ ##
627
+
628
+
629
+ class _Decoratable:
630
+ #--
631
+
632
+ @classmethod
633
+ def _apply_v_args(cls, visit_wrapper):
634
+ mro = getmro(cls)
635
+ assert mro[0] is cls
636
+ libmembers = {name for _cls in mro[1:] for name, _ in getmembers(_cls)}
637
+ for name, value in getmembers(cls):
638
+
639
+ ##
640
+
641
+ if name.startswith('_') or (name in libmembers and name not in cls.__dict__):
642
+ continue
643
+ if not callable(value):
644
+ continue
645
+
646
+ ##
647
+
648
+ if isinstance(cls.__dict__[name], _VArgsWrapper):
649
+ continue
650
+
651
+ setattr(cls, name, _VArgsWrapper(cls.__dict__[name], visit_wrapper))
652
+ return cls
653
+
654
+ def __class_getitem__(cls, _):
655
+ return cls
656
+
657
+
658
+ class Transformer(_Decoratable, ABC, Generic[_Leaf_T, _Return_T]):
659
+ #--
660
+ __visit_tokens__ = True ##
661
+
662
+
663
+ def __init__(self, visit_tokens: bool=True) -> None:
664
+ self.__visit_tokens__ = visit_tokens
665
+
666
+ def _call_userfunc(self, tree, new_children=None):
667
+ ##
668
+
669
+ children = new_children if new_children is not None else tree.children
670
+ try:
671
+ f = getattr(self, tree.data)
672
+ except AttributeError:
673
+ return self.__default__(tree.data, children, tree.meta)
674
+ else:
675
+ try:
676
+ wrapper = getattr(f, 'visit_wrapper', None)
677
+ if wrapper is not None:
678
+ return f.visit_wrapper(f, tree.data, children, tree.meta)
679
+ else:
680
+ return f(children)
681
+ except GrammarError:
682
+ raise
683
+ except Exception as e:
684
+ raise VisitError(tree.data, tree, e)
685
+
686
+ def _call_userfunc_token(self, token):
687
+ try:
688
+ f = getattr(self, token.type)
689
+ except AttributeError:
690
+ return self.__default_token__(token)
691
+ else:
692
+ try:
693
+ return f(token)
694
+ except GrammarError:
695
+ raise
696
+ except Exception as e:
697
+ raise VisitError(token.type, token, e)
698
+
699
+ def _transform_children(self, children):
700
+ for c in children:
701
+ if isinstance(c, Tree):
702
+ res = self._transform_tree(c)
703
+ elif self.__visit_tokens__ and isinstance(c, Token):
704
+ res = self._call_userfunc_token(c)
705
+ else:
706
+ res = c
707
+
708
+ if res is not Discard:
709
+ yield res
710
+
711
+ def _transform_tree(self, tree):
712
+ children = list(self._transform_children(tree.children))
713
+ return self._call_userfunc(tree, children)
714
+
715
+ def transform(self, tree: Tree[_Leaf_T]) -> _Return_T:
716
+ #--
717
+ res = list(self._transform_children([tree]))
718
+ if not res:
719
+ return None ##
720
+
721
+ assert len(res) == 1
722
+ return res[0]
723
+
724
+ def __mul__(
725
+ self: 'Transformer[_Leaf_T, Tree[_Leaf_U]]',
726
+ other: 'Union[Transformer[_Leaf_U, _Return_V], TransformerChain[_Leaf_U, _Return_V,]]'
727
+ ) -> 'TransformerChain[_Leaf_T, _Return_V]':
728
+ #--
729
+ return TransformerChain(self, other)
730
+
731
+ def __default__(self, data, children, meta):
732
+ #--
733
+ return Tree(data, children, meta)
734
+
735
+ def __default_token__(self, token):
736
+ #--
737
+ return token
738
+
739
+
740
+ def merge_transformers(base_transformer=None, **transformers_to_merge):
741
+ #--
742
+ if base_transformer is None:
743
+ base_transformer = Transformer()
744
+ for prefix, transformer in transformers_to_merge.items():
745
+ for method_name in dir(transformer):
746
+ method = getattr(transformer, method_name)
747
+ if not callable(method):
748
+ continue
749
+ if method_name.startswith("_") or method_name == "transform":
750
+ continue
751
+ prefixed_method = prefix + "__" + method_name
752
+ if hasattr(base_transformer, prefixed_method):
753
+ raise AttributeError("Cannot merge: method '%s' appears more than once" % prefixed_method)
754
+
755
+ setattr(base_transformer, prefixed_method, method)
756
+
757
+ return base_transformer
758
+
759
+
760
+ class InlineTransformer(Transformer): ##
761
+
762
+ def _call_userfunc(self, tree, new_children=None):
763
+ ##
764
+
765
+ children = new_children if new_children is not None else tree.children
766
+ try:
767
+ f = getattr(self, tree.data)
768
+ except AttributeError:
769
+ return self.__default__(tree.data, children, tree.meta)
770
+ else:
771
+ return f(*children)
772
+
773
+
774
+ class TransformerChain(Generic[_Leaf_T, _Return_T]):
775
+
776
+ transformers: 'Tuple[Union[Transformer, TransformerChain], ...]'
777
+
778
+ def __init__(self, *transformers: 'Union[Transformer, TransformerChain]') -> None:
779
+ self.transformers = transformers
780
+
781
+ def transform(self, tree: Tree[_Leaf_T]) -> _Return_T:
782
+ for t in self.transformers:
783
+ tree = t.transform(tree)
784
+ return cast(_Return_T, tree)
785
+
786
+ def __mul__(
787
+ self: 'TransformerChain[_Leaf_T, Tree[_Leaf_U]]',
788
+ other: 'Union[Transformer[_Leaf_U, _Return_V], TransformerChain[_Leaf_U, _Return_V]]'
789
+ ) -> 'TransformerChain[_Leaf_T, _Return_V]':
790
+ return TransformerChain(*self.transformers + (other,))
791
+
792
+
793
+ class Transformer_InPlace(Transformer[_Leaf_T, _Return_T]):
794
+ #--
795
+ def _transform_tree(self, tree): ##
796
+
797
+ return self._call_userfunc(tree)
798
+
799
+ def transform(self, tree: Tree[_Leaf_T]) -> _Return_T:
800
+ for subtree in tree.iter_subtrees():
801
+ subtree.children = list(self._transform_children(subtree.children))
802
+
803
+ return self._transform_tree(tree)
804
+
805
+
806
+ class Transformer_NonRecursive(Transformer[_Leaf_T, _Return_T]):
807
+ #--
808
+
809
+ def transform(self, tree: Tree[_Leaf_T]) -> _Return_T:
810
+ ##
811
+
812
+ rev_postfix = []
813
+ q: List[Branch[_Leaf_T]] = [tree]
814
+ while q:
815
+ t = q.pop()
816
+ rev_postfix.append(t)
817
+ if isinstance(t, Tree):
818
+ q += t.children
819
+
820
+ ##
821
+
822
+ stack: List = []
823
+ for x in reversed(rev_postfix):
824
+ if isinstance(x, Tree):
825
+ size = len(x.children)
826
+ if size:
827
+ args = stack[-size:]
828
+ del stack[-size:]
829
+ else:
830
+ args = []
831
+
832
+ res = self._call_userfunc(x, args)
833
+ if res is not Discard:
834
+ stack.append(res)
835
+
836
+ elif self.__visit_tokens__ and isinstance(x, Token):
837
+ res = self._call_userfunc_token(x)
838
+ if res is not Discard:
839
+ stack.append(res)
840
+ else:
841
+ stack.append(x)
842
+
843
+ result, = stack ##
844
+
845
+ ##
846
+
847
+ ##
848
+
849
+ ##
850
+
851
+ return cast(_Return_T, result)
852
+
853
+
854
+ class Transformer_InPlaceRecursive(Transformer[_Leaf_T, _Return_T]):
855
+ #--
856
+ def _transform_tree(self, tree):
857
+ tree.children = list(self._transform_children(tree.children))
858
+ return self._call_userfunc(tree)
859
+
860
+
861
+ ##
862
+
863
+
864
+ class VisitorBase:
865
+ def _call_userfunc(self, tree):
866
+ return getattr(self, tree.data, self.__default__)(tree)
867
+
868
+ def __default__(self, tree):
869
+ #--
870
+ return tree
871
+
872
+ def __class_getitem__(cls, _):
873
+ return cls
874
+
875
+
876
+ class Visitor(VisitorBase, ABC, Generic[_Leaf_T]):
877
+ #--
878
+
879
+ def visit(self, tree: Tree[_Leaf_T]) -> Tree[_Leaf_T]:
880
+ #--
881
+ for subtree in tree.iter_subtrees():
882
+ self._call_userfunc(subtree)
883
+ return tree
884
+
885
+ def visit_topdown(self, tree: Tree[_Leaf_T]) -> Tree[_Leaf_T]:
886
+ #--
887
+ for subtree in tree.iter_subtrees_topdown():
888
+ self._call_userfunc(subtree)
889
+ return tree
890
+
891
+
892
+ class Visitor_Recursive(VisitorBase, Generic[_Leaf_T]):
893
+ #--
894
+
895
+ def visit(self, tree: Tree[_Leaf_T]) -> Tree[_Leaf_T]:
896
+ #--
897
+ for child in tree.children:
898
+ if isinstance(child, Tree):
899
+ self.visit(child)
900
+
901
+ self._call_userfunc(tree)
902
+ return tree
903
+
904
+ def visit_topdown(self,tree: Tree[_Leaf_T]) -> Tree[_Leaf_T]:
905
+ #--
906
+ self._call_userfunc(tree)
907
+
908
+ for child in tree.children:
909
+ if isinstance(child, Tree):
910
+ self.visit_topdown(child)
911
+
912
+ return tree
913
+
914
+
915
+ class Interpreter(_Decoratable, ABC, Generic[_Leaf_T, _Return_T]):
916
+ #--
917
+
918
+ def visit(self, tree: Tree[_Leaf_T]) -> _Return_T:
919
+ ##
920
+
921
+ ##
922
+
923
+ ##
924
+
925
+ return self._visit_tree(tree)
926
+
927
+ def _visit_tree(self, tree: Tree[_Leaf_T]):
928
+ f = getattr(self, tree.data)
929
+ wrapper = getattr(f, 'visit_wrapper', None)
930
+ if wrapper is not None:
931
+ return f.visit_wrapper(f, tree.data, tree.children, tree.meta)
932
+ else:
933
+ return f(tree)
934
+
935
+ def visit_children(self, tree: Tree[_Leaf_T]) -> List:
936
+ return [self._visit_tree(child) if isinstance(child, Tree) else child
937
+ for child in tree.children]
938
+
939
+ def __getattr__(self, name):
940
+ return self.__default__
941
+
942
+ def __default__(self, tree):
943
+ return self.visit_children(tree)
944
+
945
+
946
+ _InterMethod = Callable[[Type[Interpreter], _Return_T], _R]
947
+
948
+ def visit_children_decor(func: _InterMethod) -> _InterMethod:
949
+ #--
950
+ @wraps(func)
951
+ def inner(cls, tree):
952
+ values = cls.visit_children(tree)
953
+ return func(cls, values)
954
+ return inner
955
+
956
+ ##
957
+
958
+
959
+ def _apply_v_args(obj, visit_wrapper):
960
+ try:
961
+ _apply = obj._apply_v_args
962
+ except AttributeError:
963
+ return _VArgsWrapper(obj, visit_wrapper)
964
+ else:
965
+ return _apply(visit_wrapper)
966
+
967
+
968
+ class _VArgsWrapper:
969
+ #--
970
+ base_func: Callable
971
+
972
+ def __init__(self, func: Callable, visit_wrapper: Callable[[Callable, str, list, Any], Any]):
973
+ if isinstance(func, _VArgsWrapper):
974
+ func = func.base_func
975
+ self.base_func = func
976
+ self.visit_wrapper = visit_wrapper
977
+ update_wrapper(self, func)
978
+
979
+ def __call__(self, *args, **kwargs):
980
+ return self.base_func(*args, **kwargs)
981
+
982
+ def __get__(self, instance, owner=None):
983
+ try:
984
+ ##
985
+
986
+ ##
987
+
988
+ g = type(self.base_func).__get__
989
+ except AttributeError:
990
+ return self
991
+ else:
992
+ return _VArgsWrapper(g(self.base_func, instance, owner), self.visit_wrapper)
993
+
994
+ def __set_name__(self, owner, name):
995
+ try:
996
+ f = type(self.base_func).__set_name__
997
+ except AttributeError:
998
+ return
999
+ else:
1000
+ f(self.base_func, owner, name)
1001
+
1002
+
1003
+ def _vargs_inline(f, _data, children, _meta):
1004
+ return f(*children)
1005
+ def _vargs_meta_inline(f, _data, children, meta):
1006
+ return f(meta, *children)
1007
+ def _vargs_meta(f, _data, children, meta):
1008
+ return f(meta, children)
1009
+ def _vargs_tree(f, data, children, meta):
1010
+ return f(Tree(data, children, meta))
1011
+
1012
+
1013
+ def v_args(inline: bool = False, meta: bool = False, tree: bool = False, wrapper: Optional[Callable] = None) -> Callable[[_DECORATED], _DECORATED]:
1014
+ #--
1015
+ if tree and (meta or inline):
1016
+ raise ValueError("Visitor functions cannot combine 'tree' with 'meta' or 'inline'.")
1017
+
1018
+ func = None
1019
+ if meta:
1020
+ if inline:
1021
+ func = _vargs_meta_inline
1022
+ else:
1023
+ func = _vargs_meta
1024
+ elif inline:
1025
+ func = _vargs_inline
1026
+ elif tree:
1027
+ func = _vargs_tree
1028
+
1029
+ if wrapper is not None:
1030
+ if func is not None:
1031
+ raise ValueError("Cannot use 'wrapper' along with 'tree', 'meta' or 'inline'.")
1032
+ func = wrapper
1033
+
1034
+ def _visitor_args_dec(obj):
1035
+ return _apply_v_args(obj, func)
1036
+ return _visitor_args_dec
1037
+
1038
+
1039
+
1040
+ TOKEN_DEFAULT_PRIORITY = 0
1041
+
1042
+
1043
+ class Symbol(Serialize):
1044
+ __slots__ = ('name',)
1045
+
1046
+ name: str
1047
+ is_term: ClassVar[bool] = NotImplemented
1048
+
1049
+ def __init__(self, name: str) -> None:
1050
+ self.name = name
1051
+
1052
+ def __eq__(self, other):
1053
+ if not isinstance(other, Symbol):
1054
+ return NotImplemented
1055
+ return self.is_term == other.is_term and self.name == other.name
1056
+
1057
+ def __ne__(self, other):
1058
+ return not (self == other)
1059
+
1060
+ def __hash__(self):
1061
+ return hash(self.name)
1062
+
1063
+ def __repr__(self):
1064
+ return '%s(%r)' % (type(self).__name__, self.name)
1065
+
1066
+ fullrepr = property(__repr__)
1067
+
1068
+ def renamed(self, f):
1069
+ return type(self)(f(self.name))
1070
+
1071
+
1072
+ class Terminal(Symbol):
1073
+ __serialize_fields__ = 'name', 'filter_out'
1074
+
1075
+ is_term: ClassVar[bool] = True
1076
+
1077
+ def __init__(self, name: str, filter_out: bool = False) -> None:
1078
+ self.name = name
1079
+ self.filter_out = filter_out
1080
+
1081
+ @property
1082
+ def fullrepr(self):
1083
+ return '%s(%r, %r)' % (type(self).__name__, self.name, self.filter_out)
1084
+
1085
+ def renamed(self, f):
1086
+ return type(self)(f(self.name), self.filter_out)
1087
+
1088
+
1089
+ class NonTerminal(Symbol):
1090
+ __serialize_fields__ = 'name',
1091
+
1092
+ is_term: ClassVar[bool] = False
1093
+
1094
+ def serialize(self, memo=None) -> Dict[str, Any]:
1095
+ ##
1096
+
1097
+ ##
1098
+
1099
+ return {'name': str(self.name), '__type__': 'NonTerminal'}
1100
+
1101
+
1102
+ class RuleOptions(Serialize):
1103
+ __serialize_fields__ = 'keep_all_tokens', 'expand1', 'priority', 'template_source', 'empty_indices'
1104
+
1105
+ keep_all_tokens: bool
1106
+ expand1: bool
1107
+ priority: Optional[int]
1108
+ template_source: Optional[str]
1109
+ empty_indices: Tuple[bool, ...]
1110
+
1111
+ def __init__(self, keep_all_tokens: bool=False, expand1: bool=False, priority: Optional[int]=None, template_source: Optional[str]=None, empty_indices: Tuple[bool, ...]=()) -> None:
1112
+ self.keep_all_tokens = keep_all_tokens
1113
+ self.expand1 = expand1
1114
+ self.priority = priority
1115
+ self.template_source = template_source
1116
+ self.empty_indices = empty_indices
1117
+
1118
+ def __repr__(self):
1119
+ return 'RuleOptions(%r, %r, %r, %r)' % (
1120
+ self.keep_all_tokens,
1121
+ self.expand1,
1122
+ self.priority,
1123
+ self.template_source
1124
+ )
1125
+
1126
+
1127
+ class Rule(Serialize):
1128
+ #--
1129
+ __slots__ = ('origin', 'expansion', 'alias', 'options', 'order', '_hash')
1130
+
1131
+ __serialize_fields__ = 'origin', 'expansion', 'order', 'alias', 'options'
1132
+ __serialize_namespace__ = Terminal, NonTerminal, RuleOptions
1133
+
1134
+ origin: NonTerminal
1135
+ expansion: Sequence[Symbol]
1136
+ order: int
1137
+ alias: Optional[str]
1138
+ options: RuleOptions
1139
+ _hash: int
1140
+
1141
+ def __init__(self, origin: NonTerminal, expansion: Sequence[Symbol],
1142
+ order: int=0, alias: Optional[str]=None, options: Optional[RuleOptions]=None):
1143
+ self.origin = origin
1144
+ self.expansion = expansion
1145
+ self.alias = alias
1146
+ self.order = order
1147
+ self.options = options or RuleOptions()
1148
+ self._hash = hash((self.origin, tuple(self.expansion)))
1149
+
1150
+ def _deserialize(self):
1151
+ self._hash = hash((self.origin, tuple(self.expansion)))
1152
+
1153
+ def __str__(self):
1154
+ return '<%s : %s>' % (self.origin.name, ' '.join(x.name for x in self.expansion))
1155
+
1156
+ def __repr__(self):
1157
+ return 'Rule(%r, %r, %r, %r)' % (self.origin, self.expansion, self.alias, self.options)
1158
+
1159
+ def __hash__(self):
1160
+ return self._hash
1161
+
1162
+ def __eq__(self, other):
1163
+ if not isinstance(other, Rule):
1164
+ return False
1165
+ return self.origin == other.origin and self.expansion == other.expansion
1166
+
1167
+
1168
+
1169
+ from contextlib import suppress
1170
+ from copy import copy
1171
+
1172
+ try: ##
1173
+
1174
+ has_interegular = bool(interegular)
1175
+ except NameError:
1176
+ has_interegular = False
1177
+
1178
+ class Pattern(Serialize, ABC):
1179
+ #--
1180
+
1181
+ value: str
1182
+ flags: Collection[str]
1183
+ raw: Optional[str]
1184
+ type: ClassVar[str]
1185
+
1186
+ def __init__(self, value: str, flags: Collection[str] = (), raw: Optional[str] = None) -> None:
1187
+ self.value = value
1188
+ self.flags = frozenset(flags)
1189
+ self.raw = raw
1190
+
1191
+ def __repr__(self):
1192
+ return repr(self.to_regexp())
1193
+
1194
+ ##
1195
+
1196
+ def __hash__(self):
1197
+ return hash((type(self), self.value, self.flags))
1198
+
1199
+ def __eq__(self, other):
1200
+ return type(self) == type(other) and self.value == other.value and self.flags == other.flags
1201
+
1202
+ @abstractmethod
1203
+ def to_regexp(self) -> str:
1204
+ raise NotImplementedError()
1205
+
1206
+ @property
1207
+ @abstractmethod
1208
+ def min_width(self) -> int:
1209
+ raise NotImplementedError()
1210
+
1211
+ @property
1212
+ @abstractmethod
1213
+ def max_width(self) -> int:
1214
+ raise NotImplementedError()
1215
+
1216
+ def _get_flags(self, value):
1217
+ for f in self.flags:
1218
+ value = ('(?%s:%s)' % (f, value))
1219
+ return value
1220
+
1221
+
1222
+ class PatternStr(Pattern):
1223
+ __serialize_fields__ = 'value', 'flags', 'raw'
1224
+
1225
+ type: ClassVar[str] = "str"
1226
+
1227
+ def to_regexp(self) -> str:
1228
+ return self._get_flags(re.escape(self.value))
1229
+
1230
+ @property
1231
+ def min_width(self) -> int:
1232
+ return len(self.value)
1233
+
1234
+ @property
1235
+ def max_width(self) -> int:
1236
+ return len(self.value)
1237
+
1238
+
1239
+ class PatternRE(Pattern):
1240
+ __serialize_fields__ = 'value', 'flags', 'raw', '_width'
1241
+
1242
+ type: ClassVar[str] = "re"
1243
+
1244
+ def to_regexp(self) -> str:
1245
+ return self._get_flags(self.value)
1246
+
1247
+ _width = None
1248
+ def _get_width(self):
1249
+ if self._width is None:
1250
+ self._width = get_regexp_width(self.to_regexp())
1251
+ return self._width
1252
+
1253
+ @property
1254
+ def min_width(self) -> int:
1255
+ return self._get_width()[0]
1256
+
1257
+ @property
1258
+ def max_width(self) -> int:
1259
+ return self._get_width()[1]
1260
+
1261
+
1262
+ class TerminalDef(Serialize):
1263
+ #--
1264
+ __serialize_fields__ = 'name', 'pattern', 'priority'
1265
+ __serialize_namespace__ = PatternStr, PatternRE
1266
+
1267
+ name: str
1268
+ pattern: Pattern
1269
+ priority: int
1270
+
1271
+ def __init__(self, name: str, pattern: Pattern, priority: int = TOKEN_DEFAULT_PRIORITY) -> None:
1272
+ assert isinstance(pattern, Pattern), pattern
1273
+ self.name = name
1274
+ self.pattern = pattern
1275
+ self.priority = priority
1276
+
1277
+ def __repr__(self):
1278
+ return '%s(%r, %r)' % (type(self).__name__, self.name, self.pattern)
1279
+
1280
+ def user_repr(self) -> str:
1281
+ if self.name.startswith('__'): ##
1282
+
1283
+ return self.pattern.raw or self.name
1284
+ else:
1285
+ return self.name
1286
+
1287
+ _T = TypeVar('_T', bound="Token")
1288
+
1289
+ class Token(str):
1290
+ #--
1291
+ __slots__ = ('type', 'start_pos', 'value', 'line', 'column', 'end_line', 'end_column', 'end_pos')
1292
+
1293
+ __match_args__ = ('type', 'value')
1294
+
1295
+ type: str
1296
+ start_pos: Optional[int]
1297
+ value: Any
1298
+ line: Optional[int]
1299
+ column: Optional[int]
1300
+ end_line: Optional[int]
1301
+ end_column: Optional[int]
1302
+ end_pos: Optional[int]
1303
+
1304
+
1305
+ @overload
1306
+ def __new__(
1307
+ cls,
1308
+ type: str,
1309
+ value: Any,
1310
+ start_pos: Optional[int] = None,
1311
+ line: Optional[int] = None,
1312
+ column: Optional[int] = None,
1313
+ end_line: Optional[int] = None,
1314
+ end_column: Optional[int] = None,
1315
+ end_pos: Optional[int] = None
1316
+ ) -> 'Token':
1317
+ ...
1318
+
1319
+ @overload
1320
+ def __new__(
1321
+ cls,
1322
+ type_: str,
1323
+ value: Any,
1324
+ start_pos: Optional[int] = None,
1325
+ line: Optional[int] = None,
1326
+ column: Optional[int] = None,
1327
+ end_line: Optional[int] = None,
1328
+ end_column: Optional[int] = None,
1329
+ end_pos: Optional[int] = None
1330
+ ) -> 'Token': ...
1331
+
1332
+ def __new__(cls, *args, **kwargs):
1333
+ if "type_" in kwargs:
1334
+ warnings.warn("`type_` is deprecated use `type` instead", DeprecationWarning)
1335
+
1336
+ if "type" in kwargs:
1337
+ raise TypeError("Error: using both 'type' and the deprecated 'type_' as arguments.")
1338
+ kwargs["type"] = kwargs.pop("type_")
1339
+
1340
+ return cls._future_new(*args, **kwargs)
1341
+
1342
+
1343
+ @classmethod
1344
+ def _future_new(cls, type, value, start_pos=None, line=None, column=None, end_line=None, end_column=None, end_pos=None):
1345
+ inst = super(Token, cls).__new__(cls, value)
1346
+
1347
+ inst.type = type
1348
+ inst.start_pos = start_pos
1349
+ inst.value = value
1350
+ inst.line = line
1351
+ inst.column = column
1352
+ inst.end_line = end_line
1353
+ inst.end_column = end_column
1354
+ inst.end_pos = end_pos
1355
+ return inst
1356
+
1357
+ @overload
1358
+ def update(self, type: Optional[str] = None, value: Optional[Any] = None) -> 'Token':
1359
+ ...
1360
+
1361
+ @overload
1362
+ def update(self, type_: Optional[str] = None, value: Optional[Any] = None) -> 'Token':
1363
+ ...
1364
+
1365
+ def update(self, *args, **kwargs):
1366
+ if "type_" in kwargs:
1367
+ warnings.warn("`type_` is deprecated use `type` instead", DeprecationWarning)
1368
+
1369
+ if "type" in kwargs:
1370
+ raise TypeError("Error: using both 'type' and the deprecated 'type_' as arguments.")
1371
+ kwargs["type"] = kwargs.pop("type_")
1372
+
1373
+ return self._future_update(*args, **kwargs)
1374
+
1375
+ def _future_update(self, type: Optional[str] = None, value: Optional[Any] = None) -> 'Token':
1376
+ return Token.new_borrow_pos(
1377
+ type if type is not None else self.type,
1378
+ value if value is not None else self.value,
1379
+ self
1380
+ )
1381
+
1382
+ @classmethod
1383
+ def new_borrow_pos(cls: Type[_T], type_: str, value: Any, borrow_t: 'Token') -> _T:
1384
+ return cls(type_, value, borrow_t.start_pos, borrow_t.line, borrow_t.column, borrow_t.end_line, borrow_t.end_column, borrow_t.end_pos)
1385
+
1386
+ def __reduce__(self):
1387
+ return (self.__class__, (self.type, self.value, self.start_pos, self.line, self.column))
1388
+
1389
+ def __repr__(self):
1390
+ return 'Token(%r, %r)' % (self.type, self.value)
1391
+
1392
+ def __deepcopy__(self, memo):
1393
+ return Token(self.type, self.value, self.start_pos, self.line, self.column)
1394
+
1395
+ def __eq__(self, other):
1396
+ if isinstance(other, Token) and self.type != other.type:
1397
+ return False
1398
+
1399
+ return str.__eq__(self, other)
1400
+
1401
+ __hash__ = str.__hash__
1402
+
1403
+
1404
+ class LineCounter:
1405
+ #--
1406
+
1407
+ __slots__ = 'char_pos', 'line', 'column', 'line_start_pos', 'newline_char'
1408
+
1409
+ def __init__(self, newline_char):
1410
+ self.newline_char = newline_char
1411
+ self.char_pos = 0
1412
+ self.line = 1
1413
+ self.column = 1
1414
+ self.line_start_pos = 0
1415
+
1416
+ def __eq__(self, other):
1417
+ if not isinstance(other, LineCounter):
1418
+ return NotImplemented
1419
+
1420
+ return self.char_pos == other.char_pos and self.newline_char == other.newline_char
1421
+
1422
+ def feed(self, token: TextOrSlice, test_newline=True):
1423
+ #--
1424
+ if test_newline:
1425
+ newlines = token.count(self.newline_char)
1426
+ if newlines:
1427
+ self.line += newlines
1428
+ self.line_start_pos = self.char_pos + token.rindex(self.newline_char) + 1
1429
+
1430
+ self.char_pos += len(token)
1431
+ self.column = self.char_pos - self.line_start_pos + 1
1432
+
1433
+
1434
+ class UnlessCallback:
1435
+ def __init__(self, scanner: 'Scanner'):
1436
+ self.scanner = scanner
1437
+
1438
+ def __call__(self, t: Token):
1439
+ res = self.scanner.fullmatch(t.value)
1440
+ if res is not None:
1441
+ t.type = res
1442
+ return t
1443
+
1444
+
1445
+ class CallChain:
1446
+ def __init__(self, callback1, callback2, cond):
1447
+ self.callback1 = callback1
1448
+ self.callback2 = callback2
1449
+ self.cond = cond
1450
+
1451
+ def __call__(self, t):
1452
+ t2 = self.callback1(t)
1453
+ return self.callback2(t) if self.cond(t2) else t2
1454
+
1455
+
1456
+ def _get_match(re_, regexp, s, flags):
1457
+ m = re_.match(regexp, s, flags)
1458
+ if m:
1459
+ return m.group(0)
1460
+
1461
+ def _create_unless(terminals, g_regex_flags, re_, use_bytes):
1462
+ tokens_by_type = classify(terminals, lambda t: type(t.pattern))
1463
+ assert len(tokens_by_type) <= 2, tokens_by_type.keys()
1464
+ embedded_strs = set()
1465
+ callback = {}
1466
+ for retok in tokens_by_type.get(PatternRE, []):
1467
+ unless = []
1468
+ for strtok in tokens_by_type.get(PatternStr, []):
1469
+ if strtok.priority != retok.priority:
1470
+ continue
1471
+ s = strtok.pattern.value
1472
+ if s == _get_match(re_, retok.pattern.to_regexp(), s, g_regex_flags):
1473
+ unless.append(strtok)
1474
+ if strtok.pattern.flags <= retok.pattern.flags:
1475
+ embedded_strs.add(strtok)
1476
+ if unless:
1477
+ callback[retok.name] = UnlessCallback(Scanner(unless, g_regex_flags, re_, use_bytes=use_bytes))
1478
+
1479
+ new_terminals = [t for t in terminals if t not in embedded_strs]
1480
+ return new_terminals, callback
1481
+
1482
+
1483
+ class Scanner:
1484
+ def __init__(self, terminals, g_regex_flags, re_, use_bytes):
1485
+ self.terminals = terminals
1486
+ self.g_regex_flags = g_regex_flags
1487
+ self.re_ = re_
1488
+ self.use_bytes = use_bytes
1489
+
1490
+ self.allowed_types = {t.name for t in self.terminals}
1491
+
1492
+ self._mres = self._build_mres(terminals, len(terminals))
1493
+
1494
+ def _build_mres(self, terminals, max_size):
1495
+ ##
1496
+
1497
+ ##
1498
+
1499
+ ##
1500
+
1501
+ mres = []
1502
+ while terminals:
1503
+ pattern = u'|'.join(u'(?P<%s>%s)' % (t.name, t.pattern.to_regexp()) for t in terminals[:max_size])
1504
+ if self.use_bytes:
1505
+ pattern = pattern.encode('latin-1')
1506
+ try:
1507
+ mre = self.re_.compile(pattern, self.g_regex_flags)
1508
+ except AssertionError: ##
1509
+
1510
+ return self._build_mres(terminals, max_size // 2)
1511
+
1512
+ mres.append(mre)
1513
+ terminals = terminals[max_size:]
1514
+ return mres
1515
+
1516
+ def match(self, text: TextSlice, pos):
1517
+ for mre in self._mres:
1518
+ m = mre.match(text.text, pos, text.end)
1519
+ if m:
1520
+ return m.group(0), m.lastgroup
1521
+
1522
+
1523
+ def fullmatch(self, text: str) -> Optional[str]:
1524
+ for mre in self._mres:
1525
+ m = mre.fullmatch(text)
1526
+ if m:
1527
+ return m.lastgroup
1528
+ return None
1529
+
1530
+ def _regexp_has_newline(r: str):
1531
+ #--
1532
+ return '\n' in r or '\\n' in r or '\\s' in r or '[^' in r or ('(?s' in r and '.' in r)
1533
+
1534
+
1535
+ class LexerState:
1536
+ #--
1537
+
1538
+ __slots__ = 'text', 'line_ctr', 'last_token'
1539
+
1540
+ text: TextSlice
1541
+ line_ctr: LineCounter
1542
+ last_token: Optional[Token]
1543
+
1544
+ def __init__(self, text: TextSlice, line_ctr: Optional[LineCounter] = None, last_token: Optional[Token]=None):
1545
+ if isinstance(text, TextSlice):
1546
+ if line_ctr is None:
1547
+ line_ctr = LineCounter(b'\n' if isinstance(text.text, bytes) else '\n')
1548
+
1549
+ if text.start > 0:
1550
+ ##
1551
+
1552
+ line_ctr.feed(TextSlice(text.text, 0, text.start))
1553
+
1554
+ if not (text.start <= line_ctr.char_pos <= text.end):
1555
+ raise ValueError("LineCounter.char_pos is out of bounds")
1556
+
1557
+ self.text = text
1558
+ self.line_ctr = line_ctr
1559
+ self.last_token = last_token
1560
+
1561
+
1562
+ def __eq__(self, other):
1563
+ if not isinstance(other, LexerState):
1564
+ return NotImplemented
1565
+
1566
+ return self.text == other.text and self.line_ctr == other.line_ctr and self.last_token == other.last_token
1567
+
1568
+ def __copy__(self):
1569
+ return type(self)(self.text, copy(self.line_ctr), self.last_token)
1570
+
1571
+
1572
+ class LexerThread:
1573
+ #--
1574
+
1575
+ def __init__(self, lexer: 'Lexer', lexer_state: Optional[LexerState]):
1576
+ self.lexer = lexer
1577
+ self.state = lexer_state
1578
+
1579
+ @classmethod
1580
+ def from_text(cls, lexer: 'Lexer', text_or_slice: TextOrSlice) -> 'LexerThread':
1581
+ text = TextSlice.cast_from(text_or_slice)
1582
+ return cls(lexer, LexerState(text))
1583
+
1584
+ @classmethod
1585
+ def from_custom_input(cls, lexer: 'Lexer', text: Any) -> 'LexerThread':
1586
+ return cls(lexer, LexerState(text))
1587
+
1588
+ def lex(self, parser_state):
1589
+ if self.state is None:
1590
+ raise TypeError("Cannot lex: No text assigned to lexer state")
1591
+ return self.lexer.lex(self.state, parser_state)
1592
+
1593
+ def __copy__(self):
1594
+ return type(self)(self.lexer, copy(self.state))
1595
+
1596
+ _Token = Token
1597
+
1598
+
1599
+ _Callback = Callable[[Token], Token]
1600
+
1601
+ class Lexer(ABC):
1602
+ #--
1603
+ @abstractmethod
1604
+ def lex(self, lexer_state: LexerState, parser_state: Any) -> Iterator[Token]:
1605
+ return NotImplemented
1606
+
1607
+ def make_lexer_state(self, text: str):
1608
+ #--
1609
+ return LexerState(TextSlice.cast_from(text))
1610
+
1611
+
1612
+ def _check_regex_collisions(terminal_to_regexp: Dict[TerminalDef, str], comparator, strict_mode, max_collisions_to_show=8):
1613
+ if not comparator:
1614
+ comparator = interegular.Comparator.from_regexes(terminal_to_regexp)
1615
+
1616
+ ##
1617
+
1618
+ ##
1619
+
1620
+ max_time = 2 if strict_mode else 0.2
1621
+
1622
+ ##
1623
+
1624
+ if comparator.count_marked_pairs() >= max_collisions_to_show:
1625
+ return
1626
+ for group in classify(terminal_to_regexp, lambda t: t.priority).values():
1627
+ for a, b in comparator.check(group, skip_marked=True):
1628
+ assert a.priority == b.priority
1629
+ ##
1630
+
1631
+ comparator.mark(a, b)
1632
+
1633
+ ##
1634
+
1635
+ message = f"Collision between Terminals {a.name} and {b.name}. "
1636
+ try:
1637
+ example = comparator.get_example_overlap(a, b, max_time).format_multiline()
1638
+ except ValueError:
1639
+ ##
1640
+
1641
+ example = "No example could be found fast enough. However, the collision does still exists"
1642
+ if strict_mode:
1643
+ raise LexError(f"{message}\n{example}")
1644
+ logger.warning("%s The lexer will choose between them arbitrarily.\n%s", message, example)
1645
+ if comparator.count_marked_pairs() >= max_collisions_to_show:
1646
+ logger.warning("Found 8 regex collisions, will not check for more.")
1647
+ return
1648
+
1649
+
1650
+ class AbstractBasicLexer(Lexer):
1651
+ terminals_by_name: Dict[str, TerminalDef]
1652
+
1653
+ @abstractmethod
1654
+ def __init__(self, conf: 'LexerConf', comparator=None) -> None:
1655
+ ...
1656
+
1657
+ @abstractmethod
1658
+ def next_token(self, lex_state: LexerState, parser_state: Any = None) -> Token:
1659
+ ...
1660
+
1661
+ def lex(self, state: LexerState, parser_state: Any) -> Iterator[Token]:
1662
+ with suppress(EOFError):
1663
+ while True:
1664
+ yield self.next_token(state, parser_state)
1665
+
1666
+
1667
+ class BasicLexer(AbstractBasicLexer):
1668
+ terminals: Collection[TerminalDef]
1669
+ ignore_types: FrozenSet[str]
1670
+ newline_types: FrozenSet[str]
1671
+ user_callbacks: Dict[str, _Callback]
1672
+ callback: Dict[str, _Callback]
1673
+ re: ModuleType
1674
+
1675
+ def __init__(self, conf: 'LexerConf', comparator=None) -> None:
1676
+ terminals = list(conf.terminals)
1677
+ assert all(isinstance(t, TerminalDef) for t in terminals), terminals
1678
+
1679
+ self.re = conf.re_module
1680
+
1681
+ if not conf.skip_validation:
1682
+ ##
1683
+
1684
+ terminal_to_regexp = {}
1685
+ for t in terminals:
1686
+ regexp = t.pattern.to_regexp()
1687
+ try:
1688
+ self.re.compile(regexp, conf.g_regex_flags)
1689
+ except self.re.error:
1690
+ raise LexError("Cannot compile token %s: %s" % (t.name, t.pattern))
1691
+
1692
+ if t.pattern.min_width == 0:
1693
+ raise LexError("Lexer does not allow zero-width terminals. (%s: %s)" % (t.name, t.pattern))
1694
+ if t.pattern.type == "re":
1695
+ terminal_to_regexp[t] = regexp
1696
+
1697
+ if not (set(conf.ignore) <= {t.name for t in terminals}):
1698
+ raise LexError("Ignore terminals are not defined: %s" % (set(conf.ignore) - {t.name for t in terminals}))
1699
+
1700
+ if has_interegular:
1701
+ _check_regex_collisions(terminal_to_regexp, comparator, conf.strict)
1702
+ elif conf.strict:
1703
+ raise LexError("interegular must be installed for strict mode. Use `pip install 'lark[interegular]'`.")
1704
+
1705
+ ##
1706
+
1707
+ self.newline_types = frozenset(t.name for t in terminals if _regexp_has_newline(t.pattern.to_regexp()))
1708
+ self.ignore_types = frozenset(conf.ignore)
1709
+
1710
+ terminals.sort(key=lambda x: (-x.priority, -x.pattern.max_width, -len(x.pattern.value), x.name))
1711
+ self.terminals = terminals
1712
+ self.user_callbacks = conf.callbacks
1713
+ self.g_regex_flags = conf.g_regex_flags
1714
+ self.use_bytes = conf.use_bytes
1715
+ self.terminals_by_name = conf.terminals_by_name
1716
+
1717
+ self._scanner: Optional[Scanner] = None
1718
+
1719
+ def _build_scanner(self) -> Scanner:
1720
+ terminals, self.callback = _create_unless(self.terminals, self.g_regex_flags, self.re, self.use_bytes)
1721
+ assert all(self.callback.values())
1722
+
1723
+ for type_, f in self.user_callbacks.items():
1724
+ if type_ in self.callback:
1725
+ ##
1726
+
1727
+ self.callback[type_] = CallChain(self.callback[type_], f, lambda t: t.type == type_)
1728
+ else:
1729
+ self.callback[type_] = f
1730
+
1731
+ return Scanner(terminals, self.g_regex_flags, self.re, self.use_bytes)
1732
+
1733
+ @property
1734
+ def scanner(self) -> Scanner:
1735
+ if self._scanner is None:
1736
+ self._scanner = self._build_scanner()
1737
+ return self._scanner
1738
+
1739
+ def match(self, text, pos):
1740
+ return self.scanner.match(text, pos)
1741
+
1742
+ def next_token(self, lex_state: LexerState, parser_state: Any = None) -> Token:
1743
+ line_ctr = lex_state.line_ctr
1744
+ while line_ctr.char_pos < lex_state.text.end:
1745
+ res = self.match(lex_state.text, line_ctr.char_pos)
1746
+ if not res:
1747
+ allowed = self.scanner.allowed_types - self.ignore_types
1748
+ if not allowed:
1749
+ allowed = {"<END-OF-FILE>"}
1750
+ raise UnexpectedCharacters(lex_state.text.text, line_ctr.char_pos, line_ctr.line, line_ctr.column,
1751
+ allowed=allowed, token_history=lex_state.last_token and [lex_state.last_token],
1752
+ state=parser_state, terminals_by_name=self.terminals_by_name)
1753
+
1754
+ value, type_ = res
1755
+
1756
+ ignored = type_ in self.ignore_types
1757
+ t = None
1758
+ if not ignored or type_ in self.callback:
1759
+ t = Token(type_, value, line_ctr.char_pos, line_ctr.line, line_ctr.column)
1760
+ line_ctr.feed(value, type_ in self.newline_types)
1761
+ if t is not None:
1762
+ t.end_line = line_ctr.line
1763
+ t.end_column = line_ctr.column
1764
+ t.end_pos = line_ctr.char_pos
1765
+ if t.type in self.callback:
1766
+ t = self.callback[t.type](t)
1767
+ if not ignored:
1768
+ if not isinstance(t, Token):
1769
+ raise LexError("Callbacks must return a token (returned %r)" % t)
1770
+ lex_state.last_token = t
1771
+ return t
1772
+
1773
+ ##
1774
+
1775
+ raise EOFError(self)
1776
+
1777
+
1778
+ class ContextualLexer(Lexer):
1779
+ lexers: Dict[int, AbstractBasicLexer]
1780
+ root_lexer: AbstractBasicLexer
1781
+
1782
+ BasicLexer: Type[AbstractBasicLexer] = BasicLexer
1783
+
1784
+ def __init__(self, conf: 'LexerConf', states: Dict[int, Collection[str]], always_accept: Collection[str]=()) -> None:
1785
+ terminals = list(conf.terminals)
1786
+ terminals_by_name = conf.terminals_by_name
1787
+
1788
+ trad_conf = copy(conf)
1789
+ trad_conf.terminals = terminals
1790
+
1791
+ if has_interegular and not conf.skip_validation:
1792
+ comparator = interegular.Comparator.from_regexes({t: t.pattern.to_regexp() for t in terminals})
1793
+ else:
1794
+ comparator = None
1795
+ lexer_by_tokens: Dict[FrozenSet[str], AbstractBasicLexer] = {}
1796
+ self.lexers = {}
1797
+ for state, accepts in states.items():
1798
+ key = frozenset(accepts)
1799
+ try:
1800
+ lexer = lexer_by_tokens[key]
1801
+ except KeyError:
1802
+ accepts = set(accepts) | set(conf.ignore) | set(always_accept)
1803
+ lexer_conf = copy(trad_conf)
1804
+ lexer_conf.terminals = [terminals_by_name[n] for n in accepts if n in terminals_by_name]
1805
+ lexer = self.BasicLexer(lexer_conf, comparator)
1806
+ lexer_by_tokens[key] = lexer
1807
+
1808
+ self.lexers[state] = lexer
1809
+
1810
+ assert trad_conf.terminals is terminals
1811
+ trad_conf.skip_validation = True ##
1812
+
1813
+ self.root_lexer = self.BasicLexer(trad_conf, comparator)
1814
+
1815
+ def lex(self, lexer_state: LexerState, parser_state: 'ParserState') -> Iterator[Token]:
1816
+ try:
1817
+ while True:
1818
+ lexer = self.lexers[parser_state.position]
1819
+ yield lexer.next_token(lexer_state, parser_state)
1820
+ except EOFError:
1821
+ pass
1822
+ except UnexpectedCharacters as e:
1823
+ ##
1824
+
1825
+ ##
1826
+
1827
+ try:
1828
+ last_token = lexer_state.last_token ##
1829
+
1830
+ token = self.root_lexer.next_token(lexer_state, parser_state)
1831
+ raise UnexpectedToken(token, e.allowed, state=parser_state, token_history=[last_token], terminals_by_name=self.root_lexer.terminals_by_name)
1832
+ except UnexpectedCharacters:
1833
+ raise e ##
1834
+
1835
+
1836
+
1837
+
1838
+ _ParserArgType: 'TypeAlias' = 'Literal["earley", "lalr", "cyk", "auto"]'
1839
+ _LexerArgType: 'TypeAlias' = 'Union[Literal["auto", "basic", "contextual", "dynamic", "dynamic_complete"], Type[Lexer]]'
1840
+ _LexerCallback = Callable[[Token], Token]
1841
+ ParserCallbacks = Dict[str, Callable]
1842
+
1843
+ class LexerConf(Serialize):
1844
+ __serialize_fields__ = 'terminals', 'ignore', 'g_regex_flags', 'use_bytes', 'lexer_type'
1845
+ __serialize_namespace__ = TerminalDef,
1846
+
1847
+ terminals: Collection[TerminalDef]
1848
+ re_module: ModuleType
1849
+ ignore: Collection[str]
1850
+ postlex: 'Optional[PostLex]'
1851
+ callbacks: Dict[str, _LexerCallback]
1852
+ g_regex_flags: int
1853
+ skip_validation: bool
1854
+ use_bytes: bool
1855
+ lexer_type: Optional[_LexerArgType]
1856
+ strict: bool
1857
+
1858
+ def __init__(self, terminals: Collection[TerminalDef], re_module: ModuleType, ignore: Collection[str]=(), postlex: 'Optional[PostLex]'=None,
1859
+ callbacks: Optional[Dict[str, _LexerCallback]]=None, g_regex_flags: int=0, skip_validation: bool=False, use_bytes: bool=False, strict: bool=False):
1860
+ self.terminals = terminals
1861
+ self.terminals_by_name = {t.name: t for t in self.terminals}
1862
+ assert len(self.terminals) == len(self.terminals_by_name)
1863
+ self.ignore = ignore
1864
+ self.postlex = postlex
1865
+ self.callbacks = callbacks or {}
1866
+ self.g_regex_flags = g_regex_flags
1867
+ self.re_module = re_module
1868
+ self.skip_validation = skip_validation
1869
+ self.use_bytes = use_bytes
1870
+ self.strict = strict
1871
+ self.lexer_type = None
1872
+
1873
+ def _deserialize(self):
1874
+ self.terminals_by_name = {t.name: t for t in self.terminals}
1875
+
1876
+ def __deepcopy__(self, memo=None):
1877
+ return type(self)(
1878
+ deepcopy(self.terminals, memo),
1879
+ self.re_module,
1880
+ deepcopy(self.ignore, memo),
1881
+ deepcopy(self.postlex, memo),
1882
+ deepcopy(self.callbacks, memo),
1883
+ deepcopy(self.g_regex_flags, memo),
1884
+ deepcopy(self.skip_validation, memo),
1885
+ deepcopy(self.use_bytes, memo),
1886
+ )
1887
+
1888
+ class ParserConf(Serialize):
1889
+ __serialize_fields__ = 'rules', 'start', 'parser_type'
1890
+
1891
+ rules: List['Rule']
1892
+ callbacks: ParserCallbacks
1893
+ start: List[str]
1894
+ parser_type: _ParserArgType
1895
+
1896
+ def __init__(self, rules: List['Rule'], callbacks: ParserCallbacks, start: List[str]):
1897
+ assert isinstance(start, list)
1898
+ self.rules = rules
1899
+ self.callbacks = callbacks
1900
+ self.start = start
1901
+
1902
+
1903
+ from functools import partial, wraps
1904
+ from itertools import product
1905
+
1906
+
1907
+ class ExpandSingleChild:
1908
+ def __init__(self, node_builder):
1909
+ self.node_builder = node_builder
1910
+
1911
+ def __call__(self, children):
1912
+ if len(children) == 1:
1913
+ return children[0]
1914
+ else:
1915
+ return self.node_builder(children)
1916
+
1917
+
1918
+
1919
+ class PropagatePositions:
1920
+ def __init__(self, node_builder, node_filter=None):
1921
+ self.node_builder = node_builder
1922
+ self.node_filter = node_filter
1923
+
1924
+ def __call__(self, children):
1925
+ res = self.node_builder(children)
1926
+
1927
+ if isinstance(res, Tree):
1928
+ ##
1929
+
1930
+ ##
1931
+
1932
+ ##
1933
+
1934
+ ##
1935
+
1936
+
1937
+ res_meta = res.meta
1938
+
1939
+ first_meta = self._pp_get_meta(children)
1940
+ if first_meta is not None:
1941
+ if not hasattr(res_meta, 'line'):
1942
+ ##
1943
+
1944
+ res_meta.line = getattr(first_meta, 'container_line', first_meta.line)
1945
+ res_meta.column = getattr(first_meta, 'container_column', first_meta.column)
1946
+ res_meta.start_pos = getattr(first_meta, 'container_start_pos', first_meta.start_pos)
1947
+ res_meta.empty = False
1948
+
1949
+ res_meta.container_line = getattr(first_meta, 'container_line', first_meta.line)
1950
+ res_meta.container_column = getattr(first_meta, 'container_column', first_meta.column)
1951
+ res_meta.container_start_pos = getattr(first_meta, 'container_start_pos', first_meta.start_pos)
1952
+
1953
+ last_meta = self._pp_get_meta(reversed(children))
1954
+ if last_meta is not None:
1955
+ if not hasattr(res_meta, 'end_line'):
1956
+ res_meta.end_line = getattr(last_meta, 'container_end_line', last_meta.end_line)
1957
+ res_meta.end_column = getattr(last_meta, 'container_end_column', last_meta.end_column)
1958
+ res_meta.end_pos = getattr(last_meta, 'container_end_pos', last_meta.end_pos)
1959
+ res_meta.empty = False
1960
+
1961
+ res_meta.container_end_line = getattr(last_meta, 'container_end_line', last_meta.end_line)
1962
+ res_meta.container_end_column = getattr(last_meta, 'container_end_column', last_meta.end_column)
1963
+ res_meta.container_end_pos = getattr(last_meta, 'container_end_pos', last_meta.end_pos)
1964
+
1965
+ return res
1966
+
1967
+ def _pp_get_meta(self, children):
1968
+ for c in children:
1969
+ if self.node_filter is not None and not self.node_filter(c):
1970
+ continue
1971
+ if isinstance(c, Tree):
1972
+ if not c.meta.empty:
1973
+ return c.meta
1974
+ elif isinstance(c, Token):
1975
+ return c
1976
+ elif hasattr(c, '__lark_meta__'):
1977
+ return c.__lark_meta__()
1978
+
1979
+ def make_propagate_positions(option):
1980
+ if callable(option):
1981
+ return partial(PropagatePositions, node_filter=option)
1982
+ elif option is True:
1983
+ return PropagatePositions
1984
+ elif option is False:
1985
+ return None
1986
+
1987
+ raise ConfigurationError('Invalid option for propagate_positions: %r' % option)
1988
+
1989
+
1990
+ class ChildFilter:
1991
+ def __init__(self, to_include, append_none, node_builder):
1992
+ self.node_builder = node_builder
1993
+ self.to_include = to_include
1994
+ self.append_none = append_none
1995
+
1996
+ def __call__(self, children):
1997
+ filtered = []
1998
+
1999
+ for i, to_expand, add_none in self.to_include:
2000
+ if add_none:
2001
+ filtered += [None] * add_none
2002
+ if to_expand:
2003
+ filtered += children[i].children
2004
+ else:
2005
+ filtered.append(children[i])
2006
+
2007
+ if self.append_none:
2008
+ filtered += [None] * self.append_none
2009
+
2010
+ return self.node_builder(filtered)
2011
+
2012
+
2013
+ class ChildFilterLALR(ChildFilter):
2014
+ #--
2015
+
2016
+ def __call__(self, children):
2017
+ filtered = []
2018
+ for i, to_expand, add_none in self.to_include:
2019
+ if add_none:
2020
+ filtered += [None] * add_none
2021
+ if to_expand:
2022
+ if filtered:
2023
+ filtered += children[i].children
2024
+ else: ##
2025
+
2026
+ filtered = children[i].children
2027
+ else:
2028
+ filtered.append(children[i])
2029
+
2030
+ if self.append_none:
2031
+ filtered += [None] * self.append_none
2032
+
2033
+ return self.node_builder(filtered)
2034
+
2035
+
2036
+ class ChildFilterLALR_NoPlaceholders(ChildFilter):
2037
+ #--
2038
+ def __init__(self, to_include, node_builder):
2039
+ self.node_builder = node_builder
2040
+ self.to_include = to_include
2041
+
2042
+ def __call__(self, children):
2043
+ filtered = []
2044
+ for i, to_expand in self.to_include:
2045
+ if to_expand:
2046
+ if filtered:
2047
+ filtered += children[i].children
2048
+ else: ##
2049
+
2050
+ filtered = children[i].children
2051
+ else:
2052
+ filtered.append(children[i])
2053
+ return self.node_builder(filtered)
2054
+
2055
+
2056
+ def _should_expand(sym):
2057
+ return not sym.is_term and sym.name.startswith('_')
2058
+
2059
+
2060
+ def maybe_create_child_filter(expansion, keep_all_tokens, ambiguous, _empty_indices: List[bool]):
2061
+ ##
2062
+
2063
+ if _empty_indices:
2064
+ assert _empty_indices.count(False) == len(expansion)
2065
+ s = ''.join(str(int(b)) for b in _empty_indices)
2066
+ empty_indices = [len(ones) for ones in s.split('0')]
2067
+ assert len(empty_indices) == len(expansion)+1, (empty_indices, len(expansion))
2068
+ else:
2069
+ empty_indices = [0] * (len(expansion)+1)
2070
+
2071
+ to_include = []
2072
+ nones_to_add = 0
2073
+ for i, sym in enumerate(expansion):
2074
+ nones_to_add += empty_indices[i]
2075
+ if keep_all_tokens or not (sym.is_term and sym.filter_out):
2076
+ to_include.append((i, _should_expand(sym), nones_to_add))
2077
+ nones_to_add = 0
2078
+
2079
+ nones_to_add += empty_indices[len(expansion)]
2080
+
2081
+ if _empty_indices or len(to_include) < len(expansion) or any(to_expand for i, to_expand,_ in to_include):
2082
+ if _empty_indices or ambiguous:
2083
+ return partial(ChildFilter if ambiguous else ChildFilterLALR, to_include, nones_to_add)
2084
+ else:
2085
+ ##
2086
+
2087
+ return partial(ChildFilterLALR_NoPlaceholders, [(i, x) for i,x,_ in to_include])
2088
+
2089
+
2090
+ class AmbiguousExpander:
2091
+ #--
2092
+ def __init__(self, to_expand, tree_class, node_builder):
2093
+ self.node_builder = node_builder
2094
+ self.tree_class = tree_class
2095
+ self.to_expand = to_expand
2096
+
2097
+ def __call__(self, children):
2098
+ def _is_ambig_tree(t):
2099
+ return hasattr(t, 'data') and t.data == '_ambig'
2100
+
2101
+ ##
2102
+
2103
+ ##
2104
+
2105
+ ##
2106
+
2107
+ ##
2108
+
2109
+ ambiguous = []
2110
+ for i, child in enumerate(children):
2111
+ if _is_ambig_tree(child):
2112
+ if i in self.to_expand:
2113
+ ambiguous.append(i)
2114
+
2115
+ child.expand_kids_by_data('_ambig')
2116
+
2117
+ if not ambiguous:
2118
+ return self.node_builder(children)
2119
+
2120
+ expand = [child.children if i in ambiguous else (child,) for i, child in enumerate(children)]
2121
+ return self.tree_class('_ambig', [self.node_builder(list(f)) for f in product(*expand)])
2122
+
2123
+
2124
+ def maybe_create_ambiguous_expander(tree_class, expansion, keep_all_tokens):
2125
+ to_expand = [i for i, sym in enumerate(expansion)
2126
+ if keep_all_tokens or ((not (sym.is_term and sym.filter_out)) and _should_expand(sym))]
2127
+ if to_expand:
2128
+ return partial(AmbiguousExpander, to_expand, tree_class)
2129
+
2130
+
2131
+ class AmbiguousIntermediateExpander:
2132
+ #--
2133
+
2134
+ def __init__(self, tree_class, node_builder):
2135
+ self.node_builder = node_builder
2136
+ self.tree_class = tree_class
2137
+
2138
+ def __call__(self, children):
2139
+ def _is_iambig_tree(child):
2140
+ return hasattr(child, 'data') and child.data == '_iambig'
2141
+
2142
+ def _collapse_iambig(children):
2143
+ #--
2144
+
2145
+ ##
2146
+
2147
+ ##
2148
+
2149
+ if children and _is_iambig_tree(children[0]):
2150
+ iambig_node = children[0]
2151
+ result = []
2152
+ for grandchild in iambig_node.children:
2153
+ collapsed = _collapse_iambig(grandchild.children)
2154
+ if collapsed:
2155
+ for child in collapsed:
2156
+ child.children += children[1:]
2157
+ result += collapsed
2158
+ else:
2159
+ new_tree = self.tree_class('_inter', grandchild.children + children[1:])
2160
+ result.append(new_tree)
2161
+ return result
2162
+
2163
+ collapsed = _collapse_iambig(children)
2164
+ if collapsed:
2165
+ processed_nodes = [self.node_builder(c.children) for c in collapsed]
2166
+ return self.tree_class('_ambig', processed_nodes)
2167
+
2168
+ return self.node_builder(children)
2169
+
2170
+
2171
+
2172
+ def inplace_transformer(func):
2173
+ @wraps(func)
2174
+ def f(children):
2175
+ ##
2176
+
2177
+ tree = Tree(func.__name__, children)
2178
+ return func(tree)
2179
+ return f
2180
+
2181
+
2182
+ def apply_visit_wrapper(func, name, wrapper):
2183
+ if wrapper is _vargs_meta or wrapper is _vargs_meta_inline:
2184
+ raise NotImplementedError("Meta args not supported for internal transformer; use YourTransformer().transform(parser.parse()) instead")
2185
+
2186
+ @wraps(func)
2187
+ def f(children):
2188
+ return wrapper(func, name, children, None)
2189
+ return f
2190
+
2191
+
2192
+ class ParseTreeBuilder:
2193
+ def __init__(self, rules, tree_class, propagate_positions=False, ambiguous=False, maybe_placeholders=False):
2194
+ self.tree_class = tree_class
2195
+ self.propagate_positions = propagate_positions
2196
+ self.ambiguous = ambiguous
2197
+ self.maybe_placeholders = maybe_placeholders
2198
+
2199
+ self.rule_builders = list(self._init_builders(rules))
2200
+
2201
+ def _init_builders(self, rules):
2202
+ propagate_positions = make_propagate_positions(self.propagate_positions)
2203
+
2204
+ for rule in rules:
2205
+ options = rule.options
2206
+ keep_all_tokens = options.keep_all_tokens
2207
+ expand_single_child = options.expand1
2208
+
2209
+ wrapper_chain = list(filter(None, [
2210
+ (expand_single_child and not rule.alias) and ExpandSingleChild,
2211
+ maybe_create_child_filter(rule.expansion, keep_all_tokens, self.ambiguous, options.empty_indices if self.maybe_placeholders else None),
2212
+ propagate_positions,
2213
+ self.ambiguous and maybe_create_ambiguous_expander(self.tree_class, rule.expansion, keep_all_tokens),
2214
+ self.ambiguous and partial(AmbiguousIntermediateExpander, self.tree_class)
2215
+ ]))
2216
+
2217
+ yield rule, wrapper_chain
2218
+
2219
+ def create_callback(self, transformer=None):
2220
+ callbacks = {}
2221
+
2222
+ default_handler = getattr(transformer, '__default__', None)
2223
+ if default_handler:
2224
+ def default_callback(data, children):
2225
+ return default_handler(data, children, None)
2226
+ else:
2227
+ default_callback = self.tree_class
2228
+
2229
+ for rule, wrapper_chain in self.rule_builders:
2230
+
2231
+ user_callback_name = rule.alias or rule.options.template_source or rule.origin.name
2232
+ try:
2233
+ f = getattr(transformer, user_callback_name)
2234
+ wrapper = getattr(f, 'visit_wrapper', None)
2235
+ if wrapper is not None:
2236
+ f = apply_visit_wrapper(f, user_callback_name, wrapper)
2237
+ elif isinstance(transformer, Transformer_InPlace):
2238
+ f = inplace_transformer(f)
2239
+ except AttributeError:
2240
+ f = partial(default_callback, user_callback_name)
2241
+
2242
+ for w in wrapper_chain:
2243
+ f = w(f)
2244
+
2245
+ if rule in callbacks:
2246
+ raise GrammarError("Rule '%s' already exists" % (rule,))
2247
+
2248
+ callbacks[rule] = f
2249
+
2250
+ return callbacks
2251
+
2252
+
2253
+
2254
+ class Action:
2255
+ def __init__(self, name):
2256
+ self.name = name
2257
+ def __str__(self):
2258
+ return self.name
2259
+ def __repr__(self):
2260
+ return str(self)
2261
+
2262
+ Shift = Action('Shift')
2263
+ Reduce = Action('Reduce')
2264
+
2265
+ StateT = TypeVar("StateT")
2266
+
2267
+ class ParseTableBase(Generic[StateT]):
2268
+ states: Dict[StateT, Dict[str, Tuple]]
2269
+ start_states: Dict[str, StateT]
2270
+ end_states: Dict[str, StateT]
2271
+
2272
+ def __init__(self, states, start_states, end_states):
2273
+ self.states = states
2274
+ self.start_states = start_states
2275
+ self.end_states = end_states
2276
+
2277
+ def serialize(self, memo):
2278
+ tokens = Enumerator()
2279
+
2280
+ states = {
2281
+ state: {tokens.get(token): ((1, arg.serialize(memo)) if action is Reduce else (0, arg))
2282
+ for token, (action, arg) in actions.items()}
2283
+ for state, actions in self.states.items()
2284
+ }
2285
+
2286
+ return {
2287
+ 'tokens': tokens.reversed(),
2288
+ 'states': states,
2289
+ 'start_states': self.start_states,
2290
+ 'end_states': self.end_states,
2291
+ }
2292
+
2293
+ @classmethod
2294
+ def deserialize(cls, data, memo):
2295
+ tokens = data['tokens']
2296
+ states = {
2297
+ state: {tokens[token]: ((Reduce, Rule.deserialize(arg, memo)) if action==1 else (Shift, arg))
2298
+ for token, (action, arg) in actions.items()}
2299
+ for state, actions in data['states'].items()
2300
+ }
2301
+ return cls(states, data['start_states'], data['end_states'])
2302
+
2303
+ class ParseTable(ParseTableBase['State']):
2304
+ #--
2305
+ pass
2306
+
2307
+
2308
+ class IntParseTable(ParseTableBase[int]):
2309
+ #--
2310
+
2311
+ @classmethod
2312
+ def from_ParseTable(cls, parse_table: ParseTable):
2313
+ enum = list(parse_table.states)
2314
+ state_to_idx: Dict['State', int] = {s:i for i,s in enumerate(enum)}
2315
+ int_states = {}
2316
+
2317
+ for s, la in parse_table.states.items():
2318
+ la = {k:(v[0], state_to_idx[v[1]]) if v[0] is Shift else v
2319
+ for k,v in la.items()}
2320
+ int_states[ state_to_idx[s] ] = la
2321
+
2322
+
2323
+ start_states = {start:state_to_idx[s] for start, s in parse_table.start_states.items()}
2324
+ end_states = {start:state_to_idx[s] for start, s in parse_table.end_states.items()}
2325
+ return cls(int_states, start_states, end_states)
2326
+
2327
+
2328
+
2329
+ class ParseConf(Generic[StateT]):
2330
+ __slots__ = 'parse_table', 'callbacks', 'start', 'start_state', 'end_state', 'states'
2331
+
2332
+ parse_table: ParseTableBase[StateT]
2333
+ callbacks: ParserCallbacks
2334
+ start: str
2335
+
2336
+ start_state: StateT
2337
+ end_state: StateT
2338
+ states: Dict[StateT, Dict[str, tuple]]
2339
+
2340
+ def __init__(self, parse_table: ParseTableBase[StateT], callbacks: ParserCallbacks, start: str):
2341
+ self.parse_table = parse_table
2342
+
2343
+ self.start_state = self.parse_table.start_states[start]
2344
+ self.end_state = self.parse_table.end_states[start]
2345
+ self.states = self.parse_table.states
2346
+
2347
+ self.callbacks = callbacks
2348
+ self.start = start
2349
+
2350
+ class ParserState(Generic[StateT]):
2351
+ __slots__ = 'parse_conf', 'lexer', 'state_stack', 'value_stack'
2352
+
2353
+ parse_conf: ParseConf[StateT]
2354
+ lexer: LexerThread
2355
+ state_stack: List[StateT]
2356
+ value_stack: list
2357
+
2358
+ def __init__(self, parse_conf: ParseConf[StateT], lexer: LexerThread, state_stack=None, value_stack=None):
2359
+ self.parse_conf = parse_conf
2360
+ self.lexer = lexer
2361
+ self.state_stack = state_stack or [self.parse_conf.start_state]
2362
+ self.value_stack = value_stack or []
2363
+
2364
+ @property
2365
+ def position(self) -> StateT:
2366
+ return self.state_stack[-1]
2367
+
2368
+ ##
2369
+
2370
+ def __eq__(self, other) -> bool:
2371
+ if not isinstance(other, ParserState):
2372
+ return NotImplemented
2373
+ return len(self.state_stack) == len(other.state_stack) and self.position == other.position
2374
+
2375
+ def __copy__(self):
2376
+ return self.copy()
2377
+
2378
+ def copy(self, deepcopy_values=True) -> 'ParserState[StateT]':
2379
+ return type(self)(
2380
+ self.parse_conf,
2381
+ self.lexer, ##
2382
+
2383
+ copy(self.state_stack),
2384
+ deepcopy(self.value_stack) if deepcopy_values else copy(self.value_stack),
2385
+ )
2386
+
2387
+ def feed_token(self, token: Token, is_end=False) -> Any:
2388
+ state_stack = self.state_stack
2389
+ value_stack = self.value_stack
2390
+ states = self.parse_conf.states
2391
+ end_state = self.parse_conf.end_state
2392
+ callbacks = self.parse_conf.callbacks
2393
+
2394
+ while True:
2395
+ state = state_stack[-1]
2396
+ try:
2397
+ action, arg = states[state][token.type]
2398
+ except KeyError:
2399
+ expected = {s for s in states[state].keys() if s.isupper()}
2400
+ raise UnexpectedToken(token, expected, state=self, interactive_parser=None)
2401
+
2402
+ assert arg != end_state
2403
+
2404
+ if action is Shift:
2405
+ ##
2406
+
2407
+ assert not is_end
2408
+ state_stack.append(arg)
2409
+ value_stack.append(token if token.type not in callbacks else callbacks[token.type](token))
2410
+ return
2411
+ else:
2412
+ ##
2413
+
2414
+ rule = arg
2415
+ size = len(rule.expansion)
2416
+ if size:
2417
+ s = value_stack[-size:]
2418
+ del state_stack[-size:]
2419
+ del value_stack[-size:]
2420
+ else:
2421
+ s = []
2422
+
2423
+ value = callbacks[rule](s) if callbacks else s
2424
+
2425
+ _action, new_state = states[state_stack[-1]][rule.origin.name]
2426
+ assert _action is Shift
2427
+ state_stack.append(new_state)
2428
+ value_stack.append(value)
2429
+
2430
+ if is_end and state_stack[-1] == end_state:
2431
+ return value_stack[-1]
2432
+
2433
+
2434
+ class LALR_Parser(Serialize):
2435
+ def __init__(self, parser_conf: ParserConf, debug: bool=False, strict: bool=False):
2436
+ analysis = LALR_Analyzer(parser_conf, debug=debug, strict=strict)
2437
+ analysis.compute_lalr()
2438
+ callbacks = parser_conf.callbacks
2439
+
2440
+ self._parse_table = analysis.parse_table
2441
+ self.parser_conf = parser_conf
2442
+ self.parser = _Parser(analysis.parse_table, callbacks, debug)
2443
+
2444
+ @classmethod
2445
+ def deserialize(cls, data, memo, callbacks, debug=False):
2446
+ inst = cls.__new__(cls)
2447
+ inst._parse_table = IntParseTable.deserialize(data, memo)
2448
+ inst.parser = _Parser(inst._parse_table, callbacks, debug)
2449
+ return inst
2450
+
2451
+ def serialize(self, memo: Any = None) -> Dict[str, Any]:
2452
+ return self._parse_table.serialize(memo)
2453
+
2454
+ def parse_interactive(self, lexer: LexerThread, start: str):
2455
+ return self.parser.parse(lexer, start, start_interactive=True)
2456
+
2457
+ def parse(self, lexer, start, on_error=None):
2458
+ try:
2459
+ return self.parser.parse(lexer, start)
2460
+ except UnexpectedInput as e:
2461
+ if on_error is None:
2462
+ raise
2463
+
2464
+ while True:
2465
+ if isinstance(e, UnexpectedCharacters):
2466
+ s = e.interactive_parser.lexer_thread.state
2467
+ p = s.line_ctr.char_pos
2468
+
2469
+ if not on_error(e):
2470
+ raise e
2471
+
2472
+ if isinstance(e, UnexpectedCharacters):
2473
+ ##
2474
+
2475
+ if p == s.line_ctr.char_pos:
2476
+ s.line_ctr.feed(s.text.text[p:p+1])
2477
+
2478
+ try:
2479
+ return e.interactive_parser.resume_parse()
2480
+ except UnexpectedToken as e2:
2481
+ if (isinstance(e, UnexpectedToken)
2482
+ and e.token.type == e2.token.type == '$END'
2483
+ and e.interactive_parser == e2.interactive_parser):
2484
+ ##
2485
+
2486
+ raise e2
2487
+ e = e2
2488
+ except UnexpectedCharacters as e2:
2489
+ e = e2
2490
+
2491
+
2492
+ class _Parser:
2493
+ parse_table: ParseTableBase
2494
+ callbacks: ParserCallbacks
2495
+ debug: bool
2496
+
2497
+ def __init__(self, parse_table: ParseTableBase, callbacks: ParserCallbacks, debug: bool=False):
2498
+ self.parse_table = parse_table
2499
+ self.callbacks = callbacks
2500
+ self.debug = debug
2501
+
2502
+ def parse(self, lexer: LexerThread, start: str, value_stack=None, state_stack=None, start_interactive=False):
2503
+ parse_conf = ParseConf(self.parse_table, self.callbacks, start)
2504
+ parser_state = ParserState(parse_conf, lexer, state_stack, value_stack)
2505
+ if start_interactive:
2506
+ return InteractiveParser(self, parser_state, parser_state.lexer)
2507
+ return self.parse_from_state(parser_state)
2508
+
2509
+
2510
+ def parse_from_state(self, state: ParserState, last_token: Optional[Token]=None):
2511
+ #--
2512
+ try:
2513
+ token = last_token
2514
+ for token in state.lexer.lex(state):
2515
+ assert token is not None
2516
+ state.feed_token(token)
2517
+
2518
+ end_token = Token.new_borrow_pos('$END', '', token) if token else Token('$END', '', 0, 1, 1)
2519
+ return state.feed_token(end_token, True)
2520
+ except UnexpectedInput as e:
2521
+ try:
2522
+ e.interactive_parser = InteractiveParser(self, state, state.lexer)
2523
+ except NameError:
2524
+ pass
2525
+ raise e
2526
+ except Exception as e:
2527
+ if self.debug:
2528
+ print("")
2529
+ print("STATE STACK DUMP")
2530
+ print("----------------")
2531
+ for i, s in enumerate(state.state_stack):
2532
+ print('%d)' % i , s)
2533
+ print("")
2534
+
2535
+ raise
2536
+
2537
+
2538
+ class InteractiveParser:
2539
+ #--
2540
+ def __init__(self, parser, parser_state: ParserState, lexer_thread: LexerThread):
2541
+ self.parser = parser
2542
+ self.parser_state = parser_state
2543
+ self.lexer_thread = lexer_thread
2544
+ self.result = None
2545
+
2546
+ @property
2547
+ def lexer_state(self) -> LexerThread:
2548
+ warnings.warn("lexer_state will be removed in subsequent releases. Use lexer_thread instead.", DeprecationWarning)
2549
+ return self.lexer_thread
2550
+
2551
+ def feed_token(self, token: Token):
2552
+ #--
2553
+ return self.parser_state.feed_token(token, token.type == '$END')
2554
+
2555
+ def iter_parse(self) -> Iterator[Token]:
2556
+ #--
2557
+ for token in self.lexer_thread.lex(self.parser_state):
2558
+ yield token
2559
+ self.result = self.feed_token(token)
2560
+
2561
+ def exhaust_lexer(self) -> List[Token]:
2562
+ #--
2563
+ return list(self.iter_parse())
2564
+
2565
+
2566
+ def feed_eof(self, last_token=None):
2567
+ #--
2568
+ eof = Token.new_borrow_pos('$END', '', last_token) if last_token is not None else self.lexer_thread._Token('$END', '', 0, 1, 1)
2569
+ return self.feed_token(eof)
2570
+
2571
+
2572
+ def __copy__(self):
2573
+ #--
2574
+ return self.copy()
2575
+
2576
+ def copy(self, deepcopy_values=True):
2577
+ return type(self)(
2578
+ self.parser,
2579
+ self.parser_state.copy(deepcopy_values=deepcopy_values),
2580
+ copy(self.lexer_thread),
2581
+ )
2582
+
2583
+ def __eq__(self, other):
2584
+ if not isinstance(other, InteractiveParser):
2585
+ return False
2586
+
2587
+ return self.parser_state == other.parser_state and self.lexer_thread == other.lexer_thread
2588
+
2589
+ def as_immutable(self):
2590
+ #--
2591
+ p = copy(self)
2592
+ return ImmutableInteractiveParser(p.parser, p.parser_state, p.lexer_thread)
2593
+
2594
+ def pretty(self):
2595
+ #--
2596
+ out = ["Parser choices:"]
2597
+ for k, v in self.choices().items():
2598
+ out.append('\t- %s -> %r' % (k, v))
2599
+ out.append('stack size: %s' % len(self.parser_state.state_stack))
2600
+ return '\n'.join(out)
2601
+
2602
+ def choices(self):
2603
+ #--
2604
+ return self.parser_state.parse_conf.parse_table.states[self.parser_state.position]
2605
+
2606
+ def accepts(self):
2607
+ #--
2608
+ accepts = set()
2609
+ conf_no_callbacks = copy(self.parser_state.parse_conf)
2610
+ ##
2611
+
2612
+ ##
2613
+
2614
+ conf_no_callbacks.callbacks = {}
2615
+ for t in self.choices():
2616
+ if t.isupper(): ##
2617
+
2618
+ new_cursor = self.copy(deepcopy_values=False)
2619
+ new_cursor.parser_state.parse_conf = conf_no_callbacks
2620
+ try:
2621
+ new_cursor.feed_token(self.lexer_thread._Token(t, ''))
2622
+ except UnexpectedToken:
2623
+ pass
2624
+ else:
2625
+ accepts.add(t)
2626
+ return accepts
2627
+
2628
+ def resume_parse(self):
2629
+ #--
2630
+ return self.parser.parse_from_state(self.parser_state, last_token=self.lexer_thread.state.last_token)
2631
+
2632
+
2633
+
2634
+ class ImmutableInteractiveParser(InteractiveParser):
2635
+ #--
2636
+
2637
+ result = None
2638
+
2639
+ def __hash__(self):
2640
+ return hash((self.parser_state, self.lexer_thread))
2641
+
2642
+ def feed_token(self, token):
2643
+ c = copy(self)
2644
+ c.result = InteractiveParser.feed_token(c, token)
2645
+ return c
2646
+
2647
+ def exhaust_lexer(self):
2648
+ #--
2649
+ cursor = self.as_mutable()
2650
+ cursor.exhaust_lexer()
2651
+ return cursor.as_immutable()
2652
+
2653
+ def as_mutable(self):
2654
+ #--
2655
+ p = copy(self)
2656
+ return InteractiveParser(p.parser, p.parser_state, p.lexer_thread)
2657
+
2658
+
2659
+
2660
+ def _wrap_lexer(lexer_class):
2661
+ future_interface = getattr(lexer_class, '__future_interface__', 0)
2662
+ if future_interface == 2:
2663
+ return lexer_class
2664
+ elif future_interface == 1:
2665
+ class CustomLexerWrapper1(Lexer):
2666
+ def __init__(self, lexer_conf):
2667
+ self.lexer = lexer_class(lexer_conf)
2668
+ def lex(self, lexer_state, parser_state):
2669
+ if isinstance(lexer_state.text, TextSlice) and not lexer_state.text.is_complete_text():
2670
+ raise TypeError("Interface=1 Custom Lexer don't support TextSlice")
2671
+ lexer_state.text = lexer_state.text
2672
+ return self.lexer.lex(lexer_state, parser_state)
2673
+ return CustomLexerWrapper1
2674
+ elif future_interface == 0:
2675
+ class CustomLexerWrapper0(Lexer):
2676
+ def __init__(self, lexer_conf):
2677
+ self.lexer = lexer_class(lexer_conf)
2678
+
2679
+ def lex(self, lexer_state, parser_state):
2680
+ if isinstance(lexer_state.text, TextSlice):
2681
+ if not lexer_state.text.is_complete_text():
2682
+ raise TypeError("Interface=0 Custom Lexer don't support TextSlice")
2683
+ return self.lexer.lex(lexer_state.text.text)
2684
+ return self.lexer.lex(lexer_state.text)
2685
+ return CustomLexerWrapper0
2686
+ else:
2687
+ raise ValueError(f"Unknown __future_interface__ value {future_interface}, integer 0-2 expected")
2688
+
2689
+
2690
+ def _deserialize_parsing_frontend(data, memo, lexer_conf, callbacks, options):
2691
+ parser_conf = ParserConf.deserialize(data['parser_conf'], memo)
2692
+ cls = (options and options._plugins.get('LALR_Parser')) or LALR_Parser
2693
+ parser = cls.deserialize(data['parser'], memo, callbacks, options.debug)
2694
+ parser_conf.callbacks = callbacks
2695
+ return ParsingFrontend(lexer_conf, parser_conf, options, parser=parser)
2696
+
2697
+
2698
+ _parser_creators: 'Dict[str, Callable[[LexerConf, Any, Any], Any]]' = {}
2699
+
2700
+
2701
+ class ParsingFrontend(Serialize):
2702
+ __serialize_fields__ = 'lexer_conf', 'parser_conf', 'parser'
2703
+
2704
+ lexer_conf: LexerConf
2705
+ parser_conf: ParserConf
2706
+ options: Any
2707
+
2708
+ def __init__(self, lexer_conf: LexerConf, parser_conf: ParserConf, options, parser=None):
2709
+ self.parser_conf = parser_conf
2710
+ self.lexer_conf = lexer_conf
2711
+ self.options = options
2712
+
2713
+ ##
2714
+
2715
+ if parser: ##
2716
+
2717
+ self.parser = parser
2718
+ else:
2719
+ create_parser = _parser_creators.get(parser_conf.parser_type)
2720
+ assert create_parser is not None, "{} is not supported in standalone mode".format(
2721
+ parser_conf.parser_type
2722
+ )
2723
+ self.parser = create_parser(lexer_conf, parser_conf, options)
2724
+
2725
+ ##
2726
+
2727
+ lexer_type = lexer_conf.lexer_type
2728
+ self.skip_lexer = False
2729
+ if lexer_type in ('dynamic', 'dynamic_complete'):
2730
+ assert lexer_conf.postlex is None
2731
+ self.skip_lexer = True
2732
+ return
2733
+
2734
+ if isinstance(lexer_type, type):
2735
+ assert issubclass(lexer_type, Lexer)
2736
+ self.lexer = _wrap_lexer(lexer_type)(lexer_conf)
2737
+ elif isinstance(lexer_type, str):
2738
+ create_lexer = {
2739
+ 'basic': create_basic_lexer,
2740
+ 'contextual': create_contextual_lexer,
2741
+ }[lexer_type]
2742
+ self.lexer = create_lexer(lexer_conf, self.parser, lexer_conf.postlex, options)
2743
+ else:
2744
+ raise TypeError("Bad value for lexer_type: {lexer_type}")
2745
+
2746
+ if lexer_conf.postlex:
2747
+ self.lexer = PostLexConnector(self.lexer, lexer_conf.postlex)
2748
+
2749
+ def _verify_start(self, start=None):
2750
+ if start is None:
2751
+ start_decls = self.parser_conf.start
2752
+ if len(start_decls) > 1:
2753
+ raise ConfigurationError("Lark initialized with more than 1 possible start rule. Must specify which start rule to parse", start_decls)
2754
+ start ,= start_decls
2755
+ elif start not in self.parser_conf.start:
2756
+ raise ConfigurationError("Unknown start rule %s. Must be one of %r" % (start, self.parser_conf.start))
2757
+ return start
2758
+
2759
+ def _make_lexer_thread(self, text: Optional[LarkInput]) -> Union[LarkInput, LexerThread, None]:
2760
+ cls = (self.options and self.options._plugins.get('LexerThread')) or LexerThread
2761
+ if self.skip_lexer:
2762
+ return text
2763
+ if text is None:
2764
+ return cls(self.lexer, None)
2765
+ if isinstance(text, (str, bytes, TextSlice)):
2766
+ return cls.from_text(self.lexer, text)
2767
+ return cls.from_custom_input(self.lexer, text)
2768
+
2769
+ def parse(self, text: Optional[LarkInput], start=None, on_error=None):
2770
+ if self.lexer_conf.lexer_type in ("dynamic", "dynamic_complete"):
2771
+ if isinstance(text, TextSlice) and not text.is_complete_text():
2772
+ raise TypeError(f"Lexer {self.lexer_conf.lexer_type} does not support text slices.")
2773
+
2774
+ chosen_start = self._verify_start(start)
2775
+ kw = {} if on_error is None else {'on_error': on_error}
2776
+ stream = self._make_lexer_thread(text)
2777
+ return self.parser.parse(stream, chosen_start, **kw)
2778
+
2779
+ def parse_interactive(self, text: Optional[TextOrSlice]=None, start=None):
2780
+ ##
2781
+
2782
+ ##
2783
+
2784
+ chosen_start = self._verify_start(start)
2785
+ if self.parser_conf.parser_type != 'lalr':
2786
+ raise ConfigurationError("parse_interactive() currently only works with parser='lalr' ")
2787
+ stream = self._make_lexer_thread(text)
2788
+ return self.parser.parse_interactive(stream, chosen_start)
2789
+
2790
+
2791
+ def _validate_frontend_args(parser, lexer) -> None:
2792
+ assert_config(parser, ('lalr', 'earley', 'cyk'))
2793
+ if not isinstance(lexer, type): ##
2794
+
2795
+ expected = {
2796
+ 'lalr': ('basic', 'contextual'),
2797
+ 'earley': ('basic', 'dynamic', 'dynamic_complete'),
2798
+ 'cyk': ('basic', ),
2799
+ }[parser]
2800
+ assert_config(lexer, expected, 'Parser %r does not support lexer %%r, expected one of %%s' % parser)
2801
+
2802
+
2803
+ def _get_lexer_callbacks(transformer, terminals):
2804
+ result = {}
2805
+ for terminal in terminals:
2806
+ callback = getattr(transformer, terminal.name, None)
2807
+ if callback is not None:
2808
+ result[terminal.name] = callback
2809
+ return result
2810
+
2811
+ class PostLexConnector:
2812
+ def __init__(self, lexer, postlexer):
2813
+ self.lexer = lexer
2814
+ self.postlexer = postlexer
2815
+
2816
+ def lex(self, lexer_state, parser_state):
2817
+ i = self.lexer.lex(lexer_state, parser_state)
2818
+ return self.postlexer.process(i)
2819
+
2820
+
2821
+
2822
+ def create_basic_lexer(lexer_conf, parser, postlex, options) -> BasicLexer:
2823
+ cls = (options and options._plugins.get('BasicLexer')) or BasicLexer
2824
+ return cls(lexer_conf)
2825
+
2826
+ def create_contextual_lexer(lexer_conf: LexerConf, parser, postlex, options) -> ContextualLexer:
2827
+ cls = (options and options._plugins.get('ContextualLexer')) or ContextualLexer
2828
+ parse_table: ParseTableBase[int] = parser._parse_table
2829
+ states: Dict[int, Collection[str]] = {idx:list(t.keys()) for idx, t in parse_table.states.items()}
2830
+ always_accept: Collection[str] = postlex.always_accept if postlex else ()
2831
+ return cls(lexer_conf, states, always_accept=always_accept)
2832
+
2833
+ def create_lalr_parser(lexer_conf: LexerConf, parser_conf: ParserConf, options=None) -> LALR_Parser:
2834
+ debug = options.debug if options else False
2835
+ strict = options.strict if options else False
2836
+ cls = (options and options._plugins.get('LALR_Parser')) or LALR_Parser
2837
+ return cls(parser_conf, debug=debug, strict=strict)
2838
+
2839
+ _parser_creators['lalr'] = create_lalr_parser
2840
+
2841
+
2842
+
2843
+
2844
+ class PostLex(ABC):
2845
+ @abstractmethod
2846
+ def process(self, stream: Iterator[Token]) -> Iterator[Token]:
2847
+ return stream
2848
+
2849
+ always_accept: Iterable[str] = ()
2850
+
2851
+ class LarkOptions(Serialize):
2852
+ #--
2853
+
2854
+ start: List[str]
2855
+ debug: bool
2856
+ strict: bool
2857
+ transformer: 'Optional[Transformer]'
2858
+ propagate_positions: Union[bool, str]
2859
+ maybe_placeholders: bool
2860
+ cache: Union[bool, str]
2861
+ cache_grammar: bool
2862
+ regex: bool
2863
+ g_regex_flags: int
2864
+ keep_all_tokens: bool
2865
+ tree_class: Optional[Callable[[str, List], Any]]
2866
+ parser: _ParserArgType
2867
+ lexer: _LexerArgType
2868
+ ambiguity: 'Literal["auto", "resolve", "explicit", "forest"]'
2869
+ postlex: Optional[PostLex]
2870
+ priority: 'Optional[Literal["auto", "normal", "invert"]]'
2871
+ lexer_callbacks: Dict[str, Callable[[Token], Token]]
2872
+ use_bytes: bool
2873
+ ordered_sets: bool
2874
+ edit_terminals: Optional[Callable[[TerminalDef], TerminalDef]]
2875
+ import_paths: 'List[Union[str, Callable[[Union[None, str, PackageResource], str], Tuple[str, str]]]]'
2876
+ source_path: Optional[str]
2877
+
2878
+ OPTIONS_DOC = r"""
2879
+ **=== General Options ===**
2880
+
2881
+ start
2882
+ The start symbol. Either a string, or a list of strings for multiple possible starts (Default: "start")
2883
+ debug
2884
+ Display debug information and extra warnings. Use only when debugging (Default: ``False``)
2885
+ When used with Earley, it generates a forest graph as "sppf.png", if 'dot' is installed.
2886
+ strict
2887
+ Throw an exception on any potential ambiguity, including shift/reduce conflicts, and regex collisions.
2888
+ transformer
2889
+ Applies the transformer to every parse tree (equivalent to applying it after the parse, but faster)
2890
+ propagate_positions
2891
+ Propagates positional attributes into the 'meta' attribute of all tree branches.
2892
+ Sets attributes: (line, column, end_line, end_column, start_pos, end_pos,
2893
+ container_line, container_column, container_end_line, container_end_column)
2894
+ Accepts ``False``, ``True``, or a callable, which will filter which nodes to ignore when propagating.
2895
+ maybe_placeholders
2896
+ When ``True``, the ``[]`` operator returns ``None`` when not matched.
2897
+ When ``False``, ``[]`` behaves like the ``?`` operator, and returns no value at all.
2898
+ (default= ``True``)
2899
+ cache
2900
+ Cache the results of the Lark grammar analysis, for x2 to x3 faster loading. LALR only for now.
2901
+
2902
+ - When ``False``, does nothing (default)
2903
+ - When ``True``, caches to a temporary file in the local directory
2904
+ - When given a string, caches to the path pointed by the string
2905
+ cache_grammar
2906
+ For use with ``cache`` option. When ``True``, the unanalyzed grammar is also included in the cache.
2907
+ Useful for classes that require the ``Lark.grammar`` to be present (e.g. Reconstructor).
2908
+ (default= ``False``)
2909
+ regex
2910
+ When True, uses the ``regex`` module instead of the stdlib ``re``.
2911
+ g_regex_flags
2912
+ Flags that are applied to all terminals (both regex and strings)
2913
+ keep_all_tokens
2914
+ Prevent the tree builder from automagically removing "punctuation" tokens (Default: ``False``)
2915
+ tree_class
2916
+ Lark will produce trees comprised of instances of this class instead of the default ``lark.Tree``.
2917
+
2918
+ **=== Algorithm Options ===**
2919
+
2920
+ parser
2921
+ Decides which parser engine to use. Accepts "earley" or "lalr". (Default: "earley").
2922
+ (there is also a "cyk" option for legacy)
2923
+ lexer
2924
+ Decides whether or not to use a lexer stage
2925
+
2926
+ - "auto" (default): Choose for me based on the parser
2927
+ - "basic": Use a basic lexer
2928
+ - "contextual": Stronger lexer (only works with parser="lalr")
2929
+ - "dynamic": Flexible and powerful (only with parser="earley")
2930
+ - "dynamic_complete": Same as dynamic, but tries *every* variation of tokenizing possible.
2931
+ ambiguity
2932
+ Decides how to handle ambiguity in the parse. Only relevant if parser="earley"
2933
+
2934
+ - "resolve": The parser will automatically choose the simplest derivation
2935
+ (it chooses consistently: greedy for tokens, non-greedy for rules)
2936
+ - "explicit": The parser will return all derivations wrapped in "_ambig" tree nodes (i.e. a forest).
2937
+ - "forest": The parser will return the root of the shared packed parse forest.
2938
+
2939
+ **=== Misc. / Domain Specific Options ===**
2940
+
2941
+ postlex
2942
+ Lexer post-processing (Default: ``None``) Only works with the basic and contextual lexers.
2943
+ priority
2944
+ How priorities should be evaluated - "auto", ``None``, "normal", "invert" (Default: "auto")
2945
+ lexer_callbacks
2946
+ Dictionary of callbacks for the lexer. May alter tokens during lexing. Use with caution.
2947
+ use_bytes
2948
+ Accept an input of type ``bytes`` instead of ``str``.
2949
+ ordered_sets
2950
+ Should Earley use ordered-sets to achieve stable output (~10% slower than regular sets. Default: True)
2951
+ edit_terminals
2952
+ A callback for editing the terminals before parse.
2953
+ import_paths
2954
+ A List of either paths or loader functions to specify from where grammars are imported
2955
+ source_path
2956
+ Override the source of from where the grammar was loaded. Useful for relative imports and unconventional grammar loading
2957
+ **=== End of Options ===**
2958
+ """
2959
+ if __doc__:
2960
+ __doc__ += OPTIONS_DOC
2961
+
2962
+
2963
+ ##
2964
+
2965
+ ##
2966
+
2967
+ ##
2968
+
2969
+ ##
2970
+
2971
+ ##
2972
+
2973
+ ##
2974
+
2975
+ _defaults: Dict[str, Any] = {
2976
+ 'debug': False,
2977
+ 'strict': False,
2978
+ 'keep_all_tokens': False,
2979
+ 'tree_class': None,
2980
+ 'cache': False,
2981
+ 'cache_grammar': False,
2982
+ 'postlex': None,
2983
+ 'parser': 'earley',
2984
+ 'lexer': 'auto',
2985
+ 'transformer': None,
2986
+ 'start': 'start',
2987
+ 'priority': 'auto',
2988
+ 'ambiguity': 'auto',
2989
+ 'regex': False,
2990
+ 'propagate_positions': False,
2991
+ 'lexer_callbacks': {},
2992
+ 'maybe_placeholders': True,
2993
+ 'edit_terminals': None,
2994
+ 'g_regex_flags': 0,
2995
+ 'use_bytes': False,
2996
+ 'ordered_sets': True,
2997
+ 'import_paths': [],
2998
+ 'source_path': None,
2999
+ '_plugins': {},
3000
+ }
3001
+
3002
+ def __init__(self, options_dict: Dict[str, Any]) -> None:
3003
+ o = dict(options_dict)
3004
+
3005
+ options = {}
3006
+ for name, default in self._defaults.items():
3007
+ if name in o:
3008
+ value = o.pop(name)
3009
+ if isinstance(default, bool) and name not in ('cache', 'use_bytes', 'propagate_positions'):
3010
+ value = bool(value)
3011
+ else:
3012
+ value = default
3013
+
3014
+ options[name] = value
3015
+
3016
+ if isinstance(options['start'], str):
3017
+ options['start'] = [options['start']]
3018
+
3019
+ self.__dict__['options'] = options
3020
+
3021
+
3022
+ assert_config(self.parser, ('earley', 'lalr', 'cyk', None))
3023
+
3024
+ if self.parser == 'earley' and self.transformer:
3025
+ raise ConfigurationError('Cannot specify an embedded transformer when using the Earley algorithm. '
3026
+ 'Please use your transformer on the resulting parse tree, or use a different algorithm (i.e. LALR)')
3027
+
3028
+ if self.cache_grammar and not self.cache:
3029
+ raise ConfigurationError('cache_grammar cannot be set when cache is disabled')
3030
+
3031
+ if o:
3032
+ raise ConfigurationError("Unknown options: %s" % o.keys())
3033
+
3034
+ def __getattr__(self, name: str) -> Any:
3035
+ try:
3036
+ return self.__dict__['options'][name]
3037
+ except KeyError as e:
3038
+ raise AttributeError(e)
3039
+
3040
+ def __setattr__(self, name: str, value: str) -> None:
3041
+ assert_config(name, self.options.keys(), "%r isn't a valid option. Expected one of: %s")
3042
+ self.options[name] = value
3043
+
3044
+ def serialize(self, memo = None) -> Dict[str, Any]:
3045
+ return self.options
3046
+
3047
+ @classmethod
3048
+ def deserialize(cls, data: Dict[str, Any], memo: Dict[int, Union[TerminalDef, Rule]]) -> "LarkOptions":
3049
+ return cls(data)
3050
+
3051
+
3052
+ ##
3053
+
3054
+ ##
3055
+
3056
+ _LOAD_ALLOWED_OPTIONS = {'postlex', 'transformer', 'lexer_callbacks', 'use_bytes', 'debug', 'g_regex_flags', 'regex', 'propagate_positions', 'tree_class', '_plugins'}
3057
+
3058
+ _VALID_PRIORITY_OPTIONS = ('auto', 'normal', 'invert', None)
3059
+ _VALID_AMBIGUITY_OPTIONS = ('auto', 'resolve', 'explicit', 'forest')
3060
+
3061
+
3062
+ _T = TypeVar('_T', bound="Lark")
3063
+
3064
+ class Lark(Serialize):
3065
+ #--
3066
+
3067
+ source_path: str
3068
+ source_grammar: str
3069
+ grammar: 'Grammar'
3070
+ options: LarkOptions
3071
+ lexer: Lexer
3072
+ parser: 'ParsingFrontend'
3073
+ terminals: Collection[TerminalDef]
3074
+
3075
+ __serialize_fields__ = ['parser', 'rules', 'options']
3076
+
3077
+ def __init__(self, grammar: 'Union[Grammar, str, IO[str]]', **options) -> None:
3078
+ self.options = LarkOptions(options)
3079
+ re_module: types.ModuleType
3080
+
3081
+ ##
3082
+
3083
+ if self.options.cache_grammar:
3084
+ self.__serialize_fields__ = self.__serialize_fields__ + ['grammar']
3085
+
3086
+ ##
3087
+
3088
+ use_regex = self.options.regex
3089
+ if use_regex:
3090
+ if _has_regex:
3091
+ re_module = regex
3092
+ else:
3093
+ raise ImportError('`regex` module must be installed if calling `Lark(regex=True)`.')
3094
+ else:
3095
+ re_module = re
3096
+
3097
+ ##
3098
+
3099
+ if self.options.source_path is None:
3100
+ try:
3101
+ self.source_path = grammar.name ##
3102
+
3103
+ except AttributeError:
3104
+ self.source_path = '<string>'
3105
+ else:
3106
+ self.source_path = self.options.source_path
3107
+
3108
+ ##
3109
+
3110
+ try:
3111
+ read = grammar.read ##
3112
+
3113
+ except AttributeError:
3114
+ pass
3115
+ else:
3116
+ grammar = read()
3117
+
3118
+ cache_fn = None
3119
+ cache_sha256 = None
3120
+ if isinstance(grammar, str):
3121
+ self.source_grammar = grammar
3122
+ if self.options.use_bytes:
3123
+ if not grammar.isascii():
3124
+ raise ConfigurationError("Grammar must be ascii only, when use_bytes=True")
3125
+
3126
+ if self.options.cache:
3127
+ if self.options.parser != 'lalr':
3128
+ raise ConfigurationError("cache only works with parser='lalr' for now")
3129
+
3130
+ unhashable = ('transformer', 'postlex', 'lexer_callbacks', 'edit_terminals', '_plugins')
3131
+ options_str = ''.join(k+str(v) for k, v in options.items() if k not in unhashable)
3132
+ from . import __version__
3133
+ s = grammar + options_str + __version__ + str(sys.version_info[:2])
3134
+ cache_sha256 = sha256_digest(s)
3135
+
3136
+ if isinstance(self.options.cache, str):
3137
+ cache_fn = self.options.cache
3138
+ else:
3139
+ if self.options.cache is not True:
3140
+ raise ConfigurationError("cache argument must be bool or str")
3141
+
3142
+ try:
3143
+ username = getpass.getuser()
3144
+ except Exception:
3145
+ ##
3146
+
3147
+ ##
3148
+
3149
+ ##
3150
+
3151
+ username = "unknown"
3152
+
3153
+
3154
+ cache_fn = tempfile.gettempdir() + "/.lark_%s_%s_%s_%s_%s.tmp" % (
3155
+ "cache_grammar" if self.options.cache_grammar else "cache", username, cache_sha256, *sys.version_info[:2])
3156
+
3157
+ old_options = self.options
3158
+ try:
3159
+ with FS.open(cache_fn, 'rb') as f:
3160
+ logger.debug('Loading grammar from cache: %s', cache_fn)
3161
+ ##
3162
+
3163
+ for name in (set(options) - _LOAD_ALLOWED_OPTIONS):
3164
+ del options[name]
3165
+ file_sha256 = f.readline().rstrip(b'\n')
3166
+ cached_used_files = pickle.load(f)
3167
+ if file_sha256 == cache_sha256.encode('utf8') and verify_used_files(cached_used_files):
3168
+ cached_parser_data = pickle.load(f)
3169
+ self._load(cached_parser_data, **options)
3170
+ return
3171
+ except FileNotFoundError:
3172
+ ##
3173
+
3174
+ pass
3175
+ except Exception: ##
3176
+
3177
+ logger.exception("Failed to load Lark from cache: %r. We will try to carry on.", cache_fn)
3178
+
3179
+ ##
3180
+
3181
+ ##
3182
+
3183
+ self.options = old_options
3184
+
3185
+
3186
+ ##
3187
+
3188
+ self.grammar, used_files = load_grammar(grammar, self.source_path, self.options.import_paths, self.options.keep_all_tokens)
3189
+ else:
3190
+ assert isinstance(grammar, Grammar)
3191
+ self.grammar = grammar
3192
+
3193
+
3194
+ if self.options.lexer == 'auto':
3195
+ if self.options.parser == 'lalr':
3196
+ self.options.lexer = 'contextual'
3197
+ elif self.options.parser == 'earley':
3198
+ if self.options.postlex is not None:
3199
+ logger.info("postlex can't be used with the dynamic lexer, so we use 'basic' instead. "
3200
+ "Consider using lalr with contextual instead of earley")
3201
+ self.options.lexer = 'basic'
3202
+ else:
3203
+ self.options.lexer = 'dynamic'
3204
+ elif self.options.parser == 'cyk':
3205
+ self.options.lexer = 'basic'
3206
+ else:
3207
+ assert False, self.options.parser
3208
+ lexer = self.options.lexer
3209
+ if isinstance(lexer, type):
3210
+ assert issubclass(lexer, Lexer) ##
3211
+
3212
+ else:
3213
+ assert_config(lexer, ('basic', 'contextual', 'dynamic', 'dynamic_complete'))
3214
+ if self.options.postlex is not None and 'dynamic' in lexer:
3215
+ raise ConfigurationError("Can't use postlex with a dynamic lexer. Use basic or contextual instead")
3216
+
3217
+ if self.options.ambiguity == 'auto':
3218
+ if self.options.parser == 'earley':
3219
+ self.options.ambiguity = 'resolve'
3220
+ else:
3221
+ assert_config(self.options.parser, ('earley', 'cyk'), "%r doesn't support disambiguation. Use one of these parsers instead: %s")
3222
+
3223
+ if self.options.priority == 'auto':
3224
+ self.options.priority = 'normal'
3225
+
3226
+ if self.options.priority not in _VALID_PRIORITY_OPTIONS:
3227
+ raise ConfigurationError("invalid priority option: %r. Must be one of %r" % (self.options.priority, _VALID_PRIORITY_OPTIONS))
3228
+ if self.options.ambiguity not in _VALID_AMBIGUITY_OPTIONS:
3229
+ raise ConfigurationError("invalid ambiguity option: %r. Must be one of %r" % (self.options.ambiguity, _VALID_AMBIGUITY_OPTIONS))
3230
+
3231
+ if self.options.parser is None:
3232
+ terminals_to_keep = '*' ##
3233
+
3234
+ elif self.options.postlex is not None:
3235
+ terminals_to_keep = set(self.options.postlex.always_accept)
3236
+ else:
3237
+ terminals_to_keep = set()
3238
+
3239
+ ##
3240
+
3241
+ self.terminals, self.rules, self.ignore_tokens = self.grammar.compile(self.options.start, terminals_to_keep)
3242
+
3243
+ if self.options.edit_terminals:
3244
+ for t in self.terminals:
3245
+ self.options.edit_terminals(t)
3246
+
3247
+ self._terminals_dict = {t.name: t for t in self.terminals}
3248
+
3249
+ ##
3250
+
3251
+ if self.options.priority == 'invert':
3252
+ for rule in self.rules:
3253
+ if rule.options.priority is not None:
3254
+ rule.options.priority = -rule.options.priority
3255
+ for term in self.terminals:
3256
+ term.priority = -term.priority
3257
+ ##
3258
+
3259
+ ##
3260
+
3261
+ ##
3262
+
3263
+ elif self.options.priority is None:
3264
+ for rule in self.rules:
3265
+ if rule.options.priority is not None:
3266
+ rule.options.priority = None
3267
+ for term in self.terminals:
3268
+ term.priority = 0
3269
+
3270
+ ##
3271
+
3272
+ self.lexer_conf = LexerConf(
3273
+ self.terminals, re_module, self.ignore_tokens, self.options.postlex,
3274
+ self.options.lexer_callbacks, self.options.g_regex_flags, use_bytes=self.options.use_bytes, strict=self.options.strict
3275
+ )
3276
+
3277
+ if self.options.parser:
3278
+ self.parser = self._build_parser()
3279
+ elif lexer:
3280
+ self.lexer = self._build_lexer()
3281
+
3282
+ if cache_fn:
3283
+ logger.debug('Saving grammar to cache: %s', cache_fn)
3284
+ try:
3285
+ with FS.open(cache_fn, 'wb') as f:
3286
+ assert cache_sha256 is not None
3287
+ f.write(cache_sha256.encode('utf8') + b'\n')
3288
+ pickle.dump(used_files, f)
3289
+ self.save(f, _LOAD_ALLOWED_OPTIONS)
3290
+ except IOError as e:
3291
+ logger.exception("Failed to save Lark to cache: %r.", cache_fn, e)
3292
+
3293
+ if __doc__:
3294
+ __doc__ += "\n\n" + LarkOptions.OPTIONS_DOC
3295
+
3296
+ def _build_lexer(self, dont_ignore: bool=False) -> BasicLexer:
3297
+ lexer_conf = self.lexer_conf
3298
+ if dont_ignore:
3299
+ from copy import copy
3300
+ lexer_conf = copy(lexer_conf)
3301
+ lexer_conf.ignore = ()
3302
+ return BasicLexer(lexer_conf)
3303
+
3304
+ def _prepare_callbacks(self) -> None:
3305
+ self._callbacks = {}
3306
+ ##
3307
+
3308
+ if self.options.ambiguity != 'forest':
3309
+ self._parse_tree_builder = ParseTreeBuilder(
3310
+ self.rules,
3311
+ self.options.tree_class or Tree,
3312
+ self.options.propagate_positions,
3313
+ self.options.parser != 'lalr' and self.options.ambiguity == 'explicit',
3314
+ self.options.maybe_placeholders
3315
+ )
3316
+ self._callbacks = self._parse_tree_builder.create_callback(self.options.transformer)
3317
+ self._callbacks.update(_get_lexer_callbacks(self.options.transformer, self.terminals))
3318
+
3319
+ def _build_parser(self) -> "ParsingFrontend":
3320
+ self._prepare_callbacks()
3321
+ _validate_frontend_args(self.options.parser, self.options.lexer)
3322
+ parser_conf = ParserConf(self.rules, self._callbacks, self.options.start)
3323
+ return _construct_parsing_frontend(
3324
+ self.options.parser,
3325
+ self.options.lexer,
3326
+ self.lexer_conf,
3327
+ parser_conf,
3328
+ options=self.options
3329
+ )
3330
+
3331
+ def save(self, f, exclude_options: Collection[str] = ()) -> None:
3332
+ #--
3333
+ if self.options.parser != 'lalr':
3334
+ raise NotImplementedError("Lark.save() is only implemented for the LALR(1) parser.")
3335
+ data, m = self.memo_serialize([TerminalDef, Rule])
3336
+ if exclude_options:
3337
+ data["options"] = {n: v for n, v in data["options"].items() if n not in exclude_options}
3338
+ pickle.dump({'data': data, 'memo': m}, f, protocol=pickle.HIGHEST_PROTOCOL)
3339
+
3340
+ @classmethod
3341
+ def load(cls: Type[_T], f) -> _T:
3342
+ #--
3343
+ inst = cls.__new__(cls)
3344
+ return inst._load(f)
3345
+
3346
+ def _deserialize_lexer_conf(self, data: Dict[str, Any], memo: Dict[int, Union[TerminalDef, Rule]], options: LarkOptions) -> LexerConf:
3347
+ lexer_conf = LexerConf.deserialize(data['lexer_conf'], memo)
3348
+ lexer_conf.callbacks = options.lexer_callbacks or {}
3349
+ lexer_conf.re_module = regex if options.regex else re
3350
+ lexer_conf.use_bytes = options.use_bytes
3351
+ lexer_conf.g_regex_flags = options.g_regex_flags
3352
+ lexer_conf.skip_validation = True
3353
+ lexer_conf.postlex = options.postlex
3354
+ return lexer_conf
3355
+
3356
+ def _load(self: _T, f: Any, **kwargs) -> _T:
3357
+ if isinstance(f, dict):
3358
+ d = f
3359
+ else:
3360
+ d = pickle.load(f)
3361
+ memo_json = d['memo']
3362
+ data = d['data']
3363
+
3364
+ assert memo_json
3365
+ memo = SerializeMemoizer.deserialize(memo_json, {'Rule': Rule, 'TerminalDef': TerminalDef}, {})
3366
+ if 'grammar' in data:
3367
+ self.grammar = Grammar.deserialize(data['grammar'], memo)
3368
+ options = dict(data['options'])
3369
+ if (set(kwargs) - _LOAD_ALLOWED_OPTIONS) & set(LarkOptions._defaults):
3370
+ raise ConfigurationError("Some options are not allowed when loading a Parser: {}"
3371
+ .format(set(kwargs) - _LOAD_ALLOWED_OPTIONS))
3372
+ options.update(kwargs)
3373
+ self.options = LarkOptions.deserialize(options, memo)
3374
+ self.rules = [Rule.deserialize(r, memo) for r in data['rules']]
3375
+ self.source_path = '<deserialized>'
3376
+ _validate_frontend_args(self.options.parser, self.options.lexer)
3377
+ self.lexer_conf = self._deserialize_lexer_conf(data['parser'], memo, self.options)
3378
+ self.terminals = self.lexer_conf.terminals
3379
+ self._prepare_callbacks()
3380
+ self._terminals_dict = {t.name: t for t in self.terminals}
3381
+ self.parser = _deserialize_parsing_frontend(
3382
+ data['parser'],
3383
+ memo,
3384
+ self.lexer_conf,
3385
+ self._callbacks,
3386
+ self.options, ##
3387
+
3388
+ )
3389
+ return self
3390
+
3391
+ @classmethod
3392
+ def _load_from_dict(cls, data, memo, **kwargs):
3393
+ inst = cls.__new__(cls)
3394
+ return inst._load({'data': data, 'memo': memo}, **kwargs)
3395
+
3396
+ @classmethod
3397
+ def open(cls: Type[_T], grammar_filename: str, rel_to: Optional[str]=None, **options) -> _T:
3398
+ #--
3399
+ if rel_to:
3400
+ basepath = os.path.dirname(rel_to)
3401
+ grammar_filename = os.path.join(basepath, grammar_filename)
3402
+ with open(grammar_filename, encoding='utf8') as f:
3403
+ return cls(f, **options)
3404
+
3405
+ @classmethod
3406
+ def open_from_package(cls: Type[_T], package: str, grammar_path: str, search_paths: 'Sequence[str]'=[""], **options) -> _T:
3407
+ #--
3408
+ package_loader = FromPackageLoader(package, search_paths)
3409
+ full_path, text = package_loader(None, grammar_path)
3410
+ options.setdefault('source_path', full_path)
3411
+ options.setdefault('import_paths', [])
3412
+ options['import_paths'].append(package_loader)
3413
+ return cls(text, **options)
3414
+
3415
+ def __repr__(self):
3416
+ return 'Lark(open(%r), parser=%r, lexer=%r, ...)' % (self.source_path, self.options.parser, self.options.lexer)
3417
+
3418
+
3419
+ def lex(self, text: TextOrSlice, dont_ignore: bool=False) -> Iterator[Token]:
3420
+ #--
3421
+ lexer: Lexer
3422
+ if not hasattr(self, 'lexer') or dont_ignore:
3423
+ lexer = self._build_lexer(dont_ignore)
3424
+ else:
3425
+ lexer = self.lexer
3426
+ lexer_thread = LexerThread.from_text(lexer, text)
3427
+ stream = lexer_thread.lex(None)
3428
+ if self.options.postlex:
3429
+ return self.options.postlex.process(stream)
3430
+ return stream
3431
+
3432
+ def get_terminal(self, name: str) -> TerminalDef:
3433
+ #--
3434
+ return self._terminals_dict[name]
3435
+
3436
+ def parse_interactive(self, text: Optional[LarkInput]=None, start: Optional[str]=None) -> 'InteractiveParser':
3437
+ #--
3438
+ return self.parser.parse_interactive(text, start=start)
3439
+
3440
+ def parse(self, text: LarkInput, start: Optional[str]=None, on_error: 'Optional[Callable[[UnexpectedInput], bool]]'=None) -> 'ParseTree':
3441
+ #--
3442
+ if on_error is not None and self.options.parser != 'lalr':
3443
+ raise NotImplementedError("The on_error option is only implemented for the LALR(1) parser.")
3444
+ return self.parser.parse(text, start=start, on_error=on_error)
3445
+
3446
+
3447
+
3448
+
3449
+ class DedentError(LarkError):
3450
+ pass
3451
+
3452
+ class Indenter(PostLex, ABC):
3453
+ #--
3454
+ paren_level: int
3455
+ indent_level: List[int]
3456
+
3457
+ def __init__(self) -> None:
3458
+ self.paren_level = 0
3459
+ self.indent_level = [0]
3460
+ assert self.tab_len > 0
3461
+
3462
+ def handle_NL(self, token: Token) -> Iterator[Token]:
3463
+ if self.paren_level > 0:
3464
+ return
3465
+
3466
+ yield token
3467
+
3468
+ indent_str = token.rsplit('\n', 1)[1] ##
3469
+
3470
+ indent = indent_str.count(' ') + indent_str.count('\t') * self.tab_len
3471
+
3472
+ if indent > self.indent_level[-1]:
3473
+ self.indent_level.append(indent)
3474
+ yield Token.new_borrow_pos(self.INDENT_type, indent_str, token)
3475
+ else:
3476
+ while indent < self.indent_level[-1]:
3477
+ self.indent_level.pop()
3478
+ yield Token.new_borrow_pos(self.DEDENT_type, indent_str, token)
3479
+
3480
+ if indent != self.indent_level[-1]:
3481
+ raise DedentError('Unexpected dedent to column %s. Expected dedent to %s' % (indent, self.indent_level[-1]))
3482
+
3483
+ def _process(self, stream):
3484
+ token = None
3485
+ for token in stream:
3486
+ if token.type == self.NL_type:
3487
+ yield from self.handle_NL(token)
3488
+ else:
3489
+ yield token
3490
+
3491
+ if token.type in self.OPEN_PAREN_types:
3492
+ self.paren_level += 1
3493
+ elif token.type in self.CLOSE_PAREN_types:
3494
+ self.paren_level -= 1
3495
+ assert self.paren_level >= 0
3496
+
3497
+ while len(self.indent_level) > 1:
3498
+ self.indent_level.pop()
3499
+ yield Token.new_borrow_pos(self.DEDENT_type, '', token) if token else Token(self.DEDENT_type, '', 0, 0, 0, 0, 0, 0)
3500
+
3501
+ assert self.indent_level == [0], self.indent_level
3502
+
3503
+ def process(self, stream):
3504
+ self.paren_level = 0
3505
+ self.indent_level = [0]
3506
+ return self._process(stream)
3507
+
3508
+ ##
3509
+
3510
+ @property
3511
+ def always_accept(self):
3512
+ return (self.NL_type,)
3513
+
3514
+ @property
3515
+ @abstractmethod
3516
+ def NL_type(self) -> str:
3517
+ #--
3518
+ raise NotImplementedError()
3519
+
3520
+ @property
3521
+ @abstractmethod
3522
+ def OPEN_PAREN_types(self) -> List[str]:
3523
+ #--
3524
+ raise NotImplementedError()
3525
+
3526
+ @property
3527
+ @abstractmethod
3528
+ def CLOSE_PAREN_types(self) -> List[str]:
3529
+ #--
3530
+ raise NotImplementedError()
3531
+
3532
+ @property
3533
+ @abstractmethod
3534
+ def INDENT_type(self) -> str:
3535
+ #--
3536
+ raise NotImplementedError()
3537
+
3538
+ @property
3539
+ @abstractmethod
3540
+ def DEDENT_type(self) -> str:
3541
+ #--
3542
+ raise NotImplementedError()
3543
+
3544
+ @property
3545
+ @abstractmethod
3546
+ def tab_len(self) -> int:
3547
+ #--
3548
+ raise NotImplementedError()
3549
+
3550
+
3551
+ class PythonIndenter(Indenter):
3552
+ #--
3553
+
3554
+ NL_type = '_NEWLINE'
3555
+ OPEN_PAREN_types = ['LPAR', 'LSQB', 'LBRACE']
3556
+ CLOSE_PAREN_types = ['RPAR', 'RSQB', 'RBRACE']
3557
+ INDENT_type = '_INDENT'
3558
+ DEDENT_type = '_DEDENT'
3559
+ tab_len = 8
3560
+
3561
+
3562
+ import pickle, zlib, base64
3563
+ DATA = (
3564
+ {'parser': {'lexer_conf': {'terminals': [{'@': 0}, {'@': 1}, {'@': 2}, {'@': 3}, {'@': 4}, {'@': 5}, {'@': 6}, {'@': 7}, {'@': 8}, {'@': 9}, {'@': 10}, {'@': 11}, {'@': 12}, {'@': 13}, {'@': 14}, {'@': 15}, {'@': 16}, {'@': 17}, {'@': 18}, {'@': 19}, {'@': 20}, {'@': 21}], 'ignore': ['WS'], 'g_regex_flags': 0, 'use_bytes': False, 'lexer_type': 'contextual', '__type__': 'LexerConf'}, 'parser_conf': {'rules': [{'@': 22}, {'@': 23}, {'@': 24}, {'@': 25}, {'@': 26}, {'@': 27}, {'@': 28}, {'@': 29}, {'@': 30}, {'@': 31}, {'@': 32}, {'@': 33}, {'@': 34}, {'@': 35}, {'@': 36}, {'@': 37}, {'@': 38}, {'@': 39}, {'@': 40}, {'@': 41}, {'@': 42}, {'@': 43}, {'@': 44}, {'@': 45}, {'@': 46}, {'@': 47}, {'@': 48}, {'@': 49}, {'@': 50}, {'@': 51}, {'@': 52}, {'@': 53}, {'@': 54}, {'@': 55}, {'@': 56}, {'@': 57}, {'@': 58}, {'@': 59}, {'@': 60}, {'@': 61}, {'@': 62}, {'@': 63}, {'@': 64}, {'@': 65}, {'@': 66}, {'@': 67}, {'@': 68}], 'start': ['start'], 'parser_type': 'lalr', '__type__': 'ParserConf'}, 'parser': {'tokens': {0: '__ANON_1', 1: '$END', 2: 'QMARK', 3: 'RPAR', 4: 'COMMA', 5: 'COLON', 6: '__ANON_0', 7: '__ANON_2', 8: 'MORETHAN', 9: 'PLUS', 10: 'DIV', 11: '__ANON_5', 12: 'MINUS', 13: '__ANON_3', 14: 'LESSTHAN', 15: 'STAR', 16: '__ANON_4', 17: 'POWER', 18: 'NAME', 19: 'LPAR', 20: 'product', 21: 'comparison_expr', 22: 'func_call', 23: 'sum', 24: 'atom', 25: 'NUMBER', 26: 'power', 27: 'add_op', 28: 'logical_and_expr', 29: '__arguments_star_5', 30: 'logical_or_expr', 31: 'ternary_expr', 32: 'expression', 33: '__logical_and_expr_star_1', 34: '__sum_star_2', 35: 'arguments', 36: '__power_star_4', 37: 'mul_op', 38: 'DOT', 39: 'start', 40: '__logical_or_expr_star_0', 41: '__product_star_3'}, 'states': {0: {0: (0, 4), 1: (1, {'@': 28}), 2: (1, {'@': 28}), 3: (1, {'@': 28}), 4: (1, {'@': 28}), 5: (1, {'@': 28}), 6: (1, {'@': 28})}, 1: {1: (1, {'@': 54}), 5: (1, {'@': 54}), 7: (1, {'@': 54}), 8: (1, {'@': 54}), 3: (1, {'@': 54}), 0: (1, {'@': 54}), 9: (1, {'@': 54}), 10: (1, {'@': 54}), 11: (1, {'@': 54}), 2: (1, {'@': 54}), 4: (1, {'@': 54}), 12: (1, {'@': 54}), 13: (1, {'@': 54}), 14: (1, {'@': 54}), 15: (1, {'@': 54}), 6: (1, {'@': 54}), 16: (1, {'@': 54}), 17: (1, {'@': 54})}, 2: {1: (1, {'@': 64}), 5: (1, {'@': 64}), 7: (1, {'@': 64}), 8: (1, {'@': 64}), 6: (1, {'@': 64}), 0: (1, {'@': 64}), 9: (1, {'@': 64}), 11: (1, {'@': 64}), 2: (1, {'@': 64}), 4: (1, {'@': 64}), 12: (1, {'@': 64}), 13: (1, {'@': 64}), 14: (1, {'@': 64}), 15: (1, {'@': 64}), 3: (1, {'@': 64}), 16: (1, {'@': 64}), 10: (1, {'@': 64})}, 3: {1: (1, {'@': 63}), 5: (1, {'@': 63}), 7: (1, {'@': 63}), 8: (1, {'@': 63}), 6: (1, {'@': 63}), 0: (1, {'@': 63}), 9: (1, {'@': 63}), 11: (1, {'@': 63}), 2: (1, {'@': 63}), 4: (1, {'@': 63}), 12: (1, {'@': 63}), 13: (1, {'@': 63}), 14: (1, {'@': 63}), 15: (1, {'@': 63}), 3: (1, {'@': 63}), 16: (1, {'@': 63}), 10: (1, {'@': 63})}, 4: {18: (0, 65), 12: (0, 37), 19: (0, 41), 20: (0, 27), 21: (0, 53), 22: (0, 30), 23: (0, 24), 24: (0, 55), 25: (0, 29), 26: (0, 75)}, 5: {6: (0, 11), 1: (1, {'@': 26}), 2: (1, {'@': 26}), 5: (1, {'@': 26}), 4: (1, {'@': 26}), 3: (1, {'@': 26})}, 6: {1: (1, {'@': 43}), 5: (1, {'@': 43}), 7: (1, {'@': 43}), 8: (1, {'@': 43}), 3: (1, {'@': 43}), 0: (1, {'@': 43}), 9: (1, {'@': 43}), 10: (1, {'@': 43}), 11: (1, {'@': 43}), 2: (1, {'@': 43}), 4: (1, {'@': 43}), 12: (1, {'@': 43}), 13: (1, {'@': 43}), 14: (1, {'@': 43}), 15: (1, {'@': 43}), 6: (1, {'@': 43}), 16: (1, {'@': 43}), 17: (1, {'@': 43})}, 7: {18: (0, 65), 26: (0, 75), 24: (0, 55), 23: (0, 71), 12: (0, 37), 19: (0, 41), 20: (0, 27), 25: (0, 29), 22: (0, 30)}, 8: {9: (0, 56), 27: (0, 12), 12: (0, 32), 1: (1, {'@': 37}), 11: (1, {'@': 37}), 2: (1, {'@': 37}), 4: (1, {'@': 37}), 5: (1, {'@': 37}), 7: (1, {'@': 37}), 13: (1, {'@': 37}), 14: (1, {'@': 37}), 8: (1, {'@': 37}), 6: (1, {'@': 37}), 3: (1, {'@': 37}), 0: (1, {'@': 37}), 16: (1, {'@': 37})}, 9: {18: (0, 65), 12: (0, 37), 19: (0, 41), 25: (0, 29), 22: (0, 30), 24: (0, 19)}, 10: {1: (1, {'@': 22})}, 11: {21: (0, 26), 18: (0, 65), 12: (0, 37), 19: (0, 41), 20: (0, 27), 22: (0, 30), 23: (0, 24), 24: (0, 55), 28: (0, 68), 25: (0, 29), 26: (0, 75)}, 12: {18: (0, 65), 26: (0, 75), 24: (0, 55), 12: (0, 37), 20: (0, 33), 19: (0, 41), 25: (0, 29), 22: (0, 30)}, 13: {29: (0, 20), 4: (0, 23), 3: (1, {'@': 56})}, 14: {1: (1, {'@': 61}), 5: (1, {'@': 61}), 7: (1, {'@': 61}), 8: (1, {'@': 61}), 3: (1, {'@': 61}), 0: (1, {'@': 61}), 9: (1, {'@': 61}), 11: (1, {'@': 61}), 2: (1, {'@': 61}), 4: (1, {'@': 61}), 12: (1, {'@': 61}), 13: (1, {'@': 61}), 14: (1, {'@': 61}), 6: (1, {'@': 61}), 16: (1, {'@': 61})}, 15: {21: (0, 26), 18: (0, 65), 28: (0, 73), 12: (0, 37), 19: (0, 41), 20: (0, 27), 22: (0, 30), 30: (0, 21), 23: (0, 24), 24: (0, 55), 25: (0, 29), 26: (0, 75), 31: (0, 16)}, 16: {1: (1, {'@': 24}), 3: (1, {'@': 24}), 4: (1, {'@': 24}), 5: (1, {'@': 24})}, 17: {}, 18: {4: (1, {'@': 67}), 3: (1, {'@': 67})}, 19: {1: (1, {'@': 65}), 5: (1, {'@': 65}), 7: (1, {'@': 65}), 8: (1, {'@': 65}), 3: (1, {'@': 65}), 0: (1, {'@': 65}), 9: (1, {'@': 65}), 11: (1, {'@': 65}), 2: (1, {'@': 65}), 4: (1, {'@': 65}), 12: (1, {'@': 65}), 13: (1, {'@': 65}), 14: (1, {'@': 65}), 15: (1, {'@': 65}), 6: (1, {'@': 65}), 16: (1, {'@': 65}), 10: (1, {'@': 65}), 17: (1, {'@': 65})}, 20: {4: (0, 74), 3: (1, {'@': 55})}, 21: {2: (0, 61), 1: (1, {'@': 25}), 3: (1, {'@': 25}), 4: (1, {'@': 25}), 5: (1, {'@': 25})}, 22: {1: (1, {'@': 57}), 2: (1, {'@': 57}), 4: (1, {'@': 57}), 5: (1, {'@': 57}), 6: (1, {'@': 57}), 3: (1, {'@': 57})}, 23: {21: (0, 26), 18: (0, 65), 28: (0, 73), 12: (0, 37), 31: (0, 38), 19: (0, 41), 20: (0, 27), 22: (0, 30), 30: (0, 21), 23: (0, 24), 24: (0, 55), 32: (0, 18), 25: (0, 29), 26: (0, 75)}, 24: {11: (0, 7), 14: (0, 49), 16: (0, 35), 7: (0, 39), 13: (0, 25), 8: (0, 47), 1: (1, {'@': 36}), 2: (1, {'@': 36}), 3: (1, {'@': 36}), 4: (1, {'@': 36}), 5: (1, {'@': 36}), 6: (1, {'@': 36}), 0: (1, {'@': 36})}, 25: {18: (0, 65), 26: (0, 75), 23: (0, 59), 24: (0, 55), 12: (0, 37), 19: (0, 41), 20: (0, 27), 25: (0, 29), 22: (0, 30)}, 26: {33: (0, 0), 0: (0, 31), 1: (1, {'@': 29}), 2: (1, {'@': 29}), 3: (1, {'@': 29}), 4: (1, {'@': 29}), 5: (1, {'@': 29}), 6: (1, {'@': 29})}, 27: {27: (0, 46), 9: (0, 56), 34: (0, 8), 12: (0, 32), 1: (1, {'@': 38}), 11: (1, {'@': 38}), 2: (1, {'@': 38}), 4: (1, {'@': 38}), 5: (1, {'@': 38}), 7: (1, {'@': 38}), 13: (1, {'@': 38}), 14: (1, {'@': 38}), 8: (1, {'@': 38}), 6: (1, {'@': 38}), 3: (1, {'@': 38}), 0: (1, {'@': 38}), 16: (1, {'@': 38})}, 28: {21: (0, 26), 18: (0, 65), 12: (0, 37), 19: (0, 41), 20: (0, 27), 28: (0, 22), 22: (0, 30), 23: (0, 24), 24: (0, 55), 25: (0, 29), 26: (0, 75)}, 29: {1: (1, {'@': 45}), 5: (1, {'@': 45}), 7: (1, {'@': 45}), 8: (1, {'@': 45}), 3: (1, {'@': 45}), 0: (1, {'@': 45}), 9: (1, {'@': 45}), 10: (1, {'@': 45}), 11: (1, {'@': 45}), 2: (1, {'@': 45}), 4: (1, {'@': 45}), 12: (1, {'@': 45}), 13: (1, {'@': 45}), 14: (1, {'@': 45}), 15: (1, {'@': 45}), 6: (1, {'@': 45}), 16: (1, {'@': 45}), 17: (1, {'@': 45})}, 30: {1: (1, {'@': 44}), 5: (1, {'@': 44}), 7: (1, {'@': 44}), 8: (1, {'@': 44}), 3: (1, {'@': 44}), 0: (1, {'@': 44}), 9: (1, {'@': 44}), 10: (1, {'@': 44}), 11: (1, {'@': 44}), 2: (1, {'@': 44}), 4: (1, {'@': 44}), 12: (1, {'@': 44}), 13: (1, {'@': 44}), 14: (1, {'@': 44}), 15: (1, {'@': 44}), 6: (1, {'@': 44}), 16: (1, {'@': 44}), 17: (1, {'@': 44})}, 31: {18: (0, 65), 12: (0, 37), 19: (0, 41), 20: (0, 27), 22: (0, 30), 23: (0, 24), 24: (0, 55), 25: (0, 29), 26: (0, 75), 21: (0, 42)}, 32: {12: (1, {'@': 50}), 19: (1, {'@': 50}), 18: (1, {'@': 50}), 25: (1, {'@': 50})}, 33: {1: (1, {'@': 62}), 5: (1, {'@': 62}), 7: (1, {'@': 62}), 8: (1, {'@': 62}), 3: (1, {'@': 62}), 0: (1, {'@': 62}), 9: (1, {'@': 62}), 11: (1, {'@': 62}), 2: (1, {'@': 62}), 4: (1, {'@': 62}), 12: (1, {'@': 62}), 13: (1, {'@': 62}), 14: (1, {'@': 62}), 6: (1, {'@': 62}), 16: (1, {'@': 62})}, 34: {18: (0, 36)}, 35: {18: (0, 65), 26: (0, 75), 24: (0, 55), 12: (0, 37), 19: (0, 41), 20: (0, 27), 23: (0, 43), 25: (0, 29), 22: (0, 30)}, 36: {1: (1, {'@': 47}), 5: (1, {'@': 47}), 7: (1, {'@': 47}), 8: (1, {'@': 47}), 3: (1, {'@': 47}), 0: (1, {'@': 47}), 9: (1, {'@': 47}), 10: (1, {'@': 47}), 11: (1, {'@': 47}), 2: (1, {'@': 47}), 4: (1, {'@': 47}), 12: (1, {'@': 47}), 13: (1, {'@': 47}), 14: (1, {'@': 47}), 15: (1, {'@': 47}), 6: (1, {'@': 47}), 16: (1, {'@': 47}), 17: (1, {'@': 47})}, 37: {18: (0, 65), 24: (0, 6), 12: (0, 37), 19: (0, 41), 25: (0, 29), 22: (0, 30)}, 38: {4: (1, {'@': 23}), 3: (1, {'@': 23}), 1: (1, {'@': 23})}, 39: {18: (0, 65), 26: (0, 75), 24: (0, 55), 12: (0, 37), 23: (0, 52), 19: (0, 41), 20: (0, 27), 25: (0, 29), 22: (0, 30)}, 40: {17: (0, 72), 1: (1, {'@': 41}), 5: (1, {'@': 41}), 7: (1, {'@': 41}), 8: (1, {'@': 41}), 6: (1, {'@': 41}), 0: (1, {'@': 41}), 9: (1, {'@': 41}), 11: (1, {'@': 41}), 2: (1, {'@': 41}), 4: (1, {'@': 41}), 12: (1, {'@': 41}), 13: (1, {'@': 41}), 14: (1, {'@': 41}), 15: (1, {'@': 41}), 3: (1, {'@': 41}), 16: (1, {'@': 41}), 10: (1, {'@': 41})}, 41: {21: (0, 26), 18: (0, 65), 28: (0, 73), 12: (0, 37), 31: (0, 38), 19: (0, 41), 20: (0, 27), 22: (0, 30), 30: (0, 21), 23: (0, 24), 24: (0, 55), 25: (0, 29), 32: (0, 66), 26: (0, 75)}, 42: {1: (1, {'@': 59}), 2: (1, {'@': 59}), 4: (1, {'@': 59}), 5: (1, {'@': 59}), 6: (1, {'@': 59}), 3: (1, {'@': 59}), 0: (1, {'@': 59})}, 43: {1: (1, {'@': 34}), 2: (1, {'@': 34}), 3: (1, {'@': 34}), 4: (1, {'@': 34}), 5: (1, {'@': 34}), 6: (1, {'@': 34}), 0: (1, {'@': 34})}, 44: {1: (1, {'@': 53}), 5: (1, {'@': 53}), 7: (1, {'@': 53}), 8: (1, {'@': 53}), 3: (1, {'@': 53}), 0: (1, {'@': 53}), 9: (1, {'@': 53}), 10: (1, {'@': 53}), 11: (1, {'@': 53}), 2: (1, {'@': 53}), 4: (1, {'@': 53}), 12: (1, {'@': 53}), 13: (1, {'@': 53}), 14: (1, {'@': 53}), 15: (1, {'@': 53}), 6: (1, {'@': 53}), 16: (1, {'@': 53}), 17: (1, {'@': 53})}, 45: {21: (0, 26), 18: (0, 65), 28: (0, 73), 12: (0, 37), 31: (0, 38), 19: (0, 41), 20: (0, 27), 22: (0, 30), 30: (0, 21), 23: (0, 24), 24: (0, 55), 3: (0, 1), 32: (0, 13), 35: (0, 50), 25: (0, 29), 26: (0, 75)}, 46: {18: (0, 65), 26: (0, 75), 24: (0, 55), 12: (0, 37), 19: (0, 41), 20: (0, 14), 25: (0, 29), 22: (0, 30)}, 47: {18: (0, 65), 26: (0, 75), 24: (0, 55), 12: (0, 37), 19: (0, 41), 20: (0, 27), 23: (0, 60), 25: (0, 29), 22: (0, 30)}, 48: {1: (1, {'@': 48}), 5: (1, {'@': 48}), 7: (1, {'@': 48}), 8: (1, {'@': 48}), 3: (1, {'@': 48}), 0: (1, {'@': 48}), 9: (1, {'@': 48}), 10: (1, {'@': 48}), 11: (1, {'@': 48}), 2: (1, {'@': 48}), 4: (1, {'@': 48}), 12: (1, {'@': 48}), 13: (1, {'@': 48}), 14: (1, {'@': 48}), 15: (1, {'@': 48}), 6: (1, {'@': 48}), 16: (1, {'@': 48}), 17: (1, {'@': 48})}, 49: {18: (0, 65), 26: (0, 75), 24: (0, 55), 12: (0, 37), 23: (0, 51), 19: (0, 41), 20: (0, 27), 25: (0, 29), 22: (0, 30)}, 50: {3: (0, 44)}, 51: {1: (1, {'@': 32}), 2: (1, {'@': 32}), 3: (1, {'@': 32}), 4: (1, {'@': 32}), 5: (1, {'@': 32}), 6: (1, {'@': 32}), 0: (1, {'@': 32})}, 52: {1: (1, {'@': 30}), 2: (1, {'@': 30}), 3: (1, {'@': 30}), 4: (1, {'@': 30}), 5: (1, {'@': 30}), 6: (1, {'@': 30}), 0: (1, {'@': 30})}, 53: {1: (1, {'@': 60}), 2: (1, {'@': 60}), 4: (1, {'@': 60}), 5: (1, {'@': 60}), 6: (1, {'@': 60}), 3: (1, {'@': 60}), 0: (1, {'@': 60})}, 54: {4: (1, {'@': 68}), 3: (1, {'@': 68})}, 55: {36: (0, 40), 17: (0, 9), 1: (1, {'@': 42}), 5: (1, {'@': 42}), 7: (1, {'@': 42}), 8: (1, {'@': 42}), 6: (1, {'@': 42}), 0: (1, {'@': 42}), 9: (1, {'@': 42}), 11: (1, {'@': 42}), 2: (1, {'@': 42}), 4: (1, {'@': 42}), 12: (1, {'@': 42}), 13: (1, {'@': 42}), 14: (1, {'@': 42}), 15: (1, {'@': 42}), 3: (1, {'@': 42}), 16: (1, {'@': 42}), 10: (1, {'@': 42})}, 56: {12: (1, {'@': 49}), 19: (1, {'@': 49}), 18: (1, {'@': 49}), 25: (1, {'@': 49})}, 57: {12: (1, {'@': 52}), 19: (1, {'@': 52}), 18: (1, {'@': 52}), 25: (1, {'@': 52})}, 58: {5: (0, 15)}, 59: {1: (1, {'@': 31}), 2: (1, {'@': 31}), 3: (1, {'@': 31}), 4: (1, {'@': 31}), 5: (1, {'@': 31}), 6: (1, {'@': 31}), 0: (1, {'@': 31})}, 60: {1: (1, {'@': 33}), 2: (1, {'@': 33}), 3: (1, {'@': 33}), 4: (1, {'@': 33}), 5: (1, {'@': 33}), 6: (1, {'@': 33}), 0: (1, {'@': 33})}, 61: {21: (0, 26), 18: (0, 65), 28: (0, 73), 12: (0, 37), 19: (0, 41), 20: (0, 27), 22: (0, 30), 30: (0, 21), 23: (0, 24), 24: (0, 55), 31: (0, 58), 25: (0, 29), 26: (0, 75)}, 62: {15: (0, 63), 37: (0, 67), 10: (0, 57), 1: (1, {'@': 39}), 11: (1, {'@': 39}), 2: (1, {'@': 39}), 4: (1, {'@': 39}), 5: (1, {'@': 39}), 7: (1, {'@': 39}), 12: (1, {'@': 39}), 13: (1, {'@': 39}), 14: (1, {'@': 39}), 8: (1, {'@': 39}), 3: (1, {'@': 39}), 6: (1, {'@': 39}), 0: (1, {'@': 39}), 16: (1, {'@': 39}), 9: (1, {'@': 39})}, 63: {12: (1, {'@': 51}), 19: (1, {'@': 51}), 18: (1, {'@': 51}), 25: (1, {'@': 51})}, 64: {1: (1, {'@': 66}), 5: (1, {'@': 66}), 7: (1, {'@': 66}), 8: (1, {'@': 66}), 3: (1, {'@': 66}), 0: (1, {'@': 66}), 9: (1, {'@': 66}), 11: (1, {'@': 66}), 2: (1, {'@': 66}), 4: (1, {'@': 66}), 12: (1, {'@': 66}), 13: (1, {'@': 66}), 14: (1, {'@': 66}), 15: (1, {'@': 66}), 6: (1, {'@': 66}), 16: (1, {'@': 66}), 10: (1, {'@': 66}), 17: (1, {'@': 66})}, 65: {19: (0, 45), 38: (0, 34), 1: (1, {'@': 46}), 5: (1, {'@': 46}), 7: (1, {'@': 46}), 8: (1, {'@': 46}), 3: (1, {'@': 46}), 0: (1, {'@': 46}), 9: (1, {'@': 46}), 10: (1, {'@': 46}), 11: (1, {'@': 46}), 2: (1, {'@': 46}), 4: (1, {'@': 46}), 12: (1, {'@': 46}), 13: (1, {'@': 46}), 14: (1, {'@': 46}), 15: (1, {'@': 46}), 6: (1, {'@': 46}), 16: (1, {'@': 46}), 17: (1, {'@': 46})}, 66: {3: (0, 48)}, 67: {18: (0, 65), 24: (0, 55), 12: (0, 37), 19: (0, 41), 26: (0, 2), 25: (0, 29), 22: (0, 30)}, 68: {1: (1, {'@': 58}), 2: (1, {'@': 58}), 4: (1, {'@': 58}), 5: (1, {'@': 58}), 6: (1, {'@': 58}), 3: (1, {'@': 58})}, 69: {21: (0, 26), 18: (0, 65), 28: (0, 73), 12: (0, 37), 31: (0, 38), 19: (0, 41), 20: (0, 27), 32: (0, 10), 22: (0, 30), 30: (0, 21), 23: (0, 24), 24: (0, 55), 39: (0, 17), 25: (0, 29), 26: (0, 75)}, 70: {18: (0, 65), 24: (0, 55), 12: (0, 37), 19: (0, 41), 25: (0, 29), 26: (0, 3), 22: (0, 30)}, 71: {1: (1, {'@': 35}), 2: (1, {'@': 35}), 3: (1, {'@': 35}), 4: (1, {'@': 35}), 5: (1, {'@': 35}), 6: (1, {'@': 35}), 0: (1, {'@': 35})}, 72: {18: (0, 65), 24: (0, 64), 12: (0, 37), 19: (0, 41), 25: (0, 29), 22: (0, 30)}, 73: {6: (0, 28), 40: (0, 5), 1: (1, {'@': 27}), 2: (1, {'@': 27}), 5: (1, {'@': 27}), 4: (1, {'@': 27}), 3: (1, {'@': 27})}, 74: {21: (0, 26), 18: (0, 65), 28: (0, 73), 12: (0, 37), 31: (0, 38), 19: (0, 41), 20: (0, 27), 22: (0, 30), 30: (0, 21), 23: (0, 24), 24: (0, 55), 32: (0, 54), 25: (0, 29), 26: (0, 75)}, 75: {15: (0, 63), 10: (0, 57), 41: (0, 62), 37: (0, 70), 1: (1, {'@': 40}), 11: (1, {'@': 40}), 2: (1, {'@': 40}), 4: (1, {'@': 40}), 5: (1, {'@': 40}), 7: (1, {'@': 40}), 12: (1, {'@': 40}), 13: (1, {'@': 40}), 14: (1, {'@': 40}), 8: (1, {'@': 40}), 3: (1, {'@': 40}), 6: (1, {'@': 40}), 0: (1, {'@': 40}), 16: (1, {'@': 40}), 9: (1, {'@': 40})}}, 'start_states': {'start': 69}, 'end_states': {'start': 17}}, '__type__': 'ParsingFrontend'}, 'rules': [{'@': 22}, {'@': 23}, {'@': 24}, {'@': 25}, {'@': 26}, {'@': 27}, {'@': 28}, {'@': 29}, {'@': 30}, {'@': 31}, {'@': 32}, {'@': 33}, {'@': 34}, {'@': 35}, {'@': 36}, {'@': 37}, {'@': 38}, {'@': 39}, {'@': 40}, {'@': 41}, {'@': 42}, {'@': 43}, {'@': 44}, {'@': 45}, {'@': 46}, {'@': 47}, {'@': 48}, {'@': 49}, {'@': 50}, {'@': 51}, {'@': 52}, {'@': 53}, {'@': 54}, {'@': 55}, {'@': 56}, {'@': 57}, {'@': 58}, {'@': 59}, {'@': 60}, {'@': 61}, {'@': 62}, {'@': 63}, {'@': 64}, {'@': 65}, {'@': 66}, {'@': 67}, {'@': 68}], 'options': {'debug': False, 'strict': False, 'keep_all_tokens': False, 'tree_class': None, 'cache': False, 'cache_grammar': False, 'postlex': None, 'parser': 'lalr', 'lexer': 'contextual', 'transformer': None, 'start': ['start'], 'priority': 'normal', 'ambiguity': 'auto', 'regex': False, 'propagate_positions': False, 'lexer_callbacks': {}, 'maybe_placeholders': False, 'edit_terminals': None, 'g_regex_flags': 0, 'use_bytes': False, 'ordered_sets': True, 'import_paths': [], 'source_path': None, '_plugins': {}}, '__type__': 'Lark'}
3565
+ )
3566
+ MEMO = (
3567
+ {0: {'name': 'WS', 'pattern': {'value': '(?:[ \t\x0c\r\n])+', 'flags': [], 'raw': None, '_width': [1, 18446744073709551616], '__type__': 'PatternRE'}, 'priority': 0, '__type__': 'TerminalDef'}, 1: {'name': 'PLUS', 'pattern': {'value': '+', 'flags': [], 'raw': '"+"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 2: {'name': 'MINUS', 'pattern': {'value': '-', 'flags': [], 'raw': '"-"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 3: {'name': 'STAR', 'pattern': {'value': '*', 'flags': [], 'raw': '"*"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 4: {'name': 'DIV', 'pattern': {'value': '/', 'flags': [], 'raw': '"/"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 5: {'name': 'POWER', 'pattern': {'value': '^', 'flags': [], 'raw': '"^"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 6: {'name': 'NUMBER', 'pattern': {'value': '\\d+(\\.\\d*)?|\\.\\d+', 'flags': [], 'raw': '/\\d+(\\.\\d*)?|\\.\\d+/', '_width': [1, 18446744073709551616], '__type__': 'PatternRE'}, 'priority': 0, '__type__': 'TerminalDef'}, 7: {'name': 'NAME', 'pattern': {'value': '[a-zA-Z_]\\w*', 'flags': [], 'raw': '/[a-zA-Z_]\\w*/', '_width': [1, 18446744073709551616], '__type__': 'PatternRE'}, 'priority': 0, '__type__': 'TerminalDef'}, 8: {'name': 'QMARK', 'pattern': {'value': '?', 'flags': [], 'raw': '"?"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 9: {'name': 'COLON', 'pattern': {'value': ':', 'flags': [], 'raw': '":"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 10: {'name': '__ANON_0', 'pattern': {'value': '||', 'flags': [], 'raw': '"||"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 11: {'name': '__ANON_1', 'pattern': {'value': '&&', 'flags': [], 'raw': '"&&"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 12: {'name': '__ANON_2', 'pattern': {'value': '==', 'flags': [], 'raw': '"=="', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 13: {'name': '__ANON_3', 'pattern': {'value': '!=', 'flags': [], 'raw': '"!="', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 14: {'name': 'LESSTHAN', 'pattern': {'value': '<', 'flags': [], 'raw': '"<"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 15: {'name': 'MORETHAN', 'pattern': {'value': '>', 'flags': [], 'raw': '">"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 16: {'name': '__ANON_4', 'pattern': {'value': '<=', 'flags': [], 'raw': '"<="', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 17: {'name': '__ANON_5', 'pattern': {'value': '>=', 'flags': [], 'raw': '">="', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 18: {'name': 'DOT', 'pattern': {'value': '.', 'flags': [], 'raw': '"."', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 19: {'name': 'LPAR', 'pattern': {'value': '(', 'flags': [], 'raw': '"("', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 20: {'name': 'RPAR', 'pattern': {'value': ')', 'flags': [], 'raw': '")"', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 21: {'name': 'COMMA', 'pattern': {'value': ',', 'flags': [], 'raw': '","', '__type__': 'PatternStr'}, 'priority': 0, '__type__': 'TerminalDef'}, 22: {'origin': {'name': 'start', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'expression', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 23: {'origin': {'name': 'expression', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'ternary_expr', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 24: {'origin': {'name': 'ternary_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'logical_or_expr', '__type__': 'NonTerminal'}, {'name': 'QMARK', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'ternary_expr', '__type__': 'NonTerminal'}, {'name': 'COLON', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'ternary_expr', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 25: {'origin': {'name': 'ternary_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'logical_or_expr', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 26: {'origin': {'name': 'logical_or_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'logical_and_expr', '__type__': 'NonTerminal'}, {'name': '__logical_or_expr_star_0', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 27: {'origin': {'name': 'logical_or_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'logical_and_expr', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 28: {'origin': {'name': 'logical_and_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'comparison_expr', '__type__': 'NonTerminal'}, {'name': '__logical_and_expr_star_1', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 29: {'origin': {'name': 'logical_and_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'comparison_expr', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 30: {'origin': {'name': 'comparison_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'sum', '__type__': 'NonTerminal'}, {'name': '__ANON_2', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'sum', '__type__': 'NonTerminal'}], 'order': 0, 'alias': 'eq', 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 31: {'origin': {'name': 'comparison_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'sum', '__type__': 'NonTerminal'}, {'name': '__ANON_3', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'sum', '__type__': 'NonTerminal'}], 'order': 1, 'alias': 'ne', 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 32: {'origin': {'name': 'comparison_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'sum', '__type__': 'NonTerminal'}, {'name': 'LESSTHAN', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'sum', '__type__': 'NonTerminal'}], 'order': 2, 'alias': 'lt', 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 33: {'origin': {'name': 'comparison_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'sum', '__type__': 'NonTerminal'}, {'name': 'MORETHAN', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'sum', '__type__': 'NonTerminal'}], 'order': 3, 'alias': 'gt', 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 34: {'origin': {'name': 'comparison_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'sum', '__type__': 'NonTerminal'}, {'name': '__ANON_4', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'sum', '__type__': 'NonTerminal'}], 'order': 4, 'alias': 'le', 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 35: {'origin': {'name': 'comparison_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'sum', '__type__': 'NonTerminal'}, {'name': '__ANON_5', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'sum', '__type__': 'NonTerminal'}], 'order': 5, 'alias': 'ge', 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 36: {'origin': {'name': 'comparison_expr', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'sum', '__type__': 'NonTerminal'}], 'order': 6, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 37: {'origin': {'name': 'sum', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'product', '__type__': 'NonTerminal'}, {'name': '__sum_star_2', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 38: {'origin': {'name': 'sum', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'product', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 39: {'origin': {'name': 'product', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'power', '__type__': 'NonTerminal'}, {'name': '__product_star_3', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 40: {'origin': {'name': 'product', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'power', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 41: {'origin': {'name': 'power', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'atom', '__type__': 'NonTerminal'}, {'name': '__power_star_4', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 42: {'origin': {'name': 'power', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'atom', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 43: {'origin': {'name': 'atom', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'MINUS', 'filter_out': False, '__type__': 'Terminal'}, {'name': 'atom', '__type__': 'NonTerminal'}], 'order': 0, 'alias': 'neg', 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 44: {'origin': {'name': 'atom', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'func_call', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 45: {'origin': {'name': 'atom', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'NUMBER', 'filter_out': False, '__type__': 'Terminal'}], 'order': 2, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 46: {'origin': {'name': 'atom', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'NAME', 'filter_out': False, '__type__': 'Terminal'}], 'order': 3, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 47: {'origin': {'name': 'atom', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'NAME', 'filter_out': False, '__type__': 'Terminal'}, {'name': 'DOT', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'NAME', 'filter_out': False, '__type__': 'Terminal'}], 'order': 4, 'alias': 'dotted_name', 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 48: {'origin': {'name': 'atom', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'LPAR', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'expression', '__type__': 'NonTerminal'}, {'name': 'RPAR', 'filter_out': True, '__type__': 'Terminal'}], 'order': 5, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': True, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 49: {'origin': {'name': 'add_op', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'PLUS', 'filter_out': False, '__type__': 'Terminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': True, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 50: {'origin': {'name': 'add_op', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'MINUS', 'filter_out': False, '__type__': 'Terminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': True, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 51: {'origin': {'name': 'mul_op', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'STAR', 'filter_out': False, '__type__': 'Terminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': True, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 52: {'origin': {'name': 'mul_op', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'DIV', 'filter_out': False, '__type__': 'Terminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': True, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 53: {'origin': {'name': 'func_call', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'NAME', 'filter_out': False, '__type__': 'Terminal'}, {'name': 'LPAR', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'arguments', '__type__': 'NonTerminal'}, {'name': 'RPAR', 'filter_out': True, '__type__': 'Terminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 54: {'origin': {'name': 'func_call', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'NAME', 'filter_out': False, '__type__': 'Terminal'}, {'name': 'LPAR', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'RPAR', 'filter_out': True, '__type__': 'Terminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (False, False, True, False), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 55: {'origin': {'name': 'arguments', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'expression', '__type__': 'NonTerminal'}, {'name': '__arguments_star_5', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 56: {'origin': {'name': 'arguments', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'expression', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 57: {'origin': {'name': '__logical_or_expr_star_0', '__type__': 'NonTerminal'}, 'expansion': [{'name': '__ANON_0', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'logical_and_expr', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 58: {'origin': {'name': '__logical_or_expr_star_0', '__type__': 'NonTerminal'}, 'expansion': [{'name': '__logical_or_expr_star_0', '__type__': 'NonTerminal'}, {'name': '__ANON_0', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'logical_and_expr', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 59: {'origin': {'name': '__logical_and_expr_star_1', '__type__': 'NonTerminal'}, 'expansion': [{'name': '__ANON_1', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'comparison_expr', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 60: {'origin': {'name': '__logical_and_expr_star_1', '__type__': 'NonTerminal'}, 'expansion': [{'name': '__logical_and_expr_star_1', '__type__': 'NonTerminal'}, {'name': '__ANON_1', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'comparison_expr', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 61: {'origin': {'name': '__sum_star_2', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'add_op', '__type__': 'NonTerminal'}, {'name': 'product', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 62: {'origin': {'name': '__sum_star_2', '__type__': 'NonTerminal'}, 'expansion': [{'name': '__sum_star_2', '__type__': 'NonTerminal'}, {'name': 'add_op', '__type__': 'NonTerminal'}, {'name': 'product', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 63: {'origin': {'name': '__product_star_3', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'mul_op', '__type__': 'NonTerminal'}, {'name': 'power', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 64: {'origin': {'name': '__product_star_3', '__type__': 'NonTerminal'}, 'expansion': [{'name': '__product_star_3', '__type__': 'NonTerminal'}, {'name': 'mul_op', '__type__': 'NonTerminal'}, {'name': 'power', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 65: {'origin': {'name': '__power_star_4', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'POWER', 'filter_out': False, '__type__': 'Terminal'}, {'name': 'atom', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 66: {'origin': {'name': '__power_star_4', '__type__': 'NonTerminal'}, 'expansion': [{'name': '__power_star_4', '__type__': 'NonTerminal'}, {'name': 'POWER', 'filter_out': False, '__type__': 'Terminal'}, {'name': 'atom', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 67: {'origin': {'name': '__arguments_star_5', '__type__': 'NonTerminal'}, 'expansion': [{'name': 'COMMA', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'expression', '__type__': 'NonTerminal'}], 'order': 0, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}, 68: {'origin': {'name': '__arguments_star_5', '__type__': 'NonTerminal'}, 'expansion': [{'name': '__arguments_star_5', '__type__': 'NonTerminal'}, {'name': 'COMMA', 'filter_out': True, '__type__': 'Terminal'}, {'name': 'expression', '__type__': 'NonTerminal'}], 'order': 1, 'alias': None, 'options': {'keep_all_tokens': False, 'expand1': False, 'priority': None, 'template_source': None, 'empty_indices': (), '__type__': 'RuleOptions'}, '__type__': 'Rule'}}
3568
+ )
3569
+ Shift = 0
3570
+ Reduce = 1
3571
+ def Lark_StandAlone(**kwargs):
3572
+ return Lark._load_from_dict(DATA, MEMO, **kwargs)