syncraft 0.2.6__py3-none-any.whl → 0.2.8__py3-none-any.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.

Potentially problematic release.


This version of syncraft might be problematic. Click here for more details.

syncraft/algebra.py CHANGED
@@ -77,7 +77,7 @@ class Algebra(Generic[A, S]):
77
77
  ######################################################## shared among all subclasses ########################################################
78
78
  run_f: Callable[[S, bool], Generator[Incomplete[S], S, Either[Any, Tuple[A, S]]]]
79
79
  name: Hashable
80
- cache: Cache[ S, Either[Any, Tuple[A, S]] ]
80
+ cache: Cache[Either[Any, Tuple[A, S]]]
81
81
 
82
82
  @classmethod
83
83
  def state(cls, **kwargs:Any)->Optional[S]:
@@ -103,10 +103,10 @@ class Algebra(Generic[A, S]):
103
103
  cache: Cache) -> Algebra[A, S]:
104
104
  def algebra_lazy_run(input: S, use_cache:bool) -> Generator[Incomplete[S], S, Either[Any, Tuple[A, S]]]:
105
105
  alg = thunk()
106
- print('--' * 20, "Algebra.lazy.algebra_lazy_run", '--' * 20)
107
- print('thunk', thunk, id(thunk))
108
- print('input', input, id(input))
109
- print('alg', alg, id(alg))
106
+ # print('--' * 20, "Algebra.lazy.algebra_lazy_run", '--' * 20)
107
+ # print('thunk', thunk, id(thunk))
108
+ # print('input', input, id(input))
109
+ # print('alg', alg, id(alg))
110
110
  result = yield from alg.run(input, use_cache)
111
111
  return result
112
112
  return cls(algebra_lazy_run, name=cls.__name__ + '.lazy', cache=cache)
syncraft/ast.py CHANGED
@@ -491,6 +491,7 @@ class LazySpec(SyntaxSpec, Generic[A]):
491
491
  value: A
492
492
  @dataclass(frozen=True)
493
493
  class ThenSpec(SyntaxSpec, Generic[A, B]):
494
+ kind: ThenKind
494
495
  left: A
495
496
  right: B
496
497
 
syncraft/cache.py CHANGED
@@ -30,8 +30,8 @@ Args = TypeVar('Args', bound=Hashable)
30
30
  Ret = TypeVar('Ret')
31
31
 
32
32
  @dataclass
33
- class Cache(Generic[Args, Ret]):
34
- cache: WeakKeyDictionary[Callable[..., Any], Dict[Args, Ret | InProgress]] = field(default_factory=WeakKeyDictionary)
33
+ class Cache(Generic[Ret]):
34
+ cache: WeakKeyDictionary[Callable[..., Any], Dict[Hashable, Ret | InProgress]] = field(default_factory=WeakKeyDictionary)
35
35
 
36
36
  def __contains__(self, f: Callable[..., Any]) -> bool:
37
37
  return f in self.cache
@@ -40,74 +40,103 @@ class Cache(Generic[Args, Ret]):
40
40
  return f"Cache({({f.__name__: list(c.keys()) for f, c in self.cache.items()})})"
41
41
 
42
42
 
43
- def __or__(self, other: Cache[Args, Any]) -> Cache[Args, Any]:
43
+ def __or__(self, other: Cache[Any]) -> Cache[Any]:
44
44
  assert self.cache is other.cache, "There should be only one global cache"
45
- if self.cache is other.cache:
46
- return self
47
- elif len(self.cache) == 0:
48
- return other
49
- elif len(other.cache) == 0:
50
- return self
51
- merged = Cache[Args, Ret]()
52
- for f, c in self.cache.items():
53
- merged.cache[f] = c.copy()
54
- for f, c in other.cache.items():
55
- merged.cache.setdefault(f, {}).update(c)
56
- return merged
45
+ return self
57
46
 
58
47
  @overload
