{ {-# OPTIONS -w #-} module HOpenPGP.Tools.Parser( parseExpr, readExpr ) where import Codec.Encryption.OpenPGP.Types import Data.Conduit.OpenPGP.Filter (Expr(..), UPredicate(..), UOp(..), OVar(..), OValue(..), SPVar(..), SPValue(..), PKPVar(..), PKPValue(..)) import HOpenPGP.Tools.Lexer } %name parse %tokentype { Token } %monad { Alex } %lexer { lexwrap } { TokenEOF } %error { happyError } %token and { TokenAnd } any { TokenAny } not { TokenNot } or { TokenOr } tag { TokenTag } int { TokenInt $$ } '=' { TokenEq } '<' { TokenLt } '>' { TokenGt } '(' { TokenLParen } ')' { TokenRParen } pkversion { TokenPKVersion } sigversion { TokenSigVersion } sigtype { TokenSigType } pkalgo { TokenPKAlgo } sigpkalgo { TokenSigPKAlgo } hashalgo { TokenHashAlgo } rsa { TokenRSA } dsa { TokenDSA } elgamal { TokenElgamal } ecdsa { TokenECDSA } ecdh { TokenECDH } dh { TokenDH } binary { TokenBinary } canonicaltext { TokenCanonicalText } standalone { TokenStandalone } genericcert { TokenGenericCert } personacert { TokenPersonaCert } casualcert { TokenCasualCert } positivecert { TokenPositiveCert } subkeybindingsig { TokenSubkeyBindingSig } primarykeybindingsig { TokenPrimaryKeyBindingSig } signaturedirectlyonakey { TokenSignatureDirectlyOnAKey } keyrevocationsig { TokenKeyRevocationSig } subkeyrevocationsig { TokenSubkeyRevocationSig } certrevocationsig { TokenCertRevocationSig } timestampsig { TokenTimestampSig } md5 { TokenMD5 } sha1 { TokenSHA1 } ripemd160 { TokenRIPEMD160 } sha256 { TokenSHA256 } sha384 { TokenSHA384 } sha512 { TokenSHA512 } sha224 { TokenSHA224 } keysize { TokenKeysize } timestamp { TokenTimestamp } fingerprint { TokenFingerprint } keyid { TokenKeyID } fpr { TokenFpr $$ } longid { TokenLongID $$ } length { TokenLength } %% Expr : any { EAny } | not Expr { ENot $2 } | OExpr { E $1 } | SPExpr { E $1 } | PKPExpr { E $1 } | Expr and Expr { EAnd $1 $3 } | Expr or Expr { EOr $1 $3 } OExpr : tag Op Val { UOP OVTag $2 $3 } | length Op Val { UOP OVLength $2 $3 } SPExpr : sigversion Op SPVal { USPP SPVVersion $2 $3 } | sigtype Op SPVsigtypes { USPP SPVSigType $2 $3 } | sigpkalgo Op SPVpkalgos { USPP SPVPKA $2 $3 } | hashalgo Op SPVhashalgos { USPP SPVHA $2 $3 } PKPExpr : pkversion Op PKPVal { UPKPP PKPVVersion $2 $3 } | pkalgo Op PKPVpkalgos { UPKPP PKPVPKA $2 $3 } | keysize Op PKPVal { UPKPP PKPVKeysize $2 $3 } | timestamp Op PKPVal { UPKPP PKPVTimestamp $2 $3 } | fingerprint Op PKPVfingerprint { UPKPP PKPVTOF $2 $3 } | keyid Op PKPVlongid { UPKPP PKPVEOKI $2 $3 } Op : '=' { UEquals } | '<' { ULessThan } | '>' { UGreaterThan } Val : int { OInt $1 } SPVal : int { SPInt $1 } SPVsigtypes : binary { SPSigType BinarySig } | canonicaltext { SPSigType CanonicalTextSig } | standalone { SPSigType StandaloneSig } | genericcert { SPSigType GenericCert } | personacert { SPSigType PersonaCert } | casualcert { SPSigType CasualCert } | positivecert { SPSigType PositiveCert } | subkeybindingsig { SPSigType SubkeyBindingSig } | primarykeybindingsig { SPSigType PrimaryKeyBindingSig } | signaturedirectlyonakey { SPSigType SignatureDirectlyOnAKey } | keyrevocationsig { SPSigType KeyRevocationSig } | subkeyrevocationsig { SPSigType SubkeyRevocationSig } | certrevocationsig { SPSigType CertRevocationSig } | timestampsig { SPSigType TimestampSig } | int { SPInt $1 } SPVpkalgos : rsa { SPPKA RSA } | dsa { SPPKA DSA } | elgamal { SPPKA ElgamalEncryptOnly } | ecdsa { SPPKA ECDSA } | ecdh { SPPKA ECDH } | dh { SPPKA DH } | int { SPInt $1 } SPVhashalgos : md5 { SPHA DeprecatedMD5 } | sha1 { SPHA SHA1 } | ripemd160 { SPHA RIPEMD160 } | sha256 { SPHA SHA256 } | sha384 { SPHA SHA384 } | sha512 { SPHA SHA512 } | sha224 { SPHA SHA224 } | int { SPInt $1 } PKPVal : int { PKPInt $1 } PKPVpkalgos : rsa { PKPPKA RSA } | dsa { PKPPKA DSA } | elgamal { PKPPKA ElgamalEncryptOnly } | ecdsa { PKPPKA ECDSA } | ecdh { PKPPKA ECDH } | dh { PKPPKA DH } | int { PKPInt $1 } PKPVfingerprint : fpr { PKPTOF $1 } PKPVlongid : longid { PKPEOKI $1 } { lexwrap :: (Token -> Alex a) -> Alex a lexwrap cont = do t <- alexMonadScan' cont t alexMonadScan' = do inp <- alexGetInput sc <- alexGetStartCode case alexScan inp sc of AlexEOF -> alexEOF AlexError (pos, _, _, _) -> alexError (show pos) AlexSkip inp' len -> do alexSetInput inp' alexMonadScan' AlexToken inp' len action -> do alexSetInput inp' action (ignorePendingBytes inp) len getPosn :: Alex (Int,Int) getPosn = do (AlexPn _ l c,_,_,_) <- alexGetInput return (l,c) happyError :: Token -> Alex a happyError t = do (l,c) <- getPosn fail (show l ++ ":" ++ show c ++ ": Parse error on Token: " ++ show t ++ "\n") parseExpr :: String -> Either String (Expr UPredicate) parseExpr s = runAlex s parse readExpr :: FilePath -> IO (Either String (Expr UPredicate)) readExpr fp = do cs <- readFile fp return (parseExpr cs) }