This commit is contained in:
Michael Zhang 2021-09-30 21:58:18 -05:00
parent 8f51231f5b
commit 30644c5db7
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
2 changed files with 27 additions and 11 deletions

View file

@ -47,13 +47,15 @@ class GenResult:
for name, rules in self.parse_rules.items(): for name, rules in self.parse_rules.items():
n = name.lstrip("?") n = name.lstrip("?")
for equation in rules: for equation in rules:
code = textwrap.dedent(f""" code = textwrap.dedent(
f"""
def {equation.name}(self, items: Any) -> Thunk[{equation.ty}]: def {equation.name}(self, items: Any) -> Thunk[{equation.ty}]:
def inner() -> {equation.ty}: def inner() -> {equation.ty}:
res = {equation.ty}() res = {equation.ty}()
return res return res
return Thunk(inner) return Thunk(inner)
""") """
)
s.append(code) s.append(code)
if not s: if not s:
s = ["pass"] s = ["pass"]

View file

@ -6,33 +6,47 @@ import re
from typing import Generic, TypeVar, Optional, Callable, Dict, Any from typing import Generic, TypeVar, Optional, Callable, Dict, Any
from lark import Lark, Transformer from lark import Lark, Transformer
T = TypeVar('T') T = TypeVar("T")
builtins: Dict[str, Any] = {{ builtins: Dict[str, Any] = {{"parseInt": lambda s: int(s)}}
"parseInt": lambda s: int(s)
}}
class Thunk(Generic[T]): class Thunk(Generic[T]):
''' A thunk represents a value that may be computed lazily. ''' """A thunk represents a value that may be computed lazily."""
value: Optional[T] value: Optional[T]
def __init__(self, func: Callable[[], T]): def __init__(self, func: Callable[[], T]):
self.func = func self.func = func
self.value = None self.value = None
def get(self) -> T: def get(self) -> T:
if self.value is None: if self.value is None:
self.value = self.func() self.value = self.func()
return self.value return self.value
parser = Lark('''
parser = Lark(
"""
{pd} {pd}
''', parser='lalr', start={starts}, debug=True) """,
parser="lalr",
start={starts},
debug=True,
)
{ex} {ex}
class Trans(Transformer[None]): {transdef}
class Trans(Transformer[None]):
{transdef}
__agNonterminals = {ntmap} __agNonterminals = {ntmap}
def parse(input: str, start: Optional[str] = None) -> Any: def parse(input: str, start: Optional[str] = None) -> Any:
if start is not None: start = __agNonterminals[start] if start is not None:
start = __agNonterminals[start]
tree = parser.parse(input, start) tree = parser.parse(input, start)
trans = Trans() trans = Trans()
res = trans.transform(tree) res = trans.transform(tree)