llparse 0.1.1__tar.gz → 0.1.3__tar.gz
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.
- {llparse-0.1.1 → llparse-0.1.3}/PKG-INFO +7 -4
- {llparse-0.1.1 → llparse-0.1.3}/README.md +6 -3
- {llparse-0.1.1 → llparse-0.1.3}/llparse/C_compiler.py +28 -30
- {llparse-0.1.1 → llparse-0.1.3}/llparse/compilator.py +5 -9
- {llparse-0.1.1 → llparse-0.1.3}/llparse/cython_builder.py +1 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/debug.py +0 -3
- {llparse-0.1.1 → llparse-0.1.3}/llparse/dot.py +0 -3
- llparse-0.1.3/llparse/errors.py +2 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/frontend.py +45 -51
- {llparse-0.1.1 → llparse-0.1.3}/llparse/llparse.py +19 -4
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pybuilder/loopchecker.py +80 -39
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pybuilder/main_code.py +27 -10
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pybuilder/parsemap.py +2 -6
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pyfront/front.py +3 -1
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pyfront/nodes.py +16 -19
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pyfront/peephole.py +1 -1
- {llparse-0.1.1 → llparse-0.1.3}/llparse/settings.py +0 -1
- {llparse-0.1.1 → llparse-0.1.3}/llparse/spanalloc.py +12 -27
- {llparse-0.1.1 → llparse-0.1.3}/llparse/test.py +1 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/trie.py +10 -21
- {llparse-0.1.1 → llparse-0.1.3}/llparse.egg-info/PKG-INFO +7 -4
- {llparse-0.1.1 → llparse-0.1.3}/llparse.egg-info/SOURCES.txt +5 -2
- {llparse-0.1.1 → llparse-0.1.3}/pyproject.toml +1 -1
- llparse-0.1.3/tests/test_frontend.py +25 -0
- llparse-0.1.3/tests/test_loop_checker.py +160 -0
- llparse-0.1.3/tests/test_span_allocator.py +121 -0
- llparse-0.1.1/llparse/tire.py +0 -158
- {llparse-0.1.1 → llparse-0.1.3}/LICENSE +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/__init__.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/constants.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/enumerator.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/header.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pybuilder/__init__.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pybuilder/builder.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pyfront/containers.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pyfront/implementation.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pyfront/namespace.py +2 -2
- {llparse-0.1.1 → llparse-0.1.3}/llparse/pyfront/transform.py +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse.egg-info/dependency_links.txt +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/llparse.egg-info/top_level.txt +0 -0
- {llparse-0.1.1 → llparse-0.1.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: llparse
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: A Parody of llparse written for writing C Parsers with Python
|
|
5
5
|
Author-email: Vizonex <VizonexBusiness@gmail.com>
|
|
6
6
|
Requires-Python: >=3.9
|
|
@@ -15,7 +15,7 @@ Dynamic: license-file
|
|
|
15
15
|
|
|
16
16
|
A python parody of the typescript library llparse.
|
|
17
17
|
|
|
18
|
-
I take no credit for the orginal work done by indutny and I was originally very nervous about making
|
|
18
|
+
I take no credit for the orginal work done by indutny and the other node-js contributors involved and I was originally very nervous about making
|
|
19
19
|
this python library that I made public...
|
|
20
20
|
|
|
21
21
|
Links to the original library
|
|
@@ -49,7 +49,7 @@ do it at your own risk. They maybe incompleted or not throughly stress-tested.
|
|
|
49
49
|
|
|
50
50
|
## New Features
|
|
51
51
|
- Throw me an issue if typescript llparse introduces something new that you want for me or another contributor to try and implement
|
|
52
|
-
just seeing llparse add new features is
|
|
52
|
+
just seeing llparse add new features is exciting to me.
|
|
53
53
|
|
|
54
54
|
- If you want a feature that typescript llparse doesn't have, be sure to try making a pull request over there as well and not just here,
|
|
55
55
|
there's a good chance they will appericate you for helping over there too and your helping make llhttp better by doing so. :)
|
|
@@ -62,7 +62,7 @@ there's a good chance they will appericate you for helping over there too and yo
|
|
|
62
62
|
- Make it easy for me or someone else to find a problem and solve it in typescript after testing it in python
|
|
63
63
|
- Typescript takes 2 commands to run a script with node-js it while python only takes one cutting the time required tremendously...
|
|
64
64
|
- The orginal project was MIT licensed.
|
|
65
|
-
- I wanted to write my own C
|
|
65
|
+
- I wanted to write my own C Parser tool with llhttp styled callbacks of my own using a language I was the most comfortable with using.
|
|
66
66
|
- I didn't like __Lemon Parser__ or __Yacc__ all that much and a good ide for handling them in Visual Studio Code with error checking to my knowlegde does not exist.
|
|
67
67
|
- The closest thing I got to what I wanted was a project named __NMFU__ shorthand for no memory for you and even I had problems with writing things using that library...
|
|
68
68
|
|
|
@@ -131,3 +131,6 @@ print(c.c)
|
|
|
131
131
|
open("http_parser.c", "w").write(c.c)
|
|
132
132
|
open("http_parser.h", "w").write(c.header)
|
|
133
133
|
```
|
|
134
|
+
|
|
135
|
+
## Video Showcasing this library
|
|
136
|
+
- https://youtu.be/YQOzJ2BghQw
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
A python parody of the typescript library llparse.
|
|
7
7
|
|
|
8
|
-
I take no credit for the orginal work done by indutny and I was originally very nervous about making
|
|
8
|
+
I take no credit for the orginal work done by indutny and the other node-js contributors involved and I was originally very nervous about making
|
|
9
9
|
this python library that I made public...
|
|
10
10
|
|
|
11
11
|
Links to the original library
|
|
@@ -39,7 +39,7 @@ do it at your own risk. They maybe incompleted or not throughly stress-tested.
|
|
|
39
39
|
|
|
40
40
|
## New Features
|
|
41
41
|
- Throw me an issue if typescript llparse introduces something new that you want for me or another contributor to try and implement
|
|
42
|
-
just seeing llparse add new features is
|
|
42
|
+
just seeing llparse add new features is exciting to me.
|
|
43
43
|
|
|
44
44
|
- If you want a feature that typescript llparse doesn't have, be sure to try making a pull request over there as well and not just here,
|
|
45
45
|
there's a good chance they will appericate you for helping over there too and your helping make llhttp better by doing so. :)
|
|
@@ -52,7 +52,7 @@ there's a good chance they will appericate you for helping over there too and yo
|
|
|
52
52
|
- Make it easy for me or someone else to find a problem and solve it in typescript after testing it in python
|
|
53
53
|
- Typescript takes 2 commands to run a script with node-js it while python only takes one cutting the time required tremendously...
|
|
54
54
|
- The orginal project was MIT licensed.
|
|
55
|
-
- I wanted to write my own C
|
|
55
|
+
- I wanted to write my own C Parser tool with llhttp styled callbacks of my own using a language I was the most comfortable with using.
|
|
56
56
|
- I didn't like __Lemon Parser__ or __Yacc__ all that much and a good ide for handling them in Visual Studio Code with error checking to my knowlegde does not exist.
|
|
57
57
|
- The closest thing I got to what I wanted was a project named __NMFU__ shorthand for no memory for you and even I had problems with writing things using that library...
|
|
58
58
|
|
|
@@ -121,3 +121,6 @@ print(c.c)
|
|
|
121
121
|
open("http_parser.c", "w").write(c.c)
|
|
122
122
|
open("http_parser.h", "w").write(c.header)
|
|
123
123
|
```
|
|
124
|
+
|
|
125
|
+
## Video Showcasing this library
|
|
126
|
+
- https://youtu.be/YQOzJ2BghQw
|
|
@@ -29,32 +29,32 @@ class CCompiler:
|
|
|
29
29
|
out.append("#include <string.h>")
|
|
30
30
|
out.append("")
|
|
31
31
|
# Seems LLParse was updated from /* UNREACHABLE */ abort(); to a Macro, Intresting...
|
|
32
|
-
out.append(
|
|
33
|
-
out.append(
|
|
34
|
-
out.append(
|
|
35
|
-
out.append(
|
|
36
|
-
out.append(
|
|
37
|
-
out.append(
|
|
38
|
-
out.append(
|
|
39
|
-
out.append(
|
|
40
|
-
|
|
41
|
-
out.append(
|
|
42
|
-
out.append(
|
|
43
|
-
out.append(
|
|
44
|
-
out.append(
|
|
45
|
-
|
|
46
|
-
out.append(
|
|
47
|
-
out.append(
|
|
48
|
-
out.append(
|
|
49
|
-
out.append(
|
|
50
|
-
|
|
51
|
-
out.append(
|
|
52
|
-
out.append(
|
|
53
|
-
out.append(
|
|
54
|
-
out.append(
|
|
55
|
-
out.append(
|
|
56
|
-
out.append(
|
|
57
|
-
out.append(
|
|
32
|
+
out.append("#ifdef __SSE4_2__")
|
|
33
|
+
out.append(" #ifdef _MSC_VER")
|
|
34
|
+
out.append(" #include <nmmintrin.h>")
|
|
35
|
+
out.append(" #else /* !_MSC_VER */")
|
|
36
|
+
out.append(" #include <x86intrin.h>")
|
|
37
|
+
out.append(" #endif /* _MSC_VER */")
|
|
38
|
+
out.append("#endif /* __SSE4_2__ */")
|
|
39
|
+
out.append("")
|
|
40
|
+
|
|
41
|
+
out.append("#ifdef __ARM_NEON__")
|
|
42
|
+
out.append(" #include <arm_neon.h>")
|
|
43
|
+
out.append("#endif /* __ARM_NEON__ */")
|
|
44
|
+
out.append("")
|
|
45
|
+
|
|
46
|
+
out.append("#ifdef __wasm__")
|
|
47
|
+
out.append(" #include <wasm_simd128.h>")
|
|
48
|
+
out.append("#endif /* __wasm__ */")
|
|
49
|
+
out.append("")
|
|
50
|
+
|
|
51
|
+
out.append("#ifdef _MSC_VER")
|
|
52
|
+
out.append(" #define ALIGN(n) _declspec(align(n))")
|
|
53
|
+
out.append(" #define UNREACHABLE __assume(0)")
|
|
54
|
+
out.append("#else /* !_MSC_VER */")
|
|
55
|
+
out.append(" #define ALIGN(n) __attribute__((aligned(n)))")
|
|
56
|
+
out.append(" #define UNREACHABLE __builtin_unreachable()")
|
|
57
|
+
out.append("#endif /* _MSC_VER */")
|
|
58
58
|
|
|
59
59
|
out.append("")
|
|
60
60
|
out.append(
|
|
@@ -83,7 +83,7 @@ class CCompiler:
|
|
|
83
83
|
out.append("}")
|
|
84
84
|
out.append("")
|
|
85
85
|
|
|
86
|
-
# TODO (Vizonex) Make llparse_state_t's Name Optional and alterable incase mixed with
|
|
86
|
+
# TODO (Vizonex) Make llparse_state_t's Name Optional and alterable incase mixed with
|
|
87
87
|
# llhttp or another parser
|
|
88
88
|
out.append(f"static llparse_state_t {info.prefix}__run(")
|
|
89
89
|
out.append(f" {info.prefix}_t* {ARG_STATE},")
|
|
@@ -182,9 +182,7 @@ class CCompiler:
|
|
|
182
182
|
else:
|
|
183
183
|
# TODO (Vizonex) Merge lines 139 & 140 together in a future update
|
|
184
184
|
callback = (
|
|
185
|
-
f"(({info.prefix}__span_cb)"
|
|
186
|
-
+ ctx.spanCbField(span.index)
|
|
187
|
-
+ f")"
|
|
185
|
+
f"(({info.prefix}__span_cb)" + ctx.spanCbField(span.index) + f")"
|
|
188
186
|
)
|
|
189
187
|
|
|
190
188
|
args = [ctx.stateArg(), posField, f"(const char*) {ctx.endPosArg()}"]
|
|
@@ -170,7 +170,7 @@ class Load(Field):
|
|
|
170
170
|
def doBuild(self, ctx: "Compilation", out: list[str]):
|
|
171
171
|
out.append(f"return {self.field(ctx)};")
|
|
172
172
|
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
# BIG ONE
|
|
175
175
|
|
|
176
176
|
|
|
@@ -374,7 +374,6 @@ class Consume(Node):
|
|
|
374
374
|
index = ctx.stateField(self.ref.field)
|
|
375
375
|
ty = ctx.getFieldType(self.ref.field)
|
|
376
376
|
|
|
377
|
-
|
|
378
377
|
if ty == "i64":
|
|
379
378
|
pass
|
|
380
379
|
elif ty == "i32":
|
|
@@ -412,7 +411,6 @@ class Empty(Node):
|
|
|
412
411
|
def __init__(self, ref: _frontend.node.Empty) -> None:
|
|
413
412
|
self.ref = ref
|
|
414
413
|
super().__init__(ref)
|
|
415
|
-
|
|
416
414
|
|
|
417
415
|
def doBuild(self, out: list[str]):
|
|
418
416
|
assert self.ref.otherwise
|
|
@@ -574,7 +572,7 @@ class Single(Node):
|
|
|
574
572
|
else:
|
|
575
573
|
ch = f"'{chr(e.key)}'"
|
|
576
574
|
|
|
577
|
-
out.append(f" case {ch}:" + "{")
|
|
575
|
+
out.append(f" case {ch}: " + "{")
|
|
578
576
|
tmp: list[str] = []
|
|
579
577
|
|
|
580
578
|
# For now debug everything....
|
|
@@ -884,7 +882,7 @@ class Compilation:
|
|
|
884
882
|
def buildStateEnum(self, out: list[str]):
|
|
885
883
|
# TODO (Vizonex) Give out other names that you could pass as an enum statename
|
|
886
884
|
# this is incase multiple llparse_state_e states are given to compile
|
|
887
|
-
# example would be mixing llhttp with some other source...
|
|
885
|
+
# example would be mixing llhttp with some other source...
|
|
888
886
|
out.append("enum llparse_state_e {")
|
|
889
887
|
out.append(f" {STATE_ERROR},")
|
|
890
888
|
for stateName in self.stateDict.keys():
|
|
@@ -992,8 +990,7 @@ class Compilation:
|
|
|
992
990
|
out.append(f"{LABEL_PREFIX}{name} : " + "{")
|
|
993
991
|
for line in lines:
|
|
994
992
|
out.append(f" {line}")
|
|
995
|
-
out.append("
|
|
996
|
-
out.append(" abort();")
|
|
993
|
+
out.append(" UNREACHABLE;")
|
|
997
994
|
out.append("}")
|
|
998
995
|
|
|
999
996
|
def buildInternalStates(self, out: list[str]):
|
|
@@ -1004,8 +1001,7 @@ class Compilation:
|
|
|
1004
1001
|
out.append(f"{LABEL_PREFIX}{name}: " + "{")
|
|
1005
1002
|
for line in lines:
|
|
1006
1003
|
out.append(f" {line}")
|
|
1007
|
-
out.append("
|
|
1008
|
-
out.append(" abort();")
|
|
1004
|
+
out.append(" UNREACHABLE;")
|
|
1009
1005
|
out.append("}")
|
|
1010
1006
|
|
|
1011
1007
|
def addState(self, state: str, lines: list[str]):
|
|
@@ -4,6 +4,7 @@ from typing import Literal, Optional, Union
|
|
|
4
4
|
from .enumerator import Enumerator
|
|
5
5
|
from .pybuilder import LoopChecker
|
|
6
6
|
from .pybuilder import builder as source
|
|
7
|
+
|
|
7
8
|
# from pyfront.namespace import code, node , transform
|
|
8
9
|
from .pyfront import namespace as _frontend
|
|
9
10
|
from .pyfront.front import Identifier, IWrap, SpanField
|
|
@@ -11,19 +12,20 @@ from .pyfront.implementation import IImplementation
|
|
|
11
12
|
from .pyfront.nodes import ITableEdge
|
|
12
13
|
from .pyfront.peephole import Peephole
|
|
13
14
|
from .spanalloc import SpanAllocator
|
|
14
|
-
from .trie import Trie, TrieEmpty, TrieNode, TrieSequence, TrieSingle
|
|
15
|
+
from .trie import Trie, TrieEmpty, TrieNode, TrieSequence, TrieSingle, ITrieSingleChild
|
|
15
16
|
|
|
16
17
|
DEFAULT_MIN_TABLE_SIZE = 32
|
|
17
18
|
DEFAULT_MAX_TABLE_WIDTH = 4
|
|
18
19
|
|
|
20
|
+
from logging import getLogger
|
|
21
|
+
|
|
22
|
+
log = getLogger("llparse.frontend")
|
|
19
23
|
|
|
20
24
|
|
|
21
25
|
WrappedNode = IWrap[_frontend.node.Node]
|
|
22
26
|
WrappedCode = IWrap[_frontend.code.Code]
|
|
23
27
|
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
29
|
@dataclass
|
|
28
30
|
class ITableLookupTarget:
|
|
29
31
|
trie: TrieEmpty
|
|
@@ -168,7 +170,7 @@ class Frontend:
|
|
|
168
170
|
trieNode = trie.build(list(node))
|
|
169
171
|
|
|
170
172
|
if not trieNode:
|
|
171
|
-
|
|
173
|
+
log.debug("TrieNode was nonexistant")
|
|
172
174
|
return self.implementation.node.Empty(
|
|
173
175
|
_frontend.node.Empty(self.Id.id(node.name))
|
|
174
176
|
)
|
|
@@ -180,7 +182,7 @@ class Frontend:
|
|
|
180
182
|
|
|
181
183
|
return children
|
|
182
184
|
|
|
183
|
-
def registerNode(self, node: WrappedNode):
|
|
185
|
+
def registerNode(self, node: WrappedNode) -> None:
|
|
184
186
|
# NOTE NO Implementations required here since this is python!
|
|
185
187
|
if isinstance(
|
|
186
188
|
node.ref,
|
|
@@ -289,7 +291,6 @@ class Frontend:
|
|
|
289
291
|
|
|
290
292
|
if isinstance(single.ref, _frontend.node.Invoke):
|
|
291
293
|
for edge in node:
|
|
292
|
-
# print(edge.key)
|
|
293
294
|
single.ref.addEdge(
|
|
294
295
|
ord(edge.key) if isinstance(edge.key, str) else edge.key,
|
|
295
296
|
self.translate(edge.node),
|
|
@@ -306,52 +307,48 @@ class Frontend:
|
|
|
306
307
|
return None
|
|
307
308
|
|
|
308
309
|
targets: dict[source.code.Node, ITableLookupTarget] = {}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
empty
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
bailout = False
|
|
325
|
-
continue
|
|
310
|
+
|
|
311
|
+
def check_child(child: ITrieSingleChild):
|
|
312
|
+
nonlocal targets
|
|
313
|
+
if not isinstance(child.node, TrieEmpty):
|
|
314
|
+
log.debug(
|
|
315
|
+
'non-leaf trie child of "%s" prevents table allocation' % node.name
|
|
316
|
+
)
|
|
317
|
+
return False
|
|
318
|
+
empty = child.node
|
|
319
|
+
if empty.value is not None:
|
|
320
|
+
log.debug(
|
|
321
|
+
'value passing trie leaf of "%s" prevents table allocation'
|
|
322
|
+
% node.name
|
|
323
|
+
)
|
|
324
|
+
return False
|
|
326
325
|
|
|
327
326
|
target = empty.node
|
|
328
|
-
if not targets
|
|
327
|
+
if target not in targets:
|
|
329
328
|
targets[target] = ITableLookupTarget(
|
|
330
329
|
keys=[child.key], noAdvance=child.noAdvance, trie=empty
|
|
331
330
|
)
|
|
332
|
-
|
|
333
|
-
break
|
|
331
|
+
return True
|
|
334
332
|
|
|
335
333
|
existing = targets[target]
|
|
336
|
-
|
|
337
334
|
if existing.noAdvance != child.noAdvance:
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
335
|
+
log.debug(
|
|
336
|
+
f'noAdvance mismatch in a trie leaf of "{node.name}" prevents '
|
|
337
|
+
"table allocation"
|
|
338
|
+
)
|
|
339
|
+
return False
|
|
342
340
|
existing.keys.append(child.key)
|
|
341
|
+
return True
|
|
343
342
|
|
|
344
|
-
|
|
345
|
-
bailout = True
|
|
346
|
-
break
|
|
347
|
-
|
|
348
|
-
# assert len(trie.children) == len(targets), "Something went wrong"
|
|
349
|
-
if bailout:
|
|
343
|
+
if not all([check_child(child) for child in trie.children]):
|
|
350
344
|
return
|
|
351
345
|
|
|
352
346
|
# Weave width limit for optimization...
|
|
353
|
-
if len(targets
|
|
354
|
-
|
|
347
|
+
if len(targets) >= (1 << self.options["maxTableElemWidth"]):
|
|
348
|
+
log.debug(
|
|
349
|
+
'too many different trie targets of "%s" for a table allocation'
|
|
350
|
+
% node.name
|
|
351
|
+
)
|
|
355
352
|
return
|
|
356
353
|
|
|
357
354
|
table = self.implementation.node.TableLookup(
|
|
@@ -360,11 +357,11 @@ class Frontend:
|
|
|
360
357
|
children.append(table)
|
|
361
358
|
|
|
362
359
|
# Break Loop
|
|
363
|
-
if self.Map.get(node):
|
|
360
|
+
if not self.Map.get(node):
|
|
364
361
|
self.Map[node] = table
|
|
365
362
|
|
|
366
363
|
for target in targets.values():
|
|
367
|
-
_next = self.translateTrie(node, target, children)
|
|
364
|
+
_next = self.translateTrie(node, target.trie, children)
|
|
368
365
|
table.ref.addEdge(
|
|
369
366
|
ITableEdge(keys=target.keys, noAdvance=target.noAdvance, node=_next)
|
|
370
367
|
)
|
|
@@ -410,9 +407,7 @@ class Frontend:
|
|
|
410
407
|
self, node: source.code.Match, trie: TrieSingle, children: MatchChildren
|
|
411
408
|
):
|
|
412
409
|
# Check if Tablelookup could be a valid option to Optimze our code up...
|
|
413
|
-
maybeTable
|
|
414
|
-
|
|
415
|
-
if maybeTable:
|
|
410
|
+
if maybeTable := self.maybeTableLookup(node, trie, children):
|
|
416
411
|
return maybeTable
|
|
417
412
|
|
|
418
413
|
single = self.implementation.node.Single(
|
|
@@ -434,8 +429,7 @@ class Frontend:
|
|
|
434
429
|
value=child.node.value if isinstance(child.node, TrieEmpty) else None,
|
|
435
430
|
)
|
|
436
431
|
|
|
437
|
-
otherwise
|
|
438
|
-
if otherwise:
|
|
432
|
+
if otherwise := trie.otherwise:
|
|
439
433
|
single.ref.setOtherwise(
|
|
440
434
|
self.translateTrie(node, otherwise, children), True, otherwise.value
|
|
441
435
|
)
|
|
@@ -444,8 +438,9 @@ class Frontend:
|
|
|
444
438
|
def translateSpanCode(self, code: source.code._Span):
|
|
445
439
|
return self.translateCode(code)
|
|
446
440
|
|
|
447
|
-
|
|
448
|
-
|
|
441
|
+
def translateCode(
|
|
442
|
+
self, code: source.code.Code
|
|
443
|
+
):
|
|
449
444
|
"""Translates Builder Classes to Frontend Classes..."""
|
|
450
445
|
|
|
451
446
|
prefixed = self.codeId.id(code.name).name
|
|
@@ -501,9 +496,8 @@ class Frontend:
|
|
|
501
496
|
else:
|
|
502
497
|
raise Exception(f'UnSupported code:"{code.name}" type: "{type(code)}"')
|
|
503
498
|
|
|
504
|
-
if self.codeCache.get(res.ref.cacheKey):
|
|
505
|
-
return
|
|
506
|
-
|
|
499
|
+
if _res := self.codeCache.get(res.ref.cacheKey):
|
|
500
|
+
return _res
|
|
507
501
|
self.codeCache[res.ref.cacheKey] = res
|
|
508
502
|
return res
|
|
509
503
|
|
|
@@ -4,8 +4,13 @@ from dataclasses import dataclass
|
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
6
|
from .C_compiler import CCompiler
|
|
7
|
-
from .frontend import (
|
|
8
|
-
|
|
7
|
+
from .frontend import (
|
|
8
|
+
DEFAULT_MAX_TABLE_WIDTH,
|
|
9
|
+
DEFAULT_MIN_TABLE_SIZE,
|
|
10
|
+
Frontend,
|
|
11
|
+
IImplementation,
|
|
12
|
+
source,
|
|
13
|
+
)
|
|
9
14
|
from .header import HeaderBuilder
|
|
10
15
|
|
|
11
16
|
|
|
@@ -62,12 +67,20 @@ class Compiler:
|
|
|
62
67
|
properties: list[source.Property],
|
|
63
68
|
header_name: Optional[str] = None,
|
|
64
69
|
Impl: Optional[IImplementation] = IImplementation(),
|
|
70
|
+
override_llparse_name: bool = False
|
|
65
71
|
):
|
|
66
72
|
"""Creates the C and header file..."""
|
|
67
73
|
info = self.to_frontend(root, properties, Impl)
|
|
68
74
|
hb = HeaderBuilder(self.prefix, self.headerGuard, properties, info.spans)
|
|
75
|
+
cdata = CCompiler(header_name, self.debug).compile(info)
|
|
76
|
+
if override_llparse_name:
|
|
77
|
+
# sometimes users want to combine parsers together when compiling with C
|
|
78
|
+
# to make up for conflicts with other parsers example: llhttp
|
|
79
|
+
# there should be a fair way of compiling everything.
|
|
80
|
+
cdata = cdata.replace('llparse', self.prefix)
|
|
81
|
+
|
|
69
82
|
return CompilerResult(
|
|
70
|
-
|
|
83
|
+
cdata , hb.build()
|
|
71
84
|
)
|
|
72
85
|
|
|
73
86
|
|
|
@@ -117,6 +130,7 @@ class LLParse(source.Builder):
|
|
|
117
130
|
maxTableElemWidth: Optional[int] = None,
|
|
118
131
|
minTableSize: Optional[int] = None,
|
|
119
132
|
header_name: Optional[str] = None,
|
|
133
|
+
override_llparse_name:bool = False
|
|
120
134
|
):
|
|
121
135
|
"""Builds Graph and then compiles the data into C code , returns with the header and C file inside of a Dataclass"""
|
|
122
136
|
|
|
@@ -128,7 +142,8 @@ class LLParse(source.Builder):
|
|
|
128
142
|
minTableSize if minTableSize else DEFAULT_MIN_TABLE_SIZE,
|
|
129
143
|
)
|
|
130
144
|
|
|
131
|
-
return compiler.compile(root, self.properties(), header_name=header_name)
|
|
145
|
+
return compiler.compile(root, self.properties(), header_name=header_name, override_llparse_name=override_llparse_name)
|
|
146
|
+
|
|
132
147
|
|
|
133
148
|
def to_frontend(
|
|
134
149
|
self,
|