packages feed

gll 0.4.0.2 → 0.4.0.3

raw patch · 5 files changed

+148/−44 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- GLL.Combinators.Interface: assoc :: AltExpr t a -> AltExpr t a
- GLL.Combinators.Interface: lassoc :: AltExpr t a -> AltExpr t a
- GLL.Combinators.Interface: rassoc :: AltExpr t a -> AltExpr t a
+ GLL.Combinators.Interface: FloatLit :: (Maybe Double) -> Token
+ GLL.Combinators.Interface: chooses_prec :: (Show t, Ord t, IsAltExpr alt) => String -> [alt t a] -> SymbExpr t a
+ GLL.Combinators.Interface: float_lit :: SubsumesToken t => SymbExpr t Double
+ GLL.Combinators.Interface: longest_match :: (Show t, Ord t, IsAltExpr alt) => alt t a -> AltExpr t a
+ GLL.Combinators.Interface: optionalWithDef :: (Show t, Ord t, IsSymbExpr s) => s t a -> a -> SymbExpr t a
+ GLL.Combinators.Interface: preferably :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t (Maybe a)
+ GLL.Combinators.Interface: reluctantly :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t (Maybe a)
+ GLL.Combinators.Interface: shortest_match :: (Show t, Ord t, IsAltExpr alt) => alt t a -> AltExpr t a
+ GLL.Combinators.Lexer: baseToDec :: Int -> String -> Int
+ GLL.Combinators.Lexer: manyOf :: Eq t => [t] -> RE t [t]
+ GLL.Combinators.Lexer: oneOf :: Eq t => [t] -> RE t t
+ GLL.Combinators.Lexer: someOf :: Eq t => [t] -> RE t [t]
+ GLL.Types.Grammar: FloatLit :: (Maybe Double) -> Token
- GLL.Combinators.Interface: (<::=) :: (HasAlts b, Show t, Ord t) => String -> b t a -> SymbExpr t a
+ GLL.Combinators.Interface: (<::=) :: (HasAlts b, Ord t, Show t) => String -> b t a -> SymbExpr t a
- GLL.Combinators.Interface: (<:=) :: (HasAlts b, Show t, Ord t) => String -> b t a -> SymbExpr t a
+ GLL.Combinators.Interface: (<:=) :: (HasAlts b, Ord t, Show t) => String -> b t a -> SymbExpr t a
- GLL.Combinators.Interface: chooses :: (Show t, Ord t) => String -> [AltExpr t a] -> SymbExpr t a
+ GLL.Combinators.Interface: chooses :: (Show t, Ord t, IsAltExpr alt) => String -> [alt t a] -> SymbExpr t a
- GLL.Combinators.Interface: manySepBy2 :: (IsSymbExpr s2, IsSymbExpr s, IsAltExpr s2, Show t, Ord t) => s t a -> s2 t b -> BNF t [a]
+ GLL.Combinators.Interface: manySepBy2 :: (IsAltExpr s2, IsSymbExpr s, IsSymbExpr s2, Ord t, Show t) => s t a -> s2 t b -> BNF t [a]
- GLL.Combinators.Interface: multipleSepBy2 :: (IsSymbExpr s2, IsSymbExpr s, IsAltExpr s2, Show t, Ord t) => s t a -> s2 t b -> BNF t [a]
+ GLL.Combinators.Interface: multipleSepBy2 :: (IsAltExpr s2, IsSymbExpr s, IsSymbExpr s2, Ord t, Show t) => s t a -> s2 t b -> BNF t [a]
- GLL.Combinators.Interface: someSepBy2 :: (IsSymbExpr s2, IsSymbExpr s, IsAltExpr s2, Show t, Ord t) => s t a -> s2 t b -> BNF t [a]
+ GLL.Combinators.Interface: someSepBy2 :: (IsAltExpr s2, IsSymbExpr s, IsSymbExpr s2, Ord t, Show t) => s t a -> s2 t b -> BNF t [a]
- GLL.Types.Derivations: showD :: (Show a1, Show a) => Map a [a1] -> String
+ GLL.Types.Derivations: showD :: (Show a, Show a1) => Map a1 [a] -> String
- GLL.Types.Derivations: showG :: (Show a1, Show a) => Map a [a1] -> String
+ GLL.Types.Derivations: showG :: (Show a, Show a1) => Map a1 [a] -> String

