+accessor :: ReadP Accessor
+accessor = do
+ x:xs <- reverse <$> sepBy1 property (char '.')
+ return $ foldl (flip Accessor) (AccessorTerm x) xs
+ where property = many (satisfy isAlphaNum)
+
+comparison :: ReadP Comparison
+comparison = do
+ space
+ operator <- string "==" <|> string "is in"
+ space
+ choice [eqString, eqNumber]
+ -- todo: contains string
+ where eqString = EqualsString <$> strLiteral
+ eqNumber = EqualsNumber . read <$> some (satisfy isNumber)
+
+action :: ReadP Action
+action = choice
+ [ openAction
+ , requestAction
+ , sendAction "reply" Reply
+ , sendAction "notify" Notify
+ ]
+ where
+ requestAction = do
+ skipSpaces
+ identifier <- manyTill (satisfy isAlphaNum) (skipSpaces >> char ':')
+ skipSpaces
+ sendAction "request" (Request identifier)
+
+openAction :: ReadP Action
+openAction = do
+ skipSpaces
+ string "open"
+ space
+ fp <- strLiteral
+ space
+ OpenDoc fp <$> strLiteral
+
+sendAction :: String -> (String -> MessageParam -> Action) -> ReadP Action
+sendAction keyword con = do
+ skipSpaces
+ string keyword
+ skipSpaces
+ method <- strLiteral
+ skipSpaces
+ con method <$> messageParam