我在为一种语言编写 parsec 规则时遇到问题 我有下一种语言定义(有问题的部分)
COMMAND ::= ':' WS LITERAL WS {LITERAL WS}* ';'
LITERAL ::= "[CHAR]*" | [^"\ ][^\ ]*
其中 WS 代表空格,LITERAL 是除空格或可以包含空格的引号字符以外的任何字符,因此,我编写了下一个函数:
literal = quotedLiteral <|> many1 (noneOf " ")
command = do { char ':'
; separator
; name <- literal
; separator
; cmds <- endBy literal separator -- (1)
; char ';' -- (2)
; return (name, Command cmds)
}
问题是符号';' 是一个有效的文字,所以 (1) 函数解析它,因此存在解析错误,因为 (2) 找不到 ';' 特点。
有什么办法可以克服这个问题:要么让文字函数不接受';' 作为文字或以某种方式修复(2)?
在 sclv 发表评论后,我找到了解决方案:
literal :: Parser Literal
literal = -- as desired in sclv (changing parserZero to pzero
command :: Parser TCommand
command = do { char ':'
; separator
; name <- literal <?> "no name"
; separator
; cmds <- sepEndBy (do { try( literal) }) separator
; char ';'
; return (name, Command cmds)
}