packages feed

hydra-0.5.0: src/main/haskell/Hydra/Dsl/Grammars.hs

-- | A DSL for building BNF grammars

module Hydra.Dsl.Grammars where

import qualified Hydra.Grammar as G

import Data.String(IsString(..))


instance IsString G.Pattern where fromString = symbol

infixr 0 >:
(>:) :: String -> G.Pattern -> G.Pattern
l >: p = G.PatternLabeled $ G.LabeledPattern (G.Label l) p

alts :: [G.Pattern] -> G.Pattern
alts = G.PatternAlternatives

define :: String -> [G.Pattern] -> G.Production
define s pats = G.Production (G.Symbol s) pat
  where
    pat = case pats of
      [p] -> p
      _ -> alts pats

ignored :: G.Pattern -> G.Pattern
ignored = G.PatternIgnored

list :: [G.Pattern] -> G.Pattern
list = G.PatternSequence

nil :: G.Pattern
nil = G.PatternNil

opt :: G.Pattern -> G.Pattern
opt = G.PatternOption

plus :: G.Pattern -> G.Pattern
plus = G.PatternPlus

regex :: String -> G.Pattern
regex = G.PatternRegex . G.Regex

-- | A helper which matches patterns like "foo.bar.quux" or "one; two; three; four"
sep :: G.Pattern -> G.Pattern -> G.Pattern
sep separator pat = list[pat, star(list[separator, pat])]

-- | A helper which matches patterns like "foo.bar.quux" or "foo.bar.quux." (i.e. trailing separators are allowed)
sepp :: G.Pattern -> G.Pattern -> G.Pattern
sepp separator pat = list[pat, star(list[separator, pat]), opt(separator)]

star :: G.Pattern -> G.Pattern
star = G.PatternStar

symbol :: String -> G.Pattern
symbol = G.PatternNonterminal . G.Symbol

terminal :: String -> G.Pattern
terminal = G.PatternConstant . G.Constant