我正在使用兆秒构建一个解析器,我不知道哪种方法是解析像这样的结构的最佳方法
names a b c
surnames d e f g其中names和surnames是后跟字符串列表的关键字,这两行中的每一行都是可选的。这也意味着
names a b c和
surnames d e f g是有效的。
我可以像这样解析每一行
maybeNames <- optional $ do
constant "names"
many identifier其中identifier解析有效的非保留字符串。
现在,我不确定如何表示每一行都是可选的,但如果它存在,仍然可以检索它的值
发布于 2018-09-04 16:15:35
首先为您的格式编写上下文无关文法:
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-04 18:36:35
您可以执行类似于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)https://stackoverflow.com/questions/52161488
复制相似问题