Search code examples
parsinghaskellcontext-free-grammar

haskell parsing contextfree-grammar to compare with a string


I'm trying to represent a context-free grammar which I would like to parse for comparing a String with the "A" of Prod "A" [NT "B", NT "C"], but I don't know how, could someone please help me?

data Symbol a b = T a | NT b 
deriving (Eq,Show)

data Produktion a b = Prod b [Symbol a b]
deriving (Eq,Show)

type Produktionen a b = [Produktion a b]   

liste11 = [Prod "A" [NT "B", NT "C"]
      ,Prod "B" [NT "D", NT "E"]
      ,Prod "D" [T "d"]
      ] --

Solution

  • There are easier ways but a primitive approach can be

    fromNT :: (Symbol a b) -> b
    fromNT (NT b) = b
    fromNT (T a) = undefined
    
    extractNT :: (Eq b) => b -> [Produktion a b] -> [[b]]   
    extractNT _ [] = [[]]
    extractNT b (p:ps)  | is p = (map fromNT (symbol p)) : extractNT b ps
                        | otherwise = []          
                        where is (Prod x xs) = x==b
                              symbol (Prod _ xs) = xs
    

    now you can write

    > extractNT "A" liste11                         
    [["B","C"]]
    

    UPDATE

    I don't think it will work for generic types but for String String

    value :: (Symbol String String) -> String
    value (T a) = a
    value (NT b) = b
    

    the other accessors can still be generic

    symbol :: (Produktion a b) -> [Symbol a b]
    symbol (Prod _ ss) = ss
    
    tag :: (Produktion a b) -> b
    tag (Prod b _) = b
    

    you can now say

    > map (map value) $ map symbol $ filter (\p -> tag p=="D") liste11
    [["d"]]
    
    > map (map value) $ map symbol $ filter (\p -> tag p=="A") liste11
    [["B","C"]]