[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.
|
* otherwise just queue it for submission.
|
||||||
*/
|
*/
|
||||||
function post_document(worker, kind, state, document) {
|
function post_document(worker, kind, state, document) {
|
||||||
|
console.log("Received document", kind)
|
||||||
if (window.localStorage) {
|
if (window.localStorage) {
|
||||||
window.localStorage.setItem(kind, document);
|
window.localStorage.setItem(kind, document);
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_state = {...state};
|
let new_state = {...state};
|
||||||
if (new_state.pending) {
|
if (new_state.pending) {
|
||||||
|
console.log("Document parked", kind)
|
||||||
new_state.next = document;
|
new_state.next = document;
|
||||||
} else {
|
} else {
|
||||||
|
console.log("Document submitted", kind)
|
||||||
new_state.pending = document;
|
new_state.pending = document;
|
||||||
new_state.next = null;
|
new_state.next = null;
|
||||||
worker.postMessage({kind, data: document});
|
worker.postMessage({kind, data: document});
|
||||||
|
|
@ -151,6 +154,7 @@ function post_document(worker, kind, state, document) {
|
||||||
function rotate_document(worker, kind, state) {
|
function rotate_document(worker, kind, state) {
|
||||||
let new_state = {...state, last: state.pending, pending: null};
|
let new_state = {...state, last: state.pending, pending: null};
|
||||||
if (new_state.next) {
|
if (new_state.next) {
|
||||||
|
console.log("Rotating document", kind)
|
||||||
new_state.pending = new_state.next;
|
new_state.pending = new_state.next;
|
||||||
new_state.next = null;
|
new_state.next = null;
|
||||||
worker.postMessage({kind, data: new_state.pending});
|
worker.postMessage({kind, data: new_state.pending});
|
||||||
|
|
|
||||||
|
|
@ -176,19 +176,21 @@ const pyodide_promise = setup_python();
|
||||||
async function load_grammar_module(code) {
|
async function load_grammar_module(code) {
|
||||||
const pyodide = self.pyodide;
|
const pyodide = self.pyodide;
|
||||||
|
|
||||||
// console.log("Running...");
|
console.log("eval_grammar: Running");
|
||||||
const my_fn = pyodide.globals.get("eval_grammar");
|
const my_fn = pyodide.globals.get("eval_grammar");
|
||||||
my_fn(code);
|
my_fn(code);
|
||||||
my_fn.destroy();
|
my_fn.destroy();
|
||||||
|
console.log("eval_grammar: Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function parse_document(code) {
|
async function parse_document(code) {
|
||||||
const pyodide = self.pyodide;
|
const pyodide = self.pyodide;
|
||||||
|
|
||||||
// console.log("Running...");
|
console.log("eval_document: Running");
|
||||||
const my_fn = pyodide.globals.get("eval_document");
|
const my_fn = pyodide.globals.get("eval_document");
|
||||||
my_fn(code);
|
my_fn(code);
|
||||||
my_fn.destroy();
|
my_fn.destroy();
|
||||||
|
console.log("eval_document: Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.onmessage = async function(event) {
|
self.onmessage = async function(event) {
|
||||||
|
|
@ -197,8 +199,10 @@ self.onmessage = async function(event) {
|
||||||
try {
|
try {
|
||||||
const { kind, data } = event.data;
|
const { kind, data } = event.data;
|
||||||
if (kind === "grammar") {
|
if (kind === "grammar") {
|
||||||
|
console.log("Worker received grammar")
|
||||||
await load_grammar_module(data);
|
await load_grammar_module(data);
|
||||||
} else if (kind === "input") {
|
} else if (kind === "input") {
|
||||||
|
console.log("Worker received input")
|
||||||
await parse_document(data);
|
await parse_document(data);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
||||||
1618
examples/sql.py
1618
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
|
# Check to make sure they didn't use anything that will give us
|
||||||
# heartburn later.
|
# 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:
|
if reserved:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Can't use {symbols} in grammars, {what} reserved.".format(
|
"Can't use {symbols} in grammars, {what} reserved.".format(
|
||||||
|
|
@ -1619,6 +1621,7 @@ class Terminal(Rule):
|
||||||
_CURRENT_DEFINITION: str = "__global"
|
_CURRENT_DEFINITION: str = "__global"
|
||||||
_CURRENT_GEN_INDEX: int = 0
|
_CURRENT_GEN_INDEX: int = 0
|
||||||
|
|
||||||
|
|
||||||
class NonTerminal(Rule):
|
class NonTerminal(Rule):
|
||||||
"""A non-terminal, or a production, in the grammar.
|
"""A non-terminal, or a production, in the grammar.
|
||||||
|
|
||||||
|
|
@ -1699,7 +1702,6 @@ class NonTerminal(Rule):
|
||||||
_CURRENT_DEFINITION = prev_defn
|
_CURRENT_DEFINITION = prev_defn
|
||||||
_CURRENT_GEN_INDEX = prev_idx
|
_CURRENT_GEN_INDEX = prev_idx
|
||||||
|
|
||||||
|
|
||||||
return self._body
|
return self._body
|
||||||
|
|
||||||
def flatten(
|
def flatten(
|
||||||
|
|
@ -1827,10 +1829,11 @@ def one_or_more(*args: Rule) -> Rule:
|
||||||
global _CURRENT_DEFINITION
|
global _CURRENT_DEFINITION
|
||||||
global _CURRENT_GEN_INDEX
|
global _CURRENT_GEN_INDEX
|
||||||
|
|
||||||
tail : NonTerminal | None = None
|
tail: NonTerminal | None = None
|
||||||
|
|
||||||
def impl() -> Rule:
|
def impl() -> Rule:
|
||||||
nonlocal tail
|
nonlocal tail
|
||||||
assert(tail is not None)
|
assert tail is not None
|
||||||
return opt(tail) + seq(*args)
|
return opt(tail) + seq(*args)
|
||||||
|
|
||||||
tail = NonTerminal(
|
tail = NonTerminal(
|
||||||
|
|
@ -1842,6 +1845,7 @@ def one_or_more(*args: Rule) -> Rule:
|
||||||
|
|
||||||
return tail
|
return tail
|
||||||
|
|
||||||
|
|
||||||
def zero_or_more(*args: Rule) -> Rule:
|
def zero_or_more(*args: Rule) -> Rule:
|
||||||
"""Generate a rule that matches a repetition of zero or more of the specified
|
"""Generate a rule that matches a repetition of zero or more of the specified
|
||||||
rule.
|
rule.
|
||||||
|
|
@ -1852,6 +1856,7 @@ def zero_or_more(*args: Rule) -> Rule:
|
||||||
"""
|
"""
|
||||||
return opt(one_or_more(*args))
|
return opt(one_or_more(*args))
|
||||||
|
|
||||||
|
|
||||||
@typing.overload
|
@typing.overload
|
||||||
def rule(f: typing.Callable, /) -> NonTerminal: ...
|
def rule(f: typing.Callable, /) -> NonTerminal: ...
|
||||||
|
|
||||||
|
|
@ -2848,9 +2853,12 @@ class TriviaMode(enum.Enum):
|
||||||
# Finally, the grammar class.
|
# 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
|
"""Starting from the given NonTerminal, gather all of the symbols
|
||||||
(NonTerminals and Terminals) that make up the grammar.
|
(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)
|
existing = named_rules.get(rule.name)
|
||||||
if existing is not None:
|
if existing is not None:
|
||||||
# TODO TEST
|
# 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}
|
- {existing.definition_location}
|
||||||
- {rule.definition_location}""")
|
- {rule.definition_location}"""
|
||||||
|
)
|
||||||
named_rules[rule.name] = rule
|
named_rules[rule.name] = rule
|
||||||
|
|
||||||
named_terminals: dict[str, Terminal] = {}
|
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)
|
existing = named_terminals.get(terminal.name)
|
||||||
if existing is not None:
|
if existing is not None:
|
||||||
# TODO TEST
|
# 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}
|
- {existing.definition_location}
|
||||||
- {terminal.definition_location}""")
|
- {terminal.definition_location}"""
|
||||||
|
)
|
||||||
|
|
||||||
existing_rule = named_rules.get(terminal.name)
|
existing_rule = named_rules.get(terminal.name)
|
||||||
if existing_rule is not None:
|
if existing_rule is not None:
|
||||||
# TODO TEST
|
# 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 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
|
named_terminals[terminal.name] = terminal
|
||||||
|
|
||||||
|
|
@ -3010,7 +3024,7 @@ class Grammar:
|
||||||
generate_nonterminal_dict- less useful to people, probably, but it is
|
generate_nonterminal_dict- less useful to people, probably, but it is
|
||||||
the input form needed by the Generator.
|
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])
|
(rule.name, [s.name for s in production])
|
||||||
for rule in self._nonterminals.values()
|
for rule in self._nonterminals.values()
|
||||||
for production in rule.body
|
for production in rule.body
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue