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

whereidentifier解析一个有效的非保留字符串。

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

4

2 回答 2

0

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

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)
于 2018-09-04T10:36:34.923 回答
0

从为您的格式编写上下文无关语法开始:

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

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

于 2018-09-04T08:15:34.690 回答