parsec не может определить правило для функции endBy - PullRequest
2 голосов
/ 08 июня 2011

У меня проблема с написанием правил 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)
            }

1 Ответ

1 голос
/ 08 июня 2011

один (непроверенный) вариант решения 1:

literal = quotedLiteral <|> someChars
   where someChars = do 
            res <- many1 (noneOf " \n")
            if (res == ';')
               then parserZero
               else return res
...