我正在使用 mixfix运算符编写函数式编程语言的解释器,就像Agda一样。
if_then_else_ : Bool -> a -> a -> a
if True then x else _ = x
if False then _ else x = x
_/\_ : Bool -> Bool -> Bool
True /\ True = True
_ /\ _ = False
这意味着我必须运行一个解析器(我使用Alex / Happy)来获取AST,并使用此特定部分(小于实际Expr
):
data Expr
= Id String
| Apply [Expr]
| Forall Type Expr
data Type = TypeBind String Expr
使用此Expr
,我必须运行第二个解析器(我打算使用Parsec)来执行以下类型的处理:
λ let example = Apply [Id "if", Id "a", Id "/\\", Id "b", Id "then", Id "c", Id "else", Id "d"]
λ parseMixfix example
Right (Apply [Id "if_then_else_",Apply [Id "_/\\_",Id "a",Id "b"],Id "c",Id "d"])
我从收到Stream
[Expr]
的Parser开始,但这只接受Apply
中的列表,并且不会深入树,只需在顶层解析。
所以我考虑选择使用[Expr]
作为Stream
而不是Expr
来使用Stream
,而不必使用data Tok a = This a | Over (Tok a) deriving (Show)
instance (Monad m) => Stream Expr m (Tok Expr) where
uncons ex = check ex
where
check :: Monad m => Expr -> m (Maybe (Tok Expr, Expr))
check ex = case ex of
Id s -> return $ Just (This (Id s), Apply [])
Apply (x:xs) -> do
mst <- check x
return $ fmap (\(a, b) -> (Over a, b)) mst
实例;这就是我所在的地方:
data Tok
使用Forall
作为Zipper面包屑的种类(或者至少我是这样看的),表明它来自树的深度。
我知道这不是正确的代码,但是请大家知道。我想知道我是否走在正确的轨道上,或者是否有更好的解决方案来解决这个问题。我在这里也错过了Id | Apply
案例;那是因为我以前只使用frontend/config/main.php:
树进行测试。