[sql] SQL "works" but it's too dang slow
This commit is contained in:
parent
c23dbe3e8f
commit
2d10e91f9e
4 changed files with 1218 additions and 452 deletions
|
|
@ -129,14 +129,17 @@ function render_state(state, input_editor) {
|
|||
* otherwise just queue it for submission.
|
||||
*/
|
||||
function post_document(worker, kind, state, document) {
|
||||
console.log("Received document", kind)
|
||||
if (window.localStorage) {
|
||||
window.localStorage.setItem(kind, document);
|
||||
}
|
||||
|
||||
let new_state = {...state};
|
||||
if (new_state.pending) {
|
||||
console.log("Document parked", kind)
|
||||
new_state.next = document;
|
||||
} else {
|
||||
console.log("Document submitted", kind)
|
||||
new_state.pending = document;
|
||||
new_state.next = null;
|
||||
worker.postMessage({kind, data: document});
|
||||
|
|
@ -151,6 +154,7 @@ function post_document(worker, kind, state, document) {
|
|||
function rotate_document(worker, kind, state) {
|
||||
let new_state = {...state, last: state.pending, pending: null};
|
||||
if (new_state.next) {
|
||||
console.log("Rotating document", kind)
|
||||
new_state.pending = new_state.next;
|
||||
new_state.next = null;
|
||||
worker.postMessage({kind, data: new_state.pending});
|
||||
|
|
|
|||
|
|
@ -176,19 +176,21 @@ const pyodide_promise = setup_python();
|
|||
async function load_grammar_module(code) {
|
||||
const pyodide = self.pyodide;
|
||||
|
||||
// console.log("Running...");
|
||||
console.log("eval_grammar: Running");
|
||||
const my_fn = pyodide.globals.get("eval_grammar");
|
||||
my_fn(code);
|
||||
my_fn.destroy();
|
||||
console.log("eval_grammar: Done");
|
||||
}
|
||||
|
||||
async function parse_document(code) {
|
||||
const pyodide = self.pyodide;
|
||||
|
||||
// console.log("Running...");
|
||||
console.log("eval_document: Running");
|
||||
const my_fn = pyodide.globals.get("eval_document");
|
||||
my_fn(code);
|
||||
my_fn.destroy();
|
||||
console.log("eval_document: Done");
|
||||
}
|
||||
|
||||
self.onmessage = async function(event) {
|
||||
|
|
@ -197,8 +199,10 @@ self.onmessage = async function(event) {
|
|||
try {
|
||||
const { kind, data } = event.data;
|
||||
if (kind === "grammar") {
|
||||
console.log("Worker received grammar")
|
||||
await load_grammar_module(data);
|
||||
} else if (kind === "input") {
|
||||
console.log("Worker received input")
|
||||
await parse_document(data);
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
|||
1602
examples/sql.py
1602
examples/sql.py
File diff suppressed because it is too large
Load diff
|
|
@ -1116,7 +1116,9 @@ class ParserGenerator:
|
|||
|
||||
# Check to make sure they didn't use anything that will give us
|
||||
# heartburn later.
|
||||
reserved = [a for a in alphabet if (a.startswith("__") and not a.startswith("__gen_")) or a == "$"]
|
||||
reserved = [
|
||||
a for a in alphabet if (a.startswith("__") and not a.startswith("__gen_")) or a == "$"
|
||||
]
|
||||
if reserved:
|
||||
raise ValueError(
|
||||
"Can't use {symbols} in grammars, {what} reserved.".format(
|
||||
|
|
@ -1619,6 +1621,7 @@ class Terminal(Rule):
|
|||
_CURRENT_DEFINITION: str = "__global"
|
||||
_CURRENT_GEN_INDEX: int = 0
|
||||
|
||||
|
||||
class NonTerminal(Rule):
|
||||
"""A non-terminal, or a production, in the grammar.
|
||||
|
||||
|
|
@ -1699,7 +1702,6 @@ class NonTerminal(Rule):
|
|||
_CURRENT_DEFINITION = prev_defn
|
||||
_CURRENT_GEN_INDEX = prev_idx
|
||||
|
||||
|
||||
return self._body
|
||||
|
||||
def flatten(
|
||||
|
|
@ -1827,10 +1829,11 @@ def one_or_more(*args: Rule) -> Rule:
|
|||
global _CURRENT_DEFINITION
|
||||
global _CURRENT_GEN_INDEX
|
||||
|
||||
tail : NonTerminal | None = None
|
||||
tail: NonTerminal | None = None
|
||||
|
||||
def impl() -> Rule:
|
||||
nonlocal tail
|
||||
assert(tail is not None)
|
||||
assert tail is not None
|
||||
return opt(tail) + seq(*args)
|
||||
|
||||
tail = NonTerminal(
|
||||
|
|
@ -1842,6 +1845,7 @@ def one_or_more(*args: Rule) -> Rule:
|
|||
|
||||
return tail
|
||||
|
||||
|
||||
def zero_or_more(*args: Rule) -> Rule:
|
||||
"""Generate a rule that matches a repetition of zero or more of the specified
|
||||
rule.
|
||||
|
|
@ -1852,6 +1856,7 @@ def zero_or_more(*args: Rule) -> Rule:
|
|||
"""
|
||||
return opt(one_or_more(*args))
|
||||
|
||||
|
||||
@typing.overload
|
||||
def rule(f: typing.Callable, /) -> NonTerminal: ...
|
||||
|
||||
|
|
@ -2848,9 +2853,12 @@ class TriviaMode(enum.Enum):
|
|||
# Finally, the grammar class.
|
||||
###############################################################################
|
||||
|
||||
PrecedenceList = list[typing.Tuple[Assoc, list[Terminal|NonTerminal]]]
|
||||
PrecedenceList = list[typing.Tuple[Assoc, list[Terminal | NonTerminal]]]
|
||||
|
||||
def gather_grammar(start: NonTerminal, trivia: list[Terminal]) -> tuple[dict[str,NonTerminal], dict[str,Terminal]]:
|
||||
|
||||
def gather_grammar(
|
||||
start: NonTerminal, trivia: list[Terminal]
|
||||
) -> tuple[dict[str, NonTerminal], dict[str, Terminal]]:
|
||||
"""Starting from the given NonTerminal, gather all of the symbols
|
||||
(NonTerminals and Terminals) that make up the grammar.
|
||||
"""
|
||||
|
|
@ -2894,9 +2902,11 @@ def gather_grammar(start: NonTerminal, trivia: list[Terminal]) -> tuple[dict[str
|
|||
existing = named_rules.get(rule.name)
|
||||
if existing is not None:
|
||||
# TODO TEST
|
||||
raise ValueError(f"""Found more than one rule named {rule.name}:
|
||||
raise ValueError(
|
||||
f"""Found more than one rule named {rule.name}:
|
||||
- {existing.definition_location}
|
||||
- {rule.definition_location}""")
|
||||
- {rule.definition_location}"""
|
||||
)
|
||||
named_rules[rule.name] = rule
|
||||
|
||||
named_terminals: dict[str, Terminal] = {}
|
||||
|
|
@ -2904,16 +2914,20 @@ def gather_grammar(start: NonTerminal, trivia: list[Terminal]) -> tuple[dict[str
|
|||
existing = named_terminals.get(terminal.name)
|
||||
if existing is not None:
|
||||
# TODO TEST
|
||||
raise ValueError(f"""Found more than one terminal named {terminal.name}:
|
||||
raise ValueError(
|
||||
f"""Found more than one terminal named {terminal.name}:
|
||||
- {existing.definition_location}
|
||||
- {terminal.definition_location}""")
|
||||
- {terminal.definition_location}"""
|
||||
)
|
||||
|
||||
existing_rule = named_rules.get(terminal.name)
|
||||
if existing_rule is not None:
|
||||
# TODO TEST
|
||||
raise ValueError(f"""Found a terminal and a rule both named {terminal.name}:
|
||||
raise ValueError(
|
||||
f"""Found a terminal and a rule both named {terminal.name}:
|
||||
- The rule was defined at {existing_rule.definition_location}
|
||||
- The terminal was defined at {terminal.definition_location}""")
|
||||
- The terminal was defined at {terminal.definition_location}"""
|
||||
)
|
||||
|
||||
named_terminals[terminal.name] = terminal
|
||||
|
||||
|
|
@ -3010,7 +3024,7 @@ class Grammar:
|
|||
generate_nonterminal_dict- less useful to people, probably, but it is
|
||||
the input form needed by the Generator.
|
||||
"""
|
||||
grammar: list[tuple[str,list[str]]] = [
|
||||
grammar: list[tuple[str, list[str]]] = [
|
||||
(rule.name, [s.name for s in production])
|
||||
for rule in self._nonterminals.values()
|
||||
for production in rule.body
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue