würden diese Grammatikregel mit Haskells Parsec Bibliothek implementieren:Haskell Parsec: `many` combinator innerhalb einer` optional` combinator
((a | b | c)* (a | b))?
dem ein Parser-Regel ist, die eine optionale (dh potentiell leer akzeptiert) Zeichenfolge. Wenn die Zeichenfolge es acccepts nicht leer ist, dann kann es, indem sie durch null oder mehr Vorkommen der a
b
oder c
Parser verbraucht werden, aber die akzeptierte Zeichenfolge, die von den äußeren meist ?
optional Parser muss verbraucht wird entweder durch Parser a
oder b
, aber nicht c
. Hier ein Beispiel:
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
Ein erster Versuch könnte wie folgt aussehen:
myParser = option "" $ do
str <- many (a <|> b <|> c)
ch <- a <|> b
return (str ++ [ch])
Aber die many
verbraucht nur all 'a' 'b' und 'c' Zeichen in jedem Testfall, a <|> b
verlassen keine zu konsumierenden Zeichen
Die Frage:
Parsec combinators benutzen, was ist die korrekte Umsetzung der ((a | b | c)* (a | b))?
-myParser
zu definieren?
Vielleicht analysieren (a | b | c) + und lehne es später ab, wenn es mit c endet? –