module Pinchot.Examples.Postal where
import Pinchot
import Data.Monoid ((<>))
postal :: Pinchot Char (Rule Char)
postal = mdo
digit <- terminal "Digit" (include '0' '9') <?> "digit from 0 to 9"
digits <- list1 digit
letter <- terminal "Letter" (include 'a' 'z' <> include 'A' 'Z')
<?> "letter from A to Z"
north <- terminal "North" (solo 'N')
south <- terminal "South" (solo 'S')
east <- terminal "East" (solo 'E')
west <- terminal "West" (solo 'W')
direction <- union "Direction" [north, south, east, west]
street <- terminalSeq "Street" ['S', 't']
avenue <- terminalSeq "Avenue" ['A', 'v', 'e']
way <- terminalSeq "Way" ['W', 'a', 'y']
boulevard <- terminalSeq "Boulevard" ['B', 'l', 'v', 'd']
suffix <- union "Suffix" [street, avenue, way, boulevard]
space <- terminal "Space" (solo ' ')
comma <- terminal "Comma" (solo ',')
letters <- nonTerminal "Letters"
[ ("NoLetter", [])
, ("ConsLetter", [letter, letters])
]
word <- record "PostalWord" [letter, letters]
preSpacedWord <- record "PreSpacedWord" [space, word]
preSpacedWords <- list preSpacedWord
words <- record "Words" [word, preSpacedWords]
number <- wrap "Number" digits
streetName <- wrap "StreetName" words
city <- wrap "City" words
state <- wrap "State" word
zipCode <- wrap "ZipCode" digits
directionSpace <- record "DirectionSpace" [direction, space]
spaceSuffix <- record "SpaceSuffix" [space, suffix]
optDirection <- option directionSpace
optSuffix <- option spaceSuffix
address <- record "Address"
[ number, space, optDirection, streetName, optSuffix,
comma, space, city, comma, space, state, space, zipCode
]
return address