próbuję napisać parser korzystając parsec że będzie analizować pliki posiadające wiedzę Haskell, takie jak:Parsek - błąd „syntezator«wiele»jest stosowany do parsera, który akceptuje pusty ciąg”
The classic 'Hello, world' program.
\begin{code}
main = putStrLn "Hello, world"
\end{code}
More text.
pisałem następujące, sort-of-inspirowany przykładów w RWH:
import Text.ParserCombinators.Parsec
main
= do contents <- readFile "hello.lhs"
let results = parseLiterate contents
print results
data Element
= Text String
| Haskell String
deriving (Show)
parseLiterate :: String -> Either ParseError [Element]
parseLiterate input
= parse literateFile "(unknown)" input
literateFile
= many codeOrProse
codeOrProse
= code <|> prose
code
= do eol
string "\\begin{code}"
eol
content <- many anyChar
eol
string "\\end{code}"
eol
return $ Haskell content
prose
= do content <- many anyChar
return $ Text content
eol
= try (string "\n\r")
<|> try (string "\r\n")
<|> string "\n"
<|> string "\r"
<?> "end of line"
Jakie mam nadzieję doprowadzić coś wzdłuż linii:
[Text "The classic 'Hello, world' program.", Haskell "main = putStrLn \"Hello, world\"", Text "More text."]
(z dopuszczeniem białych znaków itp.).
To kompiluje poprawnie, ale po uruchomieniu, pojawia się błąd:
*** Exception: Text.ParserCombinators.Parsec.Prim.many: combinator 'many' is applied to a parser that accepts an empty string
Czy ktoś może rzucić jakieś światło na to, a może pomóc roztworem proszę?
Problem polega na tym, że zarówno kod, jak i proza mogą zawierać odwrotne ukośniki (kod z powodu lambdas itp. Oraz proza, ponieważ może zawierać polecenia TeX). – stusmith
(Jedynym czynnikiem wyróżniającym jest to, że \ begin {code} i \ end {code} muszą znajdować się na newlines). – stusmith
Rozumiem - nie przemyślałem tego ... Myślę, że będziesz musiał jakoś zrestrukturyzować swoją gramatykę, aby sprawdzał po każdym nowym wierszu, czy następna część to \ begin {code} lub \ end {code} string . Niestety. Nie mam takiego doświadczenia z gramatykami. – bzn