在Haskell中记录解析

问题描述 投票:1回答:2

我正在使用Megaparsec构建解析器,我不知道解析结构的最佳方法是哪种

names a b c
surnames d e f g

其中namessurnames是关键字后跟一个字符串列表,两行中的每一行都是可选的。这也意味着

names a b c

surnames d e f g

是有效的。

我可以用类似的东西解析每一行

maybeNames <- optional $ do
    constant "names"
    many identifier

其中identifier解析有效的非保留字符串。

现在,我不确定如何表达每一行是可选的,但如果它存在,仍然检索它的值

parsing haskell megaparsec
2个回答
0
投票

首先为您的格式编写上下文无关语法:

program  ::= lines
lines    ::= line | line lines
line     ::= names | surnames
names    ::= NAMES ids
surnames ::= SURNAMES ids
ids      ::= id | id ids
id       ::= STRING

大写名称用于终端,小写名称用于非终端。然后,您可以轻松使用Alex + Happy来解析文本文件。


0
投票

您可以执行与this guide中显示的操作类似的操作,并使用<|>选择可选参数。以下是事物的本质:

whileParser :: Parser Stmt
whileParser = between sc eof stmt

stmt :: Parser Stmt
stmt = f <$> sepBy1 stmt' semi
  where
    -- if there's only one stmt return it without using ‘Seq’
    f l = if length l == 1 then head l else Seq l

stmt' = ifStmt
  <|> whileStmt
  <|> skipStmt
  <|> assignStmt
  <|> parens stmt

ifStmt :: Parser Stmt
ifStmt = do
  rword "if"
  cond  <- bExpr
  rword "then"
  stmt1 <- stmt
  rword "else"
  stmt2 <- stmt
  return (If cond stmt1 stmt2)

whileStmt :: Parser Stmt
whileStmt = do
  rword "while"
  cond <- bExpr
  rword "do"
  stmt1 <- stmt
  return (While cond stmt1)
© www.soinside.com 2019 - 2024. All rights reserved.