Files

changelog.txt view
@@ -24,3 +24,14 @@   + generalised `within`   + different whitespace and comment handling in predefined lexer   + predefined lexer handles (nested) comment-blocks++0.4.0.2 -> 0.4.0.3+  M added hex, octal and binary representation to integer literals+  + added float literals+  + exporting `preferably` and `reluctantly`+  M renamed `rassoc` to shortest_match+  M renamed `lassoc` to longest_match+  - removed `assoc`+  + version of `chooses` that is left-biased (w.r.t. alternatives)+  + generalised arguments of longest_match and shortest_match to IsAltExpr +  + exporting `optionalWithDef`
gll.cabal view
@@ -3,7 +3,7 @@  -- The name of the package. name:                gll-version:             0.4.0.2+version:             0.4.0.3 synopsis:            GLL parser with simple combinator interface  license:             BSD3 license-file:        LICENSE
src/GLL/Combinators/Interface.hs view
@@ -182,7 +182,7 @@     -- * Elementary parsers     term_parser, satisfy,     -- ** Elementary parsers using the 'Token' datatype -    keychar, keyword, int_lit, bool_lit, char_lit, string_lit, alt_id_lit, id_lit, token,+    keychar, keyword, int_lit, float_lit, bool_lit, char_lit, string_lit, alt_id_lit, id_lit, token,     -- ** Elementary character-level parsers     char,      -- * Elementary combinators@@ -193,7 +193,7 @@     -- *** Semantic actions     (<$$>),     -- *** Nonterminal introduction-    (<:=>),(<::=>),chooses,+    (<:=>),(<::=>),chooses,chooses_prec,     -- * Types     -- ** Grammar (combinator expression) types     BNF, SymbExpr, AltExpr, AltExprs,@@ -223,11 +223,12 @@     -- *** Ignoring semantic results     (<$$), (**>), (<**),     -- *** EBNF patterns-    optional, multiple, multiple1, multipleSepBy, multipleSepBy1,+    optional, preferably, reluctantly, optionalWithDef,+    multiple, multiple1, multipleSepBy, multipleSepBy1,       multipleSepBy2, within, parens, braces, brackets, angles,      -- *** Disambiguation               (<:=), (<::=),(<<<**>), (<**>>>), (<<**>), (<<<**), (**>>>), (<**>>),-            rassoc, lassoc, assoc,+            longest_match,shortest_match,             many, many1, some, some1,              manySepBy, manySepBy1, manySepBy2,                someSepBy, someSepBy1,someSepBy2,@@ -348,10 +349,15 @@ (<::=>) :: (Show t, Ord t, HasAlts b) => String -> b t a -> SymbExpr t a  x <::=> altPs = mkNtRule True False x altPs --- | Variant of <::=> that can be supplied with a list of alternates-chooses :: (Show t, Ord t) => String -> [AltExpr t a] -> SymbExpr t a-chooses p alts = (<::=>) p (OO alts)+-- | Variant of '<::=>' that can be supplied with a list of alternates+chooses :: (Show t, Ord t, IsAltExpr alt) => String -> [alt t a] -> SymbExpr t a+chooses p alts = (<::=>) p (OO (map toAlt alts)) +-- | Variant of '<::=' that can be supplied with a list of alternates+chooses_prec :: (Show t, Ord t, IsAltExpr alt) => String -> [alt t a] -> SymbExpr t a+chooses_prec p alts = (<::=) p (OO (map toAlt alts))++ infixl 4 <$$> -- | -- Form an 'AltExpr' by mapping some semantic action overy the result@@ -390,22 +396,17 @@              in OO (l : r)  -- |--- Apply this combinator to an alternative to indicate that the alternative--- is for a left-associative operator. Used for top-down disambiguation.-lassoc :: AltExpr t a -> AltExpr t a-lassoc (AltExpr (v1,v2,v3)) = AltExpr (v1,v2,\opts -> v3 (maximumPivot opts))---- |--- Apply this combinator to an alternative to indicate that the alternative--- is for a right-associative operator. Used for top-down disambiguation.-rassoc :: AltExpr t a -> AltExpr t a-rassoc (AltExpr (v1,v2,v3)) = AltExpr (v1,v2,\opts -> v3 (minimumPivot opts))+-- Apply this combinator to an alternative to turn all underlying occurrences+-- of '<**>' (or variants) apply 'longest match'.+longest_match :: (Show t, Ord t, IsAltExpr alt) => alt t a -> AltExpr t a+longest_match isalt = AltExpr (v1,v2,\opts -> v3 (maximumPivot opts))+  where AltExpr (v1,v2,v3) = toAlt isalt  --- |--- Apply this combinator to an alternative to indicate that the alternative--- is for an associative operator. Used for top-down disambiguation.-assoc :: AltExpr t a -> AltExpr t a-assoc = lassoc+-- Apply this combinator to an alternative to turn all underlying occurrences+-- of '<**>' (or variants) apply 'shortest match'.+shortest_match :: (Show t, Ord t, IsAltExpr alt) => alt t a -> AltExpr t a+shortest_match isalt = AltExpr (v1,v2,\opts -> v3 (minimumPivot opts))+  where AltExpr (v1,v2,v3) = toAlt isalt   -- | Create a symbol-parse for a terminal given: --@@ -458,6 +459,13 @@  where  unwrap (Just (IntLit (Just i)))  = i         unwrap _ = error "int_lit: downcast, or token without lexeme" +-- | Parse a single floating point literal, using a 'SubsumesToken' type.+-- Returns the lexeme interpreted as a 'Double'.+float_lit :: SubsumesToken t => SymbExpr t Double+float_lit  = term_parser (upcast (FloatLit Nothing)) (unwrap . downcast)+ where  unwrap (Just (FloatLit (Just i)))  = i+        unwrap _ = error "float_lit: downcast, or token without lexeme"+ -- | Parse a single Boolean, using a 'SubsumesToken' type. -- Returns the lexeme interpreter as a Boolean. bool_lit :: SubsumesToken t => SymbExpr t Bool@@ -687,11 +695,31 @@ manySepBy2 p s = mkRule $    (:) <$$> p <** s <**> manySepBy1 p s --- | Make a piece of BNF optional, but proceed if unsuccessful --- (yielding 'Nothing' as a result in that case).+-- | Derive either from the given symbol or the empty string. optional :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t (Maybe a)-optional p = let fresh = mkNt p "?"-                in fresh <::=> Just <$$> p <||> satisfy Nothing +optional p = fresh +  <:=>  Just <$$> p +  <||>  satisfy Nothing +  where fresh = mkNt p "?"++-- | Version of 'optional' that prefers to derive from the given symbol+-- affects only nullable nonterminal symbols+preferably :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t (Maybe a)+preferably p = fresh +  <:=   Just <$$> p +  <||>  satisfy Nothing +  where fresh = mkNt p "?"++-- | Version of 'optional' that prefers to derive the empty string from +-- the given symbol, effects only nullable nonterminal symbols+reluctantly :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t (Maybe a)+reluctantly p = fresh +  <:=   satisfy Nothing  +  <||>  Just <$$> p+  where fresh = mkNt p "?"++optionalWithDef :: (Show t, Ord t, IsSymbExpr s) => s t a -> a -> SymbExpr t a +optionalWithDef p def = mkNt p "?" <:=> id <$$> p <||> satisfy def  -- | Place a piece of BNF /within/ two other BNF fragments, ignoring their semantics. within :: IsSymbExpr s => BNF Token a -> s Token b -> BNF Token c -> BNF Token b
src/GLL/Combinators/Lexer.hs view
@@ -1,12 +1,14 @@  module GLL.Combinators.Lexer (     default_lexer, lexer, LexerSettings(..), emptyLanguage,+    oneOf, manyOf, someOf, baseToDec,     ) where  import GLL.Types.Grammar (Token(..), SubsumesToken(..)) import Data.List (isPrefixOf) import Data.Char (isSpace, isDigit, isAlpha, isUpper, isLower) import Text.Regex.Applicative+import Text.Regex.Applicative.Common (signed)  -- | Settings for changing the behaviour of the builtin lexer 'lexer'. -- Lexers are built using "Text.Regex.Applicative".@@ -73,30 +75,89 @@ lTokens lexsets =         lCharacters     <|> lKeywords-    <|> charsToInt  <$> optional (sym '-') <*> some (psym isDigit)+    <|> upcast . IntLit . Just <$> lIntegers +    <|> upcast . FloatLit . Just <$> lFloats     <|> upcast . IDLit . Just <$> identifiers lexsets      <|> upcast . AltIDLit . Just <$> altIdentifiers lexsets     <|> upcast . CharLit . Just <$> lCharLit     <|> upcast . StringLit . Just <$> lStringLit     <|> lMore-    where   -            charsToInt Nothing n = upcast (IntLit (Just (read n)))-            charsToInt (Just _) n = upcast (IntLit (Just (-(read n))))+  where     lMore = foldr ((<|>) . uncurry lToken) empty (tokens lexsets)              lChar c = upcast (Char c) <$ sym c-            lCharacters = foldr ((<|>) . lChar) empty (keychars lexsets) +            lCharacters = foldr ((<|>) . lChar) empty (keychars lexsets)              lKeyword k  = upcast (Keyword k) <$ string k             lKeywords = foldr ((<|>) . lKeyword) empty (keywords lexsets) -            lMore = foldr ((<|>) . uncurry lToken) empty (tokens lexsets)-            lToken t re = upcast . Token t . Just <$> re+lToken t re = upcast . Token t . Just <$> re -            lStringLit = toString <$ sym '\"' <*> many strChar <* sym '\"'-             where strChar =  sym '\\' *> sym '\"'-                              <|> psym ((/=) '\"')-                   toString inner = read ("\"" ++ inner ++ "\"")+lStringLit = toString <$ sym '\"' <*> many strChar <* sym '\"'+ where strChar =  sym '\\' *> sym '\"'+                  <|> psym ((/=) '\"')+       toString inner = read ("\"" ++ inner ++ "\"") -            lCharLit = id <$ sym '\'' <*> charChar <* sym '\''-              where charChar = sym '\\' *> sym '\''-                                <|> psym ((/=) '\'')+lCharLit = id <$ sym '\'' <*> charChar <* sym '\''+  where charChar = sym '\\' *> sym '\''+                    <|> psym ((/=) '\'')++lFloats :: RE Char Double+lFloats = signed ( read <$> (+        mkDP <$> decimal <*> sym '.' <*> decimal <*> optional exponent +    <|> mkEP <$> decimal <*> exponent+  ))+  where mkDP pre _ post mexp = pre ++ "." ++ post ++ maybe "" id mexp+        mkEP pre exp = pre ++ exp++        exponent = mk <$> (sym 'e' <|> sym 'E') +                      <*> optional (sym '+' <|> sym '-')+                      <*> decimal+         where mk pre sign dec = pre : maybe "" (:[]) sign ++ dec++lIntegers :: RE Char Int+lIntegers = signed (+      (read <$> decimal)+  <|> (baseToDec 16 <$ hexPrefix <*> someOf (['0'..'9']++['A'..'F']++['a'..'f']))+  <|> (baseToDec 8  <$ octPrefix <*> someOf ['0'..'7'])+  <|> (baseToDec 2  <$ binPrefix <*> someOf ['0','1'])+  )+  where hexPrefix = string "0x" <|> string "0X"+        octPrefix = string "0o" <|> string "0O"+        binPrefix = string "0b" <|> string "0B" +    +decimal :: RE Char String+decimal = someOf ['0'..'9'] + +-- | Convert numerical representation in a given base +--  (max base = 16, written as string)+--  into decimal representation (returned as Int)+baseToDec :: Int -> String -> Int+baseToDec base = baseToDec' 0 base . map toInt+  where baseToDec' acc base [] = acc+        baseToDec' acc base (d:ds) = baseToDec' (acc * base + d) base ds+        toInt c | c == 'A' || c == 'a' = 10+                | c == 'B' || c == 'b' = 11+                | c == 'C' || c == 'c' = 12+                | c == 'D' || c == 'd' = 13+                | c == 'E' || c == 'e' = 14+                | c == 'F' || c == 'f' = 15+                | otherwise = read [c]+ +oneOf :: Eq t => [t] -> RE t t       +oneOf ts = psym (\t -> t `elem` ts)++manyOf :: Eq t => [t] -> RE t [t]+manyOf ts = many (oneOf ts) ++someOf :: Eq t => [t] -> RE t [t]+someOf ts = some (oneOf ts) ++{-++manyOf :: Eq t => [t] -> RE t [t]+manyOf ts = empty <|> someOf ts++someOf :: Eq t => [t] -> RE t [t]+someOf ts = (:) <$> oneOf ts <*> manyOf ts++-}
src/GLL/Types/Grammar.hs view
@@ -52,6 +52,7 @@            | EOS            | Epsilon            | IntLit     (Maybe Int)+           | FloatLit   (Maybe Double)            | BoolLit    (Maybe Bool)            | StringLit  (Maybe String)            | CharLit    (Maybe Char)@@ -93,23 +94,25 @@  instance SubsumesToken Token where     upcast = id-    downcast = Just . id+    downcast = Just  deriving instance Ord Token deriving instance Eq Token  instance Show Token where-    show (Char c)             = "char('" ++ [c] ++ "')"+    show (Char c)             = "keychar('" ++ [c] ++ "')"     show (Keyword s)          = "keyword(\"" ++ s ++ "\")"     show (EOS)                = "<end-of-string>"     show (Epsilon)            = "<epsilon>"     show (IntLit (Just i))    = "int(" ++  show i ++ ")"     show (IntLit _)           = "<int>"+    show (FloatLit (Just i))  = "float(" ++  show i ++ ")"+    show (FloatLit _)         = "<float>"     show (BoolLit (Just b))   = "bool(" ++  show b ++ ")"     show (BoolLit _)          = "<bool>"     show (StringLit (Just s)) = "string(\"" ++ s ++ "\")"     show (StringLit _)        = "<string>"-    show (CharLit (Just c))   = "char-literal('" ++ [c] ++ "')"+    show (CharLit (Just c))   = "char('" ++ [c] ++ "')"     show (CharLit Nothing)    = "<char>"     show (AltIDLit (Just id)) = "altid(\"" ++ id ++ "\")"     show (AltIDLit Nothing)   = "<altid>"@@ -132,6 +135,7 @@     StringLit _ `matches` StringLit _  = True     CharLit _   `matches` CharLit _    = True     IntLit _    `matches` IntLit _     = True+    FloatLit _  `matches` FloatLit _   = True     BoolLit _   `matches` BoolLit _    = True     AltIDLit _  `matches` AltIDLit _   = True     IDLit _     `matches` IDLit _      = True