1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
from . import html5
from .examples import examples
from lark import Lark
from lark.tree import Tree
class App(html5.Div):
def __init__(self):
super().__init__("""
<h1>
<img src="lark-logo.png"> IDE
</h1>
<main>
<menu>
<select [name]="examples">
<option disabled selected>Examples</option>
</select>
<select [name]="parser">
<option value="earley" selected>Earley (default)</option>
<option value="lalr">LALR</option>
<option value="cyk">CYK</option>
</select>
</menu>
<div id="inputs">
<div>
<div>Grammar:</div>
<textarea [name]="grammar" id="grammar" placeholder="Lark Grammar..."></textarea>
</div>
<div>
<div>Input:</div>
<textarea [name]="input" id="input" placeholder="Parser input..."></textarea>
</div>
</div>
<div id="result">
<ul [name]="ast" />
</div>
</main>
""")
self.sinkEvent("onKeyUp", "onChange")
self.parser = "earley"
# Pre-load examples
for name, (grammar, input) in examples.items():
option = html5.Option(name)
option.grammar = grammar
option.input = input
self.examples.appendChild(option)
def onChange(self, e):
if html5.utils.doesEventHitWidgetOrChildren(e, self.examples):
example = self.examples.children(self.examples["selectedIndex"])
self.grammar["value"] = example.grammar.strip()
self.input["value"] = example.input.strip()
self.onKeyUp()
elif html5.utils.doesEventHitWidgetOrChildren(e, self.parser):
self.parser = self.parser.children(self.parser["selectedIndex"])["value"]
self.onKeyUp()
def onKeyUp(self, e=None):
l = Lark(self.grammar["value"], parser=self.parser)
try:
ast = l.parse(self.input["value"])
except Exception as e:
self.ast.appendChild(
html5.Li(str(e)), replace=True
)
print(ast)
traverse = lambda node: html5.Li([node.data, html5.Ul([traverse(c) for c in node.children])] if isinstance(node, Tree) else node)
self.ast.appendChild(traverse(ast), replace=True)
def start():
html5.Body().appendChild(
App()
)
|