Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
转换保尔森&x27;s解析器组合子到Haskell_Haskell_Sml_Ml - Fatal编程技术网

转换保尔森&x27;s解析器组合子到Haskell

转换保尔森&x27;s解析器组合子到Haskell,haskell,sml,ml,Haskell,Sml,Ml,我试图将Paulson的ML中的代码转换为程序员工作手册第9章,为λ-演算编写解释器。 我想知道是否有人能帮我把这个翻译成Haskell。 我正在努力理解语法 fun list ph = ph -- repeat ("," $-- ph) >> (op::); fun pack ph = "(" $-- list ph --$")" >> #1 | empty; 在将这段代码移植到Haskell中时,我看到了两个挑战:一个是重写

我试图将Paulson的ML中的代码转换为程序员工作手册第9章,为λ-演算编写解释器。 我想知道是否有人能帮我把这个翻译成Haskell。 我正在努力理解语法

fun list ph = ph -- repeat ("," $-- ph) >> (op::);

fun pack ph = "(" $-- list ph --$")"       >> #1
              | empty;

在将这段代码移植到Haskell中时,我看到了两个挑战:一个是重写组合符,以便它们使用SyntaxError而不是exceptions类型进行流控制,另一个是保留ML的函子的模块性。也就是说,编写一个解析器组合器库,该库与它应该使用的关键字/符号/标记器有关,是模块化的

而ML代码有两个

函子词法(关键字:关键字):词法
函子解析(Lex:LEXICAL):解析
你可以先吃点东西

data关键字=关键字
{alphas::[字符串]
,符号::[字符串]
}
数据令牌
=键字符串
|Id字符串
推导(显示,等式)
lex::关键字->字符串->[令牌]
lex kw s=。。。
哪里
alphaTok::String->Token
alphaTok a | a`elem`alphas kw=键a
|否则=Id a
...
ML代码使用类型字符串和子字符串,而Haskell的字符串实际上是一个[Char]。lexer函数看起来会有些不同,因为ML的
String.getc
可能只是Haskell中的模式匹配
c:ss1
,等等

鲍尔森的解析器具有类型[Token]→ (τ,[Token]),但允许例外情况。Haskell解析器的类型可能为[Token]→ 任一合成错误(τ,[标记]):

newtype SyntaxError=SyntaxError字符串
衍生节目
newtype解析器a=解析器{runParser::[Token]->语法错误(a[Token])中的任意一个
错误::字符串->任一语法错误b
err msg=Left(语法错误消息)
操作符
id
$
|
--
>
需要新名称,因为它们与一组内置运算符和单行注释冲突。名字的概念可以是:
ident
kw
| |
++
>
。我会跳过实现
运算符

这两个组合器的实现略有不同

ident :: Parser String
ident = Parser f
  where
    f :: [Token] -> Either SyntaxError (String, [Token])
    f (Id x : toks) = Right (x, toks)
    f (Key x : _) = err $ "Identifier expected, got keyword '" ++ x ++ "'"
    f [] = err "Identifier expected, got EOF"

    (+++) :: Parser a -> Parser b -> Parser (a, b)
    (+++) pa pb = Parser $ \toks1 -> do (x, toks2) <- runP pa toks1
                                        (y, toks3) <- runP pb toks2
                                        return ((x, y), toks3)
    ...
ident::解析器字符串
ident=f
哪里
f::[Token]->任一语法错误(字符串,[Token])
f(Id x:toks)=右(x,toks)
f(键x:417;)=err$“需要标识符,获取关键字”“++x++”“”
f[]=err“需要标识符,获得EOF”
(+++)::解析器a->解析器b->解析器(a,b)

(++++)pa pb=Parser$\toks1->do(x,toks2)在将此代码移植到Haskell时,我看到了两个挑战:一个是重写组合符,以便它们使用SyntaxError而不是exceptions类型来进行流控制,另一个是保留ML函数的模块性。也就是说,编写一个解析器组合器库,该库与它应该使用的关键字/符号/标记器有关,是模块化的

而ML代码有两个

函子词法(关键字:关键字):词法
函子解析(Lex:LEXICAL):解析
你可以先吃点东西

data关键字=关键字
{alphas::[字符串]
,符号::[字符串]
}
数据令牌
=键字符串
|Id字符串
推导(显示,等式)
lex::关键字->字符串->[令牌]
lex kw s=。。。
哪里
alphaTok::String->Token
alphaTok a | a`elem`alphas kw=键a
|否则=Id a
...
ML代码使用类型字符串和子字符串,而Haskell的字符串实际上是一个[Char]。lexer函数看起来会有些不同,因为ML的
String.getc
可能只是Haskell中的模式匹配
c:ss1
,等等

鲍尔森的解析器具有类型[Token]→ (τ,[Token]),但允许例外情况。Haskell解析器的类型可能为[Token]→ 任一合成错误(τ,[标记]):

newtype SyntaxError=SyntaxError字符串
衍生节目
newtype解析器a=解析器{runParser::[Token]->语法错误(a[Token])中的任意一个
错误::字符串->任一语法错误b
err msg=Left(语法错误消息)
操作符
id
$
|
--
>
需要新名称,因为它们与一组内置运算符和单行注释冲突。名字的概念可以是:
ident
kw
| |
++
>
。我会跳过实现
运算符

这两个组合器的实现略有不同

ident :: Parser String
ident = Parser f
  where
    f :: [Token] -> Either SyntaxError (String, [Token])
    f (Id x : toks) = Right (x, toks)
    f (Key x : _) = err $ "Identifier expected, got keyword '" ++ x ++ "'"
    f [] = err "Identifier expected, got EOF"

    (+++) :: Parser a -> Parser b -> Parser (a, b)
    (+++) pa pb = Parser $ \toks1 -> do (x, toks2) <- runP pa toks1
                                        (y, toks3) <- runP pb toks2
                                        return ((x, y), toks3)
    ...
ident::解析器字符串
ident=f
哪里
f::[Token]->任一语法错误(字符串,[Token])
f(Id x:toks)=右(x,toks)
f(键x:417;)=err$“需要标识符,获取关键字”“++x++”“”
f[]=err“需要标识符,获得EOF”
(+++)::解析器a->解析器b->解析器(a,b)

(++++)pa pb=Parser$\toks1->do(x,toks2)以上涉及未定义的运算符,例如在SML中没有内置含义的
>
。如果您正在使用某个解析库,也许可以指定该库是什么。看起来它可能与Paulson的ML中为工作程序员编写的“lambda演算章节编写解释器”相同,但无法帮助编写haskell。是的,我正在尝试将Paulson的ML中的代码转换为工作程序员手册。我是一个新的编程人员,所以我不懂。你读过之前的362页了吗?如果不是,那将是一个很好的起点。您的第一步可能应该是理解运算符的含义,但是如果给定运算符的实现(SML实现在第365页),结果应该几乎相同。您“只”需要学习足够的SML(和Haskell)来实现操作符。上面涉及到未定义的操作符,例如在SML中没有内置含义的
>
。如果你用的是p