parsec can't define rule for endBy function
I have a problem for writing parsec rules for one language I have next language definition (problematic part)
COMMAND ::= ':' WS LITERAL WS {LITERAL WS}* ';'
LITERAL ::开发者_StackOverflow中文版= "[CHAR]*" | [^"\ ][^\ ]*
where WS stands for whitespace and LITERAL is any characters except whitespace or quoted charactes that can contains white spaces so, I've write next functions:
literal = quotedLiteral <|> many1 (noneOf " ")
command = do { char ':'
; separator
; name <- literal
; separator
; cmds <- endBy literal separator -- (1)
; char ';' -- (2)
; return (name, Command cmds)
}
Problem is that symbol ';' is a valid literal so (1) function parses it, therefore there is a parsing error, because (2) fails to find ';' character.
Is there any way to overcome this problem: Either make literal function do not accept ';' as literal or somehow fix (2)?
after sclv's comment I find a solution:
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)
}
one (untested) take on solution 1:
literal = quotedLiteral <|> someChars
where someChars = do
res <- many1 (noneOf " \n")
if (res == ';')
then parserZero
else return res
精彩评论