packages feed

hopenpgp-tools-0.11: HOpenPGP/Tools/Parser.y

{
{-# 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)
}