59
48
  def _execute(self,
60
- f: Callable[[Args, bool], Ret],
61
- args: Args,
62
- use_cache: bool,
63
- is_gen: Literal[False]) -> Ret: ...
49
+ f: Callable[..., Ret],
50
+ *args:Any,
51
+ is_gen: Literal[False],
52
+ **kwargs:Any) -> Ret: ...
64
53
  @overload
65
54
  def _execute(self,
66
- f: Callable[[Args, bool], Generator[Any, Any, Ret]],
67
- args: Args,
68
- use_cache: bool,
69
- is_gen: Literal[True]) -> Generator[Any, Any, Ret]: ...
55
+ f: Callable[..., Generator[Any, Any, Ret]],
56
+ *args: Any,
57
+ is_gen: Literal[True],
58
+ **kwargs: Any) -> Generator[Any, Any, Ret]: ...
70
59
 
71
60
 
72
61
  def _execute(self,
73
- f: Callable[[Args, bool], Any],
74
- args: Args,
75
- use_cache:bool,
76
- is_gen: bool
77
- ) -> Ret | Generator[Any, Any, Ret]:
62
+ f: Callable[..., Any],
63
+ *args: Any,
64
+ is_gen: bool,
65
+ **kwargs: Any) -> Ret | Generator[Any, Any, Ret]:
78
66
  if f not in self.cache:
79
67
  self.cache.setdefault(f, dict())
80
- c: Dict[Args, Ret | InProgress] = self.cache[f]
81
- if args in c:
82
- v = c[args]
68
+ c: Dict[Hashable, Ret | InProgress] = self.cache[f]
69
+ key = (args, tuple(sorted(kwargs.items())))
70
+ if key in c:
71
+ v = c[key]
83
72
  if isinstance(v, InProgress):
84
73
  raise RecursionError("Left-recursion detected in parser", offending=f, state=args)
85
74
  else:
86
75
  return v
87
76
  try:
88
- c[args] = InProgress()
77
+ c[key] = InProgress()
89
78
  if is_gen:
90
- result = yield from f(args, use_cache)
79
+ result = yield from f(*args, **kwargs)
91
80
  else:
92
- result = f(args, use_cache)
93
- c[args] = result
94
- if not use_cache:
95
- c.pop(args, None)
81
+ result = f(*args, **kwargs)
82
+ c[key] = result
83
+ if kwargs.get('use_cache', True) is False:
84
+ c.pop(key, None)
96
85
  return result
97
86
  except Exception as e:
98
- c.pop(args, None)
87
+ c.pop(key, None)
99
88
  raise e
100
89
 
101
90
  def gen(self,
102
- f: Callable[[Args, bool], Generator[Any, Any, Ret]],
103
- args: Args,
104
- use_cache:bool) -> Generator[Any, Any, Ret]:
105
- return (yield from self._execute(f, args, use_cache, is_gen=True))
91
+ f: Callable[..., Generator[Any, Any, Ret]],
92
+ *args: Any,
93
+ **kwargs: Any) -> Generator[Any, Any, Ret]:
94
+ if f not in self.cache:
95
+ self.cache.setdefault(f, dict())
96
+ c: Dict[Hashable, Ret | InProgress] = self.cache[f]
97
+ key = (tuple(filter(lambda x: not isinstance(x, Cache), args)), tuple(sorted(filter(lambda item: not isinstance(item[1], Cache), kwargs.items()))))
98
+ if key in c:
99
+ v = c[key]
100
+ if isinstance(v, InProgress):
101
+ raise RecursionError("Left-recursion detected in parser", offending=f, state=args)
102
+ else:
103
+ return v
104
+ try:
105
+ c[key] = InProgress()
106
+ result = yield from f(*args, **kwargs)
107
+ c[key] = result
108
+ if kwargs.get('use_cache', True) is False:
109
+ c.pop(key, None)
110
+ return result
111
+ except Exception as e:
112
+ c.pop(key, None)
113
+ raise e
114
+
106
115
 
