Parsing 缩进分析器示例

Parsing 缩进分析器示例,parsing,haskell,yaml,Parsing,Haskell,Yaml,有人能举一个缩进解析器使用的小例子吗?我希望解析类似YAML的输入,如下所示: fruits: apples: yummy watermelons: not so yummy vegetables: carrots: are orange celery raw: good for the jaw 我知道有一个YAML包。我想学习IndentParser的用法。我在下面草拟了一个解析器,对于您的问题,您可能只需要块 从缩进语法分析器中选择语法分析器。注意,我没有

有人能举一个缩进解析器使用的小例子吗?我希望解析类似YAML的输入,如下所示:

fruits:
    apples: yummy
    watermelons: not so yummy

vegetables:
    carrots: are orange
    celery raw: good for the jaw

我知道有一个YAML包。我想学习IndentParser的用法。

我在下面草拟了一个解析器,对于您的问题,您可能只需要 从缩进语法分析器中选择语法分析器。注意,我没有尝试运行它,因此它可能有基本错误

解析器最大的问题不是真正的缩进,而是您只有字符串和冒号作为标记。您可能会发现下面的代码需要相当多的调试,因为它必须对不消耗太多输入非常敏感,尽管我已经尝试过小心左因子分解。因为您只有两个令牌,所以您无法从Parsec的令牌模块中获得多少好处

请注意,解析有一个奇怪的事实,即外观简单的格式通常不容易解析。为了学习,为简单表达式编写解析器将教会您更多的东西,而不是或多或少的任意文本格式(这可能只会让您感到沮丧)

data DefinitionTree=嵌套字符串[DefinitionTree]
|定义字符串
派生(显示)
--注意-这可能需要一些测试。
--
--这是一个棘手的问题,解析器必须解析尾部
--空格和制表符,但不是新行。
--
category::indentCharst字符串
类别=do

{a您对Parsec的了解程度如何?IndentParser看起来是Parsec中令牌模块的替代品,Hackage的登录页提供了一个简单的例子。但是,如果您根本不了解Parsec,那么从尝试使用Parsec+IndentParser编写缩进敏感解析器开始可能会令人沮丧。我已经完成了Parsec-chRWH中的apter。在2010年10月左右,除了.IndentParser之外,没有其他经验被Text.Parsec.Indent取代
data DefinitionTree = Nested String [DefinitionTree]
                    | Def String String
  deriving (Show)


-- Note - this might need some testing.
--
-- This is a tricky one, the parser has to parse trailing 
-- spaces and tabs but not a new line.
--
category :: IndentCharParser st String
category = do 
    { a <- body 
    ; rest 
    ; return a
    } 
  where
    body = manyTill1 (letter <|> space) (char ':') 
    rest = many (oneOf [' ', '\t'])

-- Because the DefinitionTree data type has two quite 
-- different constructors, both sharing the same prefix
-- 'category' this combinator is a bit more complicated
-- than usual, and has to use an Either type to descriminate
-- between the options. 
-- 
definition :: IndentCharParser st DefinitionTree
definition = do 
    { a <- category
    ; b <- (textL <|> definitionsR)
    ; case b of
        Left ss -> return (Def a ss)
        Right ds -> return (Nested a ds)
    }

-- Note this should parse a string *provided* it is on 
-- the same line as the category.
--
-- However you might find this assumption needs verifying...
--
textL :: IndentCharParser st (Either DefinitionTrees a)
textL = do 
    { ss <- manyTill1 anyChar "\n" 
    ; return (Left ss)
    }

-- Finally this one uses an indent parser.
--
definitionsR :: IndentCharParser st (Either a [DefinitionTree]) 
definitionsR = block body 
  where 
    body = do { a <- many1 definition; return (Right a) }