This repository has been archived on 2024-11-05. You can view files and clone it, but cannot push or open issues/pull-requests.
lamb/parser.py

80 lines
1.5 KiB
Python
Raw Normal View History

2022-10-20 11:02:49 -07:00
import pyparsing as pp
import tokens
2022-10-21 19:39:37 -07:00
import utils
2022-10-20 11:02:49 -07:00
class Parser:
lp = pp.Suppress("(")
rp = pp.Suppress(")")
# Simple tokens
pp_expr = pp.Forward()
2022-10-21 14:44:52 -07:00
pp_macro = pp.Word(pp.alphas + "_")
pp_macro.set_parse_action(tokens.macro.from_parse)
2022-10-20 11:02:49 -07:00
2022-10-21 19:39:37 -07:00
pp_church = pp.Word(pp.nums)
pp_church.set_parse_action(utils.autochurch)
2022-10-21 19:55:15 -07:00
# Function calls.
# `tokens.lambda_apply.from_parse` handles chained calls.
#
# <exp> <exp>
# <exp> <exp> <exp>
pp_call = pp.Forward()
pp_call <<= pp_expr[2, ...]
pp_call.set_parse_action(tokens.lambda_apply.from_parse)
2022-10-20 11:02:49 -07:00
# Function definitions.
# Right associative.
#
# <var> => <exp>
2022-10-21 19:13:07 -07:00
pp_lambda_fun = (
(pp.Suppress("λ") | pp.Suppress("\\")) +
pp.Group(pp.Char(pp.alphas)[1, ...]) +
pp.Suppress(".") +
2022-10-21 19:55:15 -07:00
(pp_expr ^ pp_call)
2022-10-21 19:13:07 -07:00
)
2022-10-20 11:02:49 -07:00
pp_lambda_fun.set_parse_action(tokens.lambda_func.from_parse)
# Assignment.
# Can only be found at the start of a line.
#
2022-10-21 19:55:15 -07:00
# <name> = <exp>
pp_macro_def = (
pp.line_start() +
pp_macro +
pp.Suppress("=") +
(pp_expr ^ pp_call)
)
2022-10-20 11:02:49 -07:00
pp_macro_def.set_parse_action(tokens.macro_expression.from_parse)
2022-10-21 19:55:15 -07:00
pp_expr <<= (
pp_church ^
pp_lambda_fun ^
pp_macro ^
(lp + pp_expr + rp) ^
(lp + pp_call + rp)
)
2022-10-20 11:02:49 -07:00
2022-10-21 14:44:52 -07:00
pp_command = pp.Suppress(":") + pp.Word(pp.alphas + "_")
2022-10-21 14:41:24 -07:00
pp_command.set_parse_action(tokens.command.from_parse)
2022-10-20 11:02:49 -07:00
2022-10-21 19:55:15 -07:00
pp_all = (
pp_expr ^
pp_macro_def ^
pp_command ^
pp_call
)
2022-10-20 11:02:49 -07:00
@staticmethod
2022-10-21 14:41:24 -07:00
def parse_line(line):
2022-10-21 19:55:15 -07:00
k = Parser.pp_all.parse_string(
2022-10-21 14:41:24 -07:00
line,
parse_all = True
)[0]
print(k)
2022-10-21 14:44:52 -07:00
return k
2022-10-20 11:02:49 -07:00
@staticmethod
def run_tests(lines):
2022-10-21 19:55:15 -07:00
return Parser.pp_all.run_tests(lines)