开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