Chciałbym wdrożyć tę zasadę gramatyki używając Haskell za parsec Biblioteka:Haskell parsec: `many` syntezatora wewnątrz` optional` combinator
((a | b | c)* (a | b))?
co jest regułą, że parser przyjmuje opcjonalny (czyli potencjalnie pusty) strunowy. Jeśli łańcuch jest acccepts nie jest pusty, to może być spożywany przez przepuszczenie przez zero lub więcej wystąpień a
b
lub c
parserami, ale akceptowane ciąg przez zewnętrzną najbardziej ?
opcjonalnym parsera musi być spożywane zarówno przez parser a
lub b
, ale nie c
. Oto przykład:
module Main where
import Text.Parsec
import Text.Parsec.Text
a,b,c :: GenParser() Char
a = char 'a'
b = char 'b'
c = char 'c'
-- ((a | b | c)* (a | b))?
myParser = undefined
shouldParse1,shouldParse2,shouldParse3,
shouldParse4,shouldFail :: Either ParseError String
-- these should succeed
shouldParse1 = runParser myParser() "" "" -- because ? optional
shouldParse2 = runParser myParser() "" "b"
shouldParse3 = runParser myParser() "" "ccccccb"
shouldParse4 = runParser myParser() "" "aabccab"
-- this should fail because it ends with a 'c'
shouldFail = runParser myParser() "" "aabccac"
main = do
print shouldParse1
print shouldParse2
print shouldParse3
print shouldParse4
print shouldFail
Pierwsza próba może wyglądać następująco:
myParser = option "" $ do
str <- many (a <|> b <|> c)
ch <- a <|> b
return (str ++ [ch])
Ale many
tylko konsumuje wszystko 'A' 'b' i 'znaków C' w każdym przypadku testowego, pozostawiając a <|> b
żadnych postaci do konsumpcji.
Pytanie:
Korzystanie parsec kombinatorów, jaka jest prawidłowa realizacja ((a | b | c)* (a | b))?
zdefiniować myParser
?
Może parse (a | b | c) + i odrzucić go później, jeśli kończy się na c? –