107
116
  def call(self,
108
- f: Callable[[Args, bool], Ret],
109
- args: Args,
110
- use_cache:bool) -> Ret:
111
- return self._execute(f, args, use_cache, is_gen=False)
117
+ f: Callable[..., Ret],
118
+ *args:Any,
119
+ **kwargs:Any) -> Ret:
120
+ if f not in self.cache:
121
+ self.cache.setdefault(f, dict())
122
+ c: Dict[Hashable, Ret | InProgress] = self.cache[f]
123
+ key = (tuple(filter(lambda x: not isinstance(x, Cache), args)), tuple(sorted(filter(lambda item: not isinstance(item[1], Cache), kwargs.items()))))
124
+ if key in c:
125
+ v = c[key]
126
+ if isinstance(v, InProgress):
127
+ raise RecursionError("Left-recursion detected in parser", offending=f, state=args)
128
+ else:
129
+ return v
130
+ try:
131
+ c[key] = InProgress()
132
+ result = f(*args, **kwargs)
133
+ c[key] = result
134
+ if kwargs.get('use_cache', True) is False:
135
+ c.pop(key, None)
136
+ return result
137
+ except Exception as e:
138
+ c.pop(key, None)
139
+ raise e
140
+
112
141
 
113
142
 
syncraft/generator.py CHANGED
@@ -245,7 +245,7 @@ class Generator(Algebra[ParseResult[T], GenState[T]]):
245
245
  Algebra[B, GenState[T]]: An algebra yielding the final result.
246
246
  """
247
247
  def flat_map_run(input: GenState[T], use_cache:bool) -> PyGenerator[Incomplete[GenState[T]], GenState[T], Either[Any, Tuple[B, GenState[T]]]]:
248
- if not isinstance(input.ast, Then) or isinstance(input.ast, Nothing):
248
+ if not input.pruned and (not isinstance(input.ast, Then) or isinstance(input.ast, Nothing)):
249
249
  return Left(Error(this=self,
250
250
  message=f"Expect Then got {input.ast}",
251
251
  state=input))
syncraft/parser.py CHANGED
@@ -122,18 +122,6 @@ class ParserState(Bindable, Generic[T]):
122
122
  class Parser(Algebra[T, ParserState[T]]):
123
123
  @classmethod
124
124
  def state(cls, sql: str, dialect: str) -> ParserState[T]: # type: ignore
125
- """Tokenize SQL text into an initial ``ParserState``.
126
-
127
- Uses ``sqlglot.tokenize`` for the given dialect and wraps tokens into
128
- the project's ``Token`` type.
129
-
130
- Args:
131
- sql: The SQL text to tokenize.
132
- dialect: The sqlglot dialect name (e.g. "sqlite", "duckdb").
133
-
134
- Returns:
135
- ParserState[T]: Initial parser state at index 0.
136
- """
137
125
  tokens = tuple([Token(token_type=token.token_type, text=token.text) for token in tokenize(sql, dialect=dialect)])
138
126
  return ParserState.from_tokens(tokens) # type: ignore
139
127
 
@@ -146,21 +134,6 @@ class Parser(Algebra[T, ParserState[T]]):
146
134
  case_sensitive: bool = False,
147
135
  regex: Optional[re.Pattern[str]] = None
148
136
  )-> Algebra[T, ParserState[T]]:
149
- """Match a single token according to a specification.
150
-
151
- Succeeds when the current token satisfies the provided
152
- ``TokenSpec`` (by type, exact text, or regex). On failure,
153
- an informative ``Error`` is produced with location context.
154
-
155
- Args:
156
- token_type: Expected enum type of the token.
157
- text: Exact token text to match.
158
- case_sensitive: Whether text matching is case sensitive.
159
- regex: Regular expression pattern to match token text.
160
-
161
- Returns:
162
- Algebra[T, ParserState[T]]: An algebra yielding the matched token.
163
- """
164
137
  spec = TokenSpec(token_type=token_type, text=text, case_sensitive=case_sensitive, regex=regex)
165
138
  def token_run(state: ParserState[T], use_cache:bool) -> Generator[Incomplete[ParserState[T]],ParserState[T], Either[Any, Tuple[T, ParserState[T]]]]:
166
139
  while True:
syncraft/syntax.py CHANGED
@@ -54,7 +54,7 @@ class Syntax(Generic[A, S]):
54
54
  """
