How to write a concatenated backtracking parser in haskell

I am trying to get a parser created from concatenated parsers to return to the parse.

here is the code:

ab = (try $ char 'a') <|> (try $ char 'b')
cd = (try $ char 'b') <|> (try $ char 'c')
abcd = (try $ many1 ab) >> (try cd)

here when i run

parse abcd "parser"

with the input "aaaaaaaaaaaaac", it works, but these are errors on the "aaaaaaaaaaaaaab", which should be acceptable.

Any ideas on what I can do to make this work

Thanks in advance

+4
source share
1 answer

So, are you trying to write a regex (a|b)+(b|c)in Haskell? Here's how you do it:

import Text.Parsec.String
import Text.Parsec

ab :: Parser Char
ab = char 'a' <|> char 'b'

bc :: Parser Char
bc = char 'b' <|> char 'c'

abc :: Parser String
abc = do
    a <- ab
    b <- bc
    return [a,b]

abbc :: Parser String
abbc = try abc <|> do
    c <- ab
    s <- abbc
    return (c:s)

parser :: String -> Either ParseError String
parser = parse abbc "(a|b)+(b|c)"

Now download ghciand run the code as follows:

aaditmshah@home:~$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :load Test.hs
[1 of 1] Compiling Main             ( Test.hs, interpreted )
Ok, modules loaded: Main.
*Main> parser "aaaaaaaaaaaaaac"
Loading package array-0.4.0.1 ... linking ... done.
Loading package deepseq-1.3.0.1 ... linking ... done.
Loading package bytestring-0.10.0.2 ... linking ... done.
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package mtl-2.1.2 ... linking ... done.
Loading package text-0.11.3.1 ... linking ... done.
Loading package parsec-3.1.5 ... linking ... done.
Right "aaaaaaaaaaaaaac"
*Main> parser "aaaaaaaaaaaaaab"
Right "aaaaaaaaaaaaaab"
*Main> 
Leaving GHCi.

How it works? Let the parser understand the parser:

ab :: Parser Char
ab = char 'a' <|> char 'b'

bc :: Parser Char
bc = char 'b' <|> char 'c'

. (a|b) (b|c) .

abc :: Parser String
abc = do
    a <- ab
    b <- bc
    return [a,b]

. (a|b)(b|c).

abbc :: Parser String
abbc = try abc <|> do
    c <- ab
    s <- abbc
    return (c:s)

. :

  • (a|b)(b|c).
  • , . (a|b), 1, .

, (a|b)*(a|b)(b|c), (a|b)+(b|c).

try . (a|b)(b|c). , .

+6

Source: https://habr.com/ru/post/1536041/


All Articles