packages feed

context-free-grammar-0.0.1: src/Data/Cfg/Bnf/Parser.y

{
-- | Parser for Bnf
module Data.Cfg.Bnf.Parser(parse) where

import qualified Data.Map as M
import Data.Cfg.Bnf.Scanner(scan)
import Data.Cfg.Bnf.Syntax
import Data.Cfg.Bnf.Token
import Data.Cfg.Cfg(Production, V(..), Vs)
}

%name parseTokens grammar

%error { parseError }

%tokentype { Token }

%token
    FULL_STOP           { Token FULL_STOP $$ }
    LOWER_IDENTIFIER    { Token LOWER_IDENTIFIER $$ }
    OR                  { Token OR $$ }
    UPPER_IDENTIFIER    { Token UPPER_IDENTIFIER $$ }
    YIELDS              { Token YIELDS $$ }

%%

grammar :: { Grammar String String  }
        : prods { Grammar $1 }

prods :: { [Production String String] }
      : prods prod { $1 ++ $2 }
      | prod { $1 }

prod :: { [Production String String] }
     : LOWER_IDENTIFIER YIELDS rhs FULL_STOP { [ ($1, alt) | alt <- $3 ] }

rhs :: { [Vs String String] }
    : alts { $1 }

alts :: { [Vs String String] }
     : alts OR alt { $1 ++ [ $3 ] }
     | alt { [ $1 ] }

alt :: { Vs String String }
    : terms { $1 }

terms :: { Vs String String }
      : terms term { $1 ++ [ $2 ] }
      | { [] }

term :: { V String String }
     : UPPER_IDENTIFIER { T $1 }
     | LOWER_IDENTIFIER { NT $1 }

{

parseError :: [Token] -> a
parseError ts = error $ "parseError at: " ++ show ts

-- | Parses Bnf source into a 'Grammar'.
parse :: String -> Grammar String String
parse = parseTokens . scan

-- | Parses a list of 'Token's into a 'Grammar'.
parseTokens :: [Token] -> Grammar String String
}