55
55
  The core signature of Syntax is take an Algebra Class and return an Algebra Instance.
56
56
  """
57
- alg: Callable[[Type[Algebra[Any, Any]], Cache[Any, Any]], Algebra[A, S]]
57
+ alg: Callable[[Type[Algebra[Any, Any]], Cache[Any]], Algebra[A, S]]
58
58
  meta: Description = field(default_factory=Description, repr=False)
59
59
 
60
60
  def algebra(self, name: str | MethodType | FunctionType, *args: Any, **kwargs: Any) -> Syntax[A, S]:
@@ -71,7 +71,7 @@ class Syntax(Generic[A, S]):
71
71
  Returns:
72
72
  A new Syntax reflecting the transformed algebra.
73
73
  """
74
- def algebra_run(cls: Type[Algebra[Any, S]], cache: Cache[Any, Any]) -> Algebra[Any, S]:
74
+ def algebra_run(cls: Type[Algebra[Any, S]], cache: Cache[Any]) -> Algebra[Any, S]:
75
75
  a = self(cls, cache)
76
76
  if isinstance(name, str):
77
77
  attr = getattr(a, name, None) or getattr(cls, name, None)
@@ -97,7 +97,7 @@ class Syntax(Generic[A, S]):
97
97
  def as_(self, typ: Type[B]) -> B:
98
98
  return cast(typ, self) # type: ignore
99
99
 
100
- def __call__(self, alg: Type[Algebra[Any, Any]], cache: Cache[Any, Any]) -> Algebra[A, S]:
100
+ def __call__(self, alg: Type[Algebra[Any, Any]], cache: Cache[Any]) -> Algebra[A, S]:
101
101
  return self.alg(alg, cache)
102
102
 
103
103
 
