Parsing 哈斯克尔递归下降分析器
对于这种语法,我如何在不使用parsec或任何库的情况下创建一个递归的体面解析器? 如果字符串不属于此语法,则输出应为错误消息? 解析::字符串->AST Re->Sq | Sq+Re Sq->Ba | Ba Sq Ba->El | Ba* El->低位或数字|(Re)Parsing 哈斯克尔递归下降分析器,parsing,haskell,functional-programming,abstract-syntax-tree,Parsing,Haskell,Functional Programming,Abstract Syntax Tree,对于这种语法,我如何在不使用parsec或任何库的情况下创建一个递归的体面解析器? 如果字符串不属于此语法,则输出应为错误消息? 解析::字符串->AST Re->Sq | Sq+Re Sq->Ba | Ba Sq Ba->El | Ba* El->低位或数字|(Re) 小写或数字只是小写字母或数字首先,您需要定义抽象语法树,可能是一些声明的数据类型。然后,您需要定义基本的解析操作。比如说, type ParseResult = Either String AST type ParseState
小写或数字只是小写字母或数字首先,您需要定义抽象语法树,可能是一些声明的数据类型。然后,您需要定义基本的解析操作。比如说,
type ParseResult = Either String AST
type ParseState = (ParseResult, String)
您的解析操作非常简单:
re, sq, ba, el :: ParseState -> ParseState
其中,re
是顶级解析器操作
具体的解析步骤可能如下所示:
el (_, ('(':restOfInput)) = case re (Right restOfInput) of
err@(Left error, s) -> err
(result, ')':s) -> (El result, s)
(_, s) -> (Left "no closing parens", s)
el (_, input@(c:restOfInput)) = if lowerOrDigit c
then (El c, restOfInput)
else (Left "bad character", "")
解析库为您带来巨大动力的地方在于处理所有解析状态并将错误传播到调用堆栈 你可以使用
alex
和happy
:为什么你不想使用任何库?不使用parsec或任何库-不说为什么,这是一个荒谬的要求。使用库的好处是,通常你可以更多地关注什么而不是如何使用。词法分析器和语法分析器往往很难“连接自己”。因此,通常最好使用一种防止出错的工具。要编写递归下降解析器,首先需要以LL(1)形式重写语法。之后,您可以通过检查第一个字符/标记并选择正确的产品来编写自顶向下的解析器。库可以为您完成部分工作,但出于某种原因,您不想使用它们。