首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell中的记录解析

Haskell中的记录解析
EN

Stack Overflow用户
提问于 2018-09-04 15:58:12
回答 2查看 174关注 0票数 2

我正在使用兆秒构建一个解析器,我不知道哪种方法是解析像这样的结构的最佳方法

代码语言:javascript
复制
names a b c
surnames d e f g

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

代码语言:javascript
复制
names a b c

代码语言:javascript
复制
surnames d e f g

是有效的。

我可以像这样解析每一行

代码语言:javascript
复制
maybeNames <- optional $ do
    constant "names"
    many identifier

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

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

EN

回答 2

Stack Overflow用户

发布于 2018-09-04 16:15:35

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

代码语言:javascript
复制
program  ::= lines
lines    ::= line | line lines
line     ::= names | surnames
names    ::= NAMES ids
surnames ::= SURNAMES ids
ids      ::= id | id ids
id       ::= STRING

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

票数 0
EN

Stack Overflow用户

发布于 2018-09-04 18:36:35

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

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52161488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档