agtest/agmain.py

76 lines
2.1 KiB
Python
Raw Normal View History

2021-06-09 00:56:30 +00:00
import textwrap
import os
2021-06-09 07:44:52 +00:00
import importlib
2021-06-09 00:56:30 +00:00
from lark import Lark
from agast import *
2021-06-13 23:28:28 +00:00
from aggen import *
2021-06-09 05:10:45 +00:00
p = Lark(open("grammar.lark").read(), start="program", parser="lalr")
2021-06-09 00:56:30 +00:00
if __name__ == "__main__":
2021-09-30 21:37:43 +00:00
with open("test/arith.ag") as f:
2021-06-14 20:52:53 +00:00
data = f.read()
cst = p.parse(data)
trans = Parser()
ast = trans.transform(cst)
res = gen(ast)
2021-09-30 22:39:08 +00:00
print("Grammar:")
print(res.parser_data)
2021-06-14 20:52:53 +00:00
if not os.path.exists("gen"):
os.makedirs("gen")
with open("gen/arith.py", "w") as f:
2021-09-30 20:59:03 +00:00
fmt_str = textwrap.dedent(
"""
2021-09-30 22:39:08 +00:00
# This document is generated by agtest.
2021-09-30 21:07:36 +00:00
2021-06-14 20:52:53 +00:00
__all__ = ["parse"]
from typing import Generic, TypeVar, Optional, Callable, Dict, Any
from lark import Lark, Transformer
T = TypeVar('T')
builtins: Dict[str, Any] = {{
"parseInt": lambda s: int(s)
}}
2021-09-30 22:39:08 +00:00
2021-06-14 20:52:53 +00:00
class Thunk(Generic[T]):
''' A thunk represents a value that may be computed lazily. '''
value: Optional[T]
def __init__(self, func: Callable[[], T]):
self.func = func
self.value = None
def get(self) -> T:
if self.value is None:
self.value = self.func()
return self.value
2021-09-30 22:39:08 +00:00
parser = Lark('''
{pd}
''', parser='lalr', start={starts}, debug=True)
2021-06-14 20:52:53 +00:00
{ex}
2021-09-30 22:39:08 +00:00
class Trans(Transformer[None]): {transdef}
2021-09-30 20:32:32 +00:00
def parse(input: str, start: Optional[str] = None) -> Any:
2021-09-30 21:07:36 +00:00
tree = parser.parse(input, start)
trans = Trans()
res = trans.transform(tree)
return res
2021-09-30 20:59:03 +00:00
"""
)
f.write(
2021-09-30 21:07:36 +00:00
fmt_str.format(
pd=res.parser_data,
ex=res.extra,
starts=list(res.starts),
transdef=res.transdef,
)
2021-09-30 20:59:03 +00:00
)
2021-06-14 20:52:53 +00:00
mod = importlib.import_module("gen.arith")
2021-09-30 20:59:03 +00:00
print(mod.parse("1 + 2 * 3", start="expr")) # type: ignore