@@ -562,37 +562,28 @@ def run(*,
562
562
 
563
563
 
564
564
  def lazy(thunk: Callable[[], Syntax[A, S]]) -> Syntax[A, S]:
565
- syntax: Optional[Syntax[A, S]] = None
566
565
  algebra: Optional[Algebra[A, S]] = None
566
+ syntax: Optional[Syntax[A, S]] = None
567
+ previous_cls: Optional[Type[Algebra[Any, S]]] = None
567
568
  def syntax_lazy_run(cls: Type[Algebra[Any, S]], cache: Cache) -> Algebra[A, S]:
568
- nonlocal syntax, algebra
569
- print('==' * 20, 'Syntax.lazy.syntax_lazy_run', '==' * 20)
570
- print('thunk', thunk, id(thunk))
571
- print('syntax', syntax, id(syntax))
572
- print('algebra', algebra, id(algebra))
569
+ nonlocal algebra, syntax, previous_cls
570
+ # print('==' * 20, 'Syntax.lazy.syntax_lazy_run', '==' * 20)
571
+ # print('thunk', thunk, id(thunk))
572
+ # print('syntax', syntax, id(syntax))
573
+ # print('algebra', algebra, id(algebra))
573
574
  if syntax is None:
574
575
  syntax = thunk()
575
576
  def algebra_lazy_f():
576
577
  if syntax is None:
577
578
  raise SyncraftError("Lazy thunk did not resolve to a Syntax", offending=thunk, expect="a Syntax")
578
579
  return syntax(cls, cache)
579
- if algebra is None:
580
- algebra = cls.lazy(algebra_lazy_f, cache=cache)
580
+ if algebra is None or (previous_cls is not None and previous_cls is not cls):
581
+ algebra = cls.lazy(algebra_lazy_f, cache=cache)
582
+ previous_cls = cls
581
583
  return algebra
582
584
  return Syntax(syntax_lazy_run).describe(name='lazy(?)', fixity='postfix')
583
585
 
584
586
 
585
- # def lazy(thunk: Callable[[], Syntax[A, S]]) -> Syntax[A, S]:
586
- # resolved: Optional[Syntax[A, S]] = None
587
-
588
- # def run_lazy(cls: Type[Algebra[Any, S]], cache: Cache) -> Algebra[A, S]:
589
- # nonlocal resolved
590
- # if resolved is None:
591
- # resolved = thunk()
592
- # return resolved(cls, cache) # reuse the same Algebra instance
593
- # return Syntax(run_lazy)
594
-
595
-
596
587
 
597
588
 
598
589
  def token(*,
syncraft/walker.py CHANGED
@@ -7,13 +7,14 @@ from dataclasses import dataclass, replace, field
7
7
  from syncraft.algebra import (
8
8
  Algebra, Either, Right, Incomplete, Left, SyncraftError
9
9
  )
10
- from syncraft.ast import TokenSpec, ThenSpec, ManySpec, ChoiceSpec, LazySpec
10
+ from syncraft.ast import TokenSpec, ThenSpec, ManySpec, ChoiceSpec, LazySpec, ThenKind
11
11
  from syncraft.parser import TokenType
12
12
  from syncraft.constraint import Bindable, FrozenDict
13
13
 
14
14
  import re
15
15
  from syncraft.syntax import Syntax
16
16
  from syncraft.cache import Cache
17
+ from rich import print
17
18
 
18
19
 
19
20
  S = TypeVar('S', bound=Bindable)
@@ -31,7 +32,6 @@ SS = TypeVar('SS', bound=Hashable)
31
32
  class WalkerState(Bindable, Generic[SS]):
32
33
  reducer: Optional[Callable[[Any, SS], SS]] = None
33
34
  acc: Optional[SS] = None
34
- visited: frozenset = field(default_factory=frozenset)
35
35
 
36
36
 
37
37
  def reduce(self, value: Any) -> WalkerState[SS]:
@@ -41,8 +41,6 @@ class WalkerState(Bindable, Generic[SS]):
41
41
  else:
42
42
  return replace(self, acc=value)
43
43
 
44
- def visit(self, key: Hashable) -> WalkerState[SS]:
45
- return replace(self, visited=self.visited | {key})
46
44
 
47
45
 
48
46
 
@@ -55,24 +53,40 @@ class Walker(Algebra[SS, WalkerState[SS]]):
55
53
  return WalkerState(reducer=reducer, acc=init)
56
54
 
57
55
 
56
+
57
+ @classmethod
58
+ def token(cls,
59
+ *,
60
+ cache: Cache,
61
+ token_type: Optional[TokenType] = None,
62
+ text: Optional[str] = None,
63
+ case_sensitive: bool = False,
64
+ regex: Optional[re.Pattern[str]] = None
65
+ )-> Algebra[Any, WalkerState[SS]]:
66
+ def token_run(input: WalkerState[SS], use_cache:bool) -> PyGenerator[Incomplete[WalkerState[SS]], WalkerState[SS], Either[Any, Tuple[Any, WalkerState[SS]]]]:
67
+ yield from ()
68
+ data = TokenSpec(token_type=token_type, text=text, regex=regex, case_sensitive=case_sensitive)
69
+ return Right((data, input.reduce(data)))
70
+ return cls(token_run, name=cls.__name__ + f'.token({token_type or text or regex})', cache=cache)
71
+
58
72
  @classmethod
59
- def lazy(cls, thunk: Callable[[], Algebra[Any, WalkerState[SS]]], cache: Cache) -> Algebra[Any, WalkerState[SS]]:
60
- def alazy_run(input: WalkerState[SS], use_cache:bool) -> PyGenerator[Incomplete[WalkerState[SS]], WalkerState[SS], Either[Any, Tuple[Any, WalkerState[SS]]]]:
61
- result = yield from thunk().run(input, use_cache)
62
- return result
63
-
64
- def lazy_run(input: WalkerState[SS], use_cache:bool) -> PyGenerator[Incomplete[WalkerState[SS]], WalkerState[SS], Either[Any, Tuple[Any, WalkerState[SS]]]]:
65
- print('thunk', thunk, input.visited)
66
- if thunk in input.visited:
67
- return Right((None, input))
68
- else:
69
- thunk_result = yield from thunk().run(input, use_cache)
70
- match thunk_result:
71
- case Right((value, from_thunk)):
72
- data = LazySpec(value=value)
73
- return Right((data, from_thunk.visit(thunk).reduce(data)))
73
+ def lazy(cls,
74
+ thunk: Callable[[], Algebra[Any, WalkerState[SS]]],
75
+ cache: Cache) -> Algebra[Any, WalkerState[SS]]:
76
+ def algebra_lazy_run(input: WalkerState[SS], use_cache:bool) -> PyGenerator[Incomplete[WalkerState[SS]], WalkerState[SS], Either[Any, Tuple[Any, WalkerState[SS]]]]:
77
+ alg = thunk()
78
+ print('--' * 20, "Walker.lazy.algebra_lazy_run", '--' * 20)
79
+ print('thunk', thunk, id(thunk))
80
+ print('input', input, id(input))
81
+ print('alg', alg, id(alg))
82
+ thunk_result = yield from alg.run(input, use_cache)
83
+ match thunk_result:
84
+ case Right((value, from_thunk)):
85
+ data = LazySpec(value=value)
86
+ return Right((data, from_thunk.reduce(data)))
74
87
  raise SyncraftError("flat_map should always return a value or an error.", offending=thunk_result, expect=(Left, Right))
75
- return cls(lazy_run, name=cls.__name__ + '.lazy', cache=cache)
88
+ return cls(algebra_lazy_run, name=cls.__name__ + '.lazy', cache=cache)
89
+
76
90
 
77
91
 
78
92
  def then_both(self, other: Algebra[Any, WalkerState[SS]]) -> Algebra[Any, WalkerState[SS]]:
@@ -83,16 +97,16 @@ class Walker(Algebra[SS, WalkerState[SS]]):
83
97
  other_result = yield from other.run(from_left, use_cache)
84
98
  match other_result:
85
99
  case Right((result, from_right)):
86
- data = ThenSpec(left=value, right=result)
100
+ data = ThenSpec(kind=ThenKind.BOTH, left=value, right=result)
87
101
  return Right((data, from_right.reduce(data)))
88
102
  raise SyncraftError("flat_map should always return a value or an error.", offending=self_result, expect=(Left, Right))
89
103
  return self.__class__(then_run, name=self.name, cache=self.cache | other.cache)
90
104
 
91
105
  def then_left(self, other: Algebra[Any, WalkerState[SS]]) -> Algebra[Any, WalkerState[SS]]:
92
- return self.then_both(other) # For simplicity, treat as both
106
+ return self.then_both(other).map(lambda t: replace(t, kind=ThenKind.LEFT))
93
107
 
94
108
  def then_right(self, other: Algebra[Any, WalkerState[SS]]) -> Algebra[Any, WalkerState[SS]]:
95
- return self.then_both(other)
109
+ return self.then_both(other).map(lambda t: replace(t, kind=ThenKind.RIGHT))
96
110
 
97
111
 
98
112
  def many(self, *, at_least: int, at_most: Optional[int]) -> Algebra[Any, WalkerState[SS]]:
@@ -121,27 +135,9 @@ class Walker(Algebra[SS, WalkerState[SS]]):
121
135
  raise SyncraftError("", offending=self)
122
136
  return self.__class__(or_else_run, name=f"or_else({self.name} | {other.name})", cache=self.cache | other.cache)
123
137
 
124
- @classmethod
125
- def token(cls,
126
- *,
127
- cache: Cache,
128
- token_type: Optional[TokenType] = None,
129
- text: Optional[str] = None,
130
- case_sensitive: bool = False,
131
- regex: Optional[re.Pattern[str]] = None
132
- )-> Algebra[Any, WalkerState[SS]]:
133
- def token_run(input: WalkerState[SS], use_cache:bool) -> PyGenerator[Incomplete[WalkerState[SS]], WalkerState[SS], Either[Any, Tuple[Any, WalkerState[SS]]]]:
134
- yield from ()
135
- data = TokenSpec(token_type=token_type, text=text, regex=regex, case_sensitive=case_sensitive)
136
- return Right((data, input.reduce(data)))
137
- return cls(token_run, name=cls.__name__ + f'.token({token_type or text or regex})', cache=cache)
138
138
 
139
139
 
140
- def walk(syntax: Syntax[Any, Any], reducer: Callable[[Any, Any], SS], init: SS)-> Optional[SS]:
140
+ def walk(syntax: Syntax[Any, Any], reducer: Callable[[Any, Any], SS], init: SS)-> Tuple[Any, None | SS]:
141
141
  from syncraft.syntax import run
142
- from rich import print
143
142
  v, s = run(syntax=syntax, alg=Walker, use_cache=False, reducer=reducer, init=init)
144
- if s is not None:
145
- return s.acc
146
- else:
147
- return None
143
+ return v, s
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syncraft
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: Parser combinator library
5
5
  Author-email: Michael Afmokt <michael@esacca.com>
6
6
  License-Expression: MIT
@@ -0,0 +1,20 @@
1
+ syncraft/__init__.py,sha256=g1Rd3DwPJ-Z7dL0PBNyNkcLBmpkp8bIBDWabkeBCD48,1329
2
+ syncraft/algebra.py,sha256=RfI6IzVPflDMuONbajGmqDYo0gR2Yqt3GSaZ8M0N-cs,20709
3
+ syncraft/ast.py,sha256=UZSByp1XZjaBMldc6AVL6bZcjTbPPi7qtlAM1HwY2Tk,20798
4
+ syncraft/cache.py,sha256=oqF0E-jHFzYW36YqPRQm-wP_8_YhcB6VfGNdvgllE0w,4827
5
+ syncraft/constraint.py,sha256=a6j_VafRor8W7FBXh20DoVnIUO9nfn7eIValigCf9lU,16318
6
+ syncraft/dev.py,sha256=v7jdb2aOVCGbio-Jw14tRhO09FkhWc0vrDdIkIKPu2Y,186
7
+ syncraft/finder.py,sha256=Mv9BYrsDjjq62Z4NO3gElZAbkEgSBINhSbqFbKEQW4Q,4347
8
+ syncraft/generator.py,sha256=2q_dRKZlPLdfyrwdZqL01KpNes00qLKm-D13OWzN79I,21232
9
+ syncraft/lexer.py,sha256=npPHAEEbBRQYcFHPMHtXmiVLbCZAnjpTtj3cnVui4W0,3720
10
+ syncraft/parser.py,sha256=bdCbbeJ5p-j8kJniqmKSRAE8N3pCWN-ltJIpALW0h54,9070
11
+ syncraft/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ syncraft/sqlite3.py,sha256=Pq09IHZOwuWg5W82l9D1flzd36QV0TOHQpTJ5U02V8g,34701
13
+ syncraft/syntax.py,sha256=ILIEK0GQp0_rpXJYEAX9E_wN7ouTUiFfyGqlQtaAJN4,24794
14
+ syncraft/utils.py,sha256=2V446Il2q4mR7bwwGX5_qruJPU0WXU2PniXEjl6EOPE,8746
15
+ syncraft/walker.py,sha256=-IFS8M_cL5qG2meJleo_AS2ejTis0bnLWu-6Yw-ILUk,6817
16
+ syncraft-0.2.8.dist-info/licenses/LICENSE,sha256=wHSV424U5csa3339dy1AZbsz2xsd0hrkMx2QK48CcUk,1062
17
+ syncraft-0.2.8.dist-info/METADATA,sha256=2QiTtmFXvxrquEPGn1eqBTSbsesiHavUf_KyQgxQtHk,1023
18
+ syncraft-0.2.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
+ syncraft-0.2.8.dist-info/top_level.txt,sha256=Kq3t8ESXB2xW1Xt3uPmkENFc-c4f2pamNmaURBk7zc8,9
20
+ syncraft-0.2.8.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- syncraft/__init__.py,sha256=g1Rd3DwPJ-Z7dL0PBNyNkcLBmpkp8bIBDWabkeBCD48,1329
2
- syncraft/algebra.py,sha256=W6n4YH75VUU960DTW1ZGljmuhvOtLOzkL6_w9DG6fWI,20706
3
- syncraft/ast.py,sha256=kMpZtox3S41t6srptJzd8G0p7Imu-FX2reC6Zdk47PY,20779
4
- syncraft/cache.py,sha256=n7YpN6OmkDySVKRP-FWE8Ni6WqzMHz2b4TsSbBPRJtA,3655
5
- syncraft/constraint.py,sha256=a6j_VafRor8W7FBXh20DoVnIUO9nfn7eIValigCf9lU,16318
6
- syncraft/dev.py,sha256=v7jdb2aOVCGbio-Jw14tRhO09FkhWc0vrDdIkIKPu2Y,186
7
- syncraft/finder.py,sha256=Mv9BYrsDjjq62Z4NO3gElZAbkEgSBINhSbqFbKEQW4Q,4347
8
- syncraft/generator.py,sha256=ybliYMDCC7z_Q3ODUYvYvwaKaMl7lULtJkmtX_c6lWw,21209
9
- syncraft/lexer.py,sha256=npPHAEEbBRQYcFHPMHtXmiVLbCZAnjpTtj3cnVui4W0,3720
10
- syncraft/parser.py,sha256=jt34gkHl4OJuImedR4abPGPw0VZtSOPzuTQRsvx8G_k,10094
11
- syncraft/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- syncraft/sqlite3.py,sha256=Pq09IHZOwuWg5W82l9D1flzd36QV0TOHQpTJ5U02V8g,34701
13
- syncraft/syntax.py,sha256=O4HE4IDZ6fclP7kRy5L6rIuIdp_LmnMsr0LRuAIIS8s,25033
14
- syncraft/utils.py,sha256=2V446Il2q4mR7bwwGX5_qruJPU0WXU2PniXEjl6EOPE,8746
15
- syncraft/walker.py,sha256=EoTSCCiaIPpBpsd6EcbFCw2_0jlDyNkemAeDoqA4Mus,7118
16
- syncraft-0.2.6.dist-info/licenses/LICENSE,sha256=wHSV424U5csa3339dy1AZbsz2xsd0hrkMx2QK48CcUk,1062
17
- syncraft-0.2.6.dist-info/METADATA,sha256=tFUXcscYjk8tgtahL7BPkTstoFN7o3rJgi2QL9z3y-s,1023
18
- syncraft-0.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- syncraft-0.2.6.dist-info/top_level.txt,sha256=Kq3t8ESXB2xW1Xt3uPmkENFc-c4f2pamNmaURBk7zc8,9
20
- syncraft-0.2.6.dist-info/RECORD,,