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