diff --git a/changelog.txt b/changelog.txt
new file mode 100644
--- /dev/null
+++ b/changelog.txt
@@ -0,0 +1,22 @@
+0.3.0.1 -> 0.3.0.2
+    + smart constructors for creating Grammars. To be used instead of constructors.
+0.3.0.2 -> 0.3.0.3
+    + SubsumesToken class for making Token a subtype of a custom Parseable type.
+        The terminal parsers id_lit, int_lit, etc. can be used directly.
+    + Additional constructor in 'Token' for alternative identifiers.
+    - Method 'matches' of class 'Parseable' no longer has a default definition
+        (default was (==)).
+0.3.0.3 -> 0.3.0.4
+    - Removed global disambiguation options (leftBiased, minimum/maximumPivot)
+    + introduced lassoc, rassoc and assoc for associativity based 
+        local disambiguation
+    + renamed some to many1 and let many and many1 implement shortest-match,
+        hence, if there is ambiguity the list with the maximum size is chosen.
+    + introduced some and some1 that are the same as many/many1 except
+        that they implement longest-match (resulting in minimum sized list)
+    + introduced multiple and multiple1 that are as above but implementing
+        no disambiguation (possibly useful for debuggin)
+    + introduced manySepBy(1), someSepBy(1) and multipleSepBy(1)
+0.3.0.4 -> 0.3.0.6
+    + added missing string literal token to predefined lexer
+    + added user-defined tokens to predefined lexer (given as a list)
diff --git a/gll.cabal b/gll.cabal
--- a/gll.cabal
+++ b/gll.cabal
@@ -3,7 +3,7 @@
 
 -- The name of the package.
 name:                gll
-version:             0.3.0.1
+version:             0.3.0.6
 synopsis:            GLL parser with simple combinator interface 
 license:             BSD3
 license-file:        LICENSE
@@ -36,6 +36,8 @@
         Please email any questions, comments and suggestions to the 
         maintainer.
 
+extra-source-files: changelog.txt
+
 library
     hs-source-dirs  :   src
     build-depends   :     base >=4.3.1.0 && <= 4.8.0.0
@@ -43,6 +45,8 @@
                         , array
                         , TypeCompose
                         , pretty
+                        , text
+                        , regex-applicative >= 0.3
     exposed-modules :     GLL.Combinators.Interface
                         , GLL.Combinators.Test.Interface
                         , GLL.Combinators
@@ -51,6 +55,7 @@
     other-modules   :   GLL.Types.Abstract
                         , GLL.Combinators.Memoisation
                         , GLL.Combinators.Options
+                        , GLL.Combinators.Lexer
                         , GLL.Types.Grammar
                         , GLL.Combinators.Visit.Grammar
                         , GLL.Combinators.Visit.Sem
diff --git a/src/GLL/Combinators/Interface.hs b/src/GLL/Combinators/Interface.hs
--- a/src/GLL/Combinators/Interface.hs
+++ b/src/GLL/Combinators/Interface.hs
@@ -182,7 +182,7 @@
     -- * Elementary parsers
     term_parser, satisfy,
     -- ** Elementary parsers using the 'Token' datatype 
-    keychar, keyword, int_lit, bool_lit, string_lit, id_lit, token,
+    keychar, keyword, int_lit, bool_lit, string_lit, alt_id_lit, id_lit, token,
     -- ** Elementary character-level parsers
     char, 
     -- * Elementary combinators
@@ -198,29 +198,35 @@
     -- ** Grammar (combinator expression) types
     BNF, SymbExpr, AltExpr, AltExprs,
     -- ** Parseable token types 
-    Token(..), Parseable(..), 
+    Token(..), Parseable(..), SubsumesToken(..), 
     -- * Running a parser 
-    parse,
+    parse, 
     -- **  Running a parser with options
     parseWithOptions,
     -- *** Possible options
-    CombinatorOptions, CombinatorOption, leftBiased, maximumPivot, maximumPivotAtNt,
+    CombinatorOptions, CombinatorOption, 
              GLL.Combinators.Options.maximumErrors, throwErrors,
     -- **** Parser options
     fullSPPF, allNodes, packedNodesOnly, strictBinarisation,
     -- *** Running a parser with options and explicit failure
     parseWithOptionsAndError,
     -- ** Runing a parser to obtain 'ParseResult'.
-    parseResult, parseResultWithOptions,ParseResult(..), 
+    parseResult, parseResultWithOptions,ParseResult(..),
+    -- ** Builtin lexers.
+    default_lexer, 
+    -- *** Lexer settings
+        lexer, LexerSettings(..), emptyLanguage,
     -- * Derived combinators
     mkNt, 
     -- *** Ignoring semantic results
     (<$$), (**>), (<**),
-    -- *** Post-parse disambiguation
-    (<::=),
     -- *** EBNF patterns
-    optional, many, some,
-     -- * Lifting
+    optional, multiple, multiple1, multipleSepBy, multipleSepBy1,
+     -- *** Disambiguation  
+            (<::=),
+            lassoc, rassoc, assoc,many, many1, some, some1, 
+            manySepBy, manySepBy1, someSepBy, someSepBy1, 
+    -- * Lifting
     HasAlts(..), IsSymbExpr(..), IsAltExpr(..),
      -- * Memoisation
     memo, newMemoTable, memClear, MemoTable, MemoRef, useMemoisation,
@@ -230,16 +236,18 @@
 import GLL.Combinators.Visit.Sem
 import GLL.Combinators.Visit.Grammar
 import GLL.Combinators.Memoisation
+import GLL.Combinators.Lexer
 import GLL.Types.Abstract
 import GLL.Parser hiding (parse, parseWithOptions, Options, Option, runOptions)
 import qualified GLL.Parser as GLL
 
 import Control.Arrow
 import Control.Compose (OO(..),unOO)
-import Data.List (intersperse)
+import Data.List (intercalate)
 import qualified Data.Array as A
 import qualified Data.IntMap as IM
 import qualified Data.Map as M
+import Data.Text (pack)
 import Data.IORef 
 import System.IO.Unsafe
 
@@ -274,8 +282,9 @@
         parse_res   = GLL.parseWithOptions (popts++[GLL.maximumErrors max_err]) grammar input
         sppf        = sppf_result parse_res
         arr         = A.array (0,m) (zip [0..] input)
-    in (grammar, parse_res, if res_success parse_res 
-                            then Right $ unsafePerformIO as
+        res_list    = unsafePerformIO as
+    in (grammar, parse_res, if res_success parse_res && not (null res_list)
+                            then Right $ res_list 
                             else Left (error_message parse_res) )
 
 -- | The grammar of a given parser.
@@ -323,7 +332,7 @@
 -- | 
 -- Form a rule by giving the name of the left-hand side of the new rule.
 -- Use this combinator on recursive non-terminals.
-(<:=>) :: (Show t, Ord t, HasAlts b) => Nt -> b t a -> SymbExpr t a 
+(<:=>) :: (Show t, Ord t, HasAlts b) => String -> b t a -> SymbExpr t a 
 x <:=> altPs = mkNtRule False False x altPs
 infixl 2 <::=>
 
@@ -335,16 +344,17 @@
 --  if and only if it is left-recursive and would be
 --  left-recursive if all the right-hand sides of the productions of the
 --  grammar are reversed.
-(<::=>) :: (Show t, Ord t, HasAlts b) => Nt -> b t a -> SymbExpr t a 
+(<::=>) :: (Show t, Ord t, HasAlts b) => String -> b t a -> SymbExpr t a 
 x <::=> altPs = mkNtRule True False x altPs
 
-mkNtRule :: (Show t, Ord t, HasAlts b) => Bool -> Bool -> Nt -> b t a -> SymbExpr t a
-mkNtRule use_ctx left_biased x altPs' =
+mkNtRule :: (Show t, Ord t, HasAlts b) => Bool -> Bool -> String -> b t a -> SymbExpr t a
+mkNtRule use_ctx left_biased x' altPs' =
     let vas1 = map (\(AltExpr (f,_,_)) -> f) altPs 
         vas2 = map (\(AltExpr (_,s,_)) -> s) altPs
         vas3 = map (\(AltExpr (_,_,t)) -> t) altPs
         alts  = map (Prod x) vas1    
         altPs = altsOf altPs'
+        x     = pack x'
     in SymbExpr (Nt x, grammar_nterm x alts vas2, sem_nterm use_ctx left_biased x alts vas3)
 
 infixl 4 <$$>
@@ -378,6 +388,24 @@
                  r = altsOf r'
              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 indicate that the alternative
+-- is for an associative operator. Used for top-down disambiguation.
+assoc :: AltExpr t a -> AltExpr t a
+assoc = lassoc
+
 -- | Create a symbol-parse for a terminal given:
 --
 --  * The 'Parseable' token represented by the terminal.
@@ -414,51 +442,59 @@
 parens p = within (char '(') p (char ')')
 -}
 
--- | Parse a single character, using the 'Token' datatype.
-keychar :: Char -> SymbExpr Token Char
-keychar c = term_parser (Char c) (const c)        -- helper for Char tokens
+-- | Parse a single character, using a 'SubsumesToken' type.
+keychar :: SubsumesToken t => Char -> SymbExpr t Char
+keychar c = term_parser (upcast (Char c)) (const c)        -- helper for Char tokens
 
--- | Parse a single character, using the 'Token' datatype.
-keyword :: String -> SymbExpr Token String
-keyword k = term_parser (Keyword k) (const k)        -- helper for Char tokens
+-- | Parse a single character, using a 'SubsumesToken' type.
+keyword :: SubsumesToken t => String -> SymbExpr t String
+keyword k = term_parser (upcast (Keyword k)) (const k)        -- helper for Char tokens
 
--- | Parse a single integer, using the 'Token' datatype.
+-- | Parse a single integer, using a 'SubsumesToken' type.
 -- Returns the lexeme interpreted as an integer.
-int_lit :: SymbExpr Token Int
-int_lit  = term_parser (IntLit Nothing) unwrap
- where  unwrap (IntLit (Just i))  = i
-        unwrap _                  = error "int_lit: the token must store lexeme"
+int_lit :: SubsumesToken t => SymbExpr t Int
+int_lit  = term_parser (upcast (IntLit Nothing)) (unwrap . downcast)
+ where  unwrap (Just (IntLit (Just i)))  = i
+        unwrap _ = error "int_lit: downcast, or token without lexeme"
 
--- | Parse a single Boolean, using the 'Token' datatype.
+-- | Parse a single Boolean, using a 'SubsumesToken' type.
 -- Returns the lexeme interpreter as a Boolean.
-bool_lit :: SymbExpr Token Bool
-bool_lit  = term_parser (BoolLit Nothing) unwrap
- where  unwrap (BoolLit (Just b))  = b
-        unwrap _                   = error "bool_lit: the token must store lexeme"
+bool_lit :: SubsumesToken t => SymbExpr t Bool
+bool_lit  = term_parser (upcast (BoolLit Nothing)) (unwrap . downcast)
+ where  unwrap (Just (BoolLit (Just b)))  = b
+        unwrap _ = error "bool_lit: downcast, or token without lexeme"
 
--- | Parse a single String literal, using the 'Token' datatype.
+-- | Parse a single String literal, using a 'SubsumesToken' type.
 -- Returns the lexeme interpreted as a String literal.
-string_lit :: SymbExpr Token String
-string_lit  = term_parser (StringLit Nothing) unwrap
- where  unwrap (StringLit (Just i)) = i
-        unwrap _                    = error "string_lit: the token must store lexeme"
+string_lit :: SubsumesToken t => SymbExpr t String
+string_lit  = term_parser (upcast (StringLit Nothing)) (unwrap . downcast)
+ where  unwrap (Just (StringLit (Just i))) = i
+        unwrap _ = error "string_lit: downcast, or token without lexeme"
 
--- | Parse a single identifier, using the 'Token' datatype.
--- Returns the lexeme as a String
-id_lit :: SymbExpr Token String
-id_lit = term_parser (IDLit Nothing) unwrap
- where  unwrap (IDLit (Just i)) = i
-        unwrap _                = error "id_lit: the token must store lexeme"
+-- | Parse a single identifier, using a 'SubsumesToken' type.
+-- Returns the lexeme as a String.
+id_lit :: SubsumesToken t => SymbExpr t String
+id_lit = term_parser (upcast (IDLit Nothing)) (unwrap . downcast)
+ where  unwrap (Just (IDLit (Just i))) = i
+        unwrap _ = error "id_lit: downcast, or token without lexeme"
 
--- | Parse a single arbitrary token, using the 'Token' datatype.
+-- | Parse a single alternative identifier, using a 'SubsumesToken' type.
+-- Returns the lexeme as a String.
+alt_id_lit :: SubsumesToken t => SymbExpr t String
+alt_id_lit = term_parser (upcast (AltIDLit Nothing)) (unwrap . downcast)
+ where  unwrap (Just (AltIDLit (Just i))) = i
+        unwrap _ = error "alt_id_lit: downcast, or token without lexeme"
+
+
+-- | Parse a single arbitrary token, using a 'SubsumesToken' type.
 -- Returns the lexeme.
-token :: String -> SymbExpr Token String
-token name = term_parser (Token name Nothing) unwrap
- where  unwrap (Token name' (Just i)) | name == name' = i
-        unwrap _                                      = error "tokenT: the token must store the lexeme"
+token :: SubsumesToken t => String -> SymbExpr t String
+token name = term_parser (upcast (Token name Nothing)) (unwrap . downcast)
+ where  unwrap (Just (Token name' (Just i))) | name == name' = i
+        unwrap _  = error "tokenT: downcast, or token without lexeme"
 
 epsilon :: (Show t, Ord t) => AltExpr t ()
-epsilon = AltExpr ([], M.insert x [Prod x []],\_ _ _ _ _ l r -> 
+epsilon = AltExpr ([], M.insert (pack x) [Prod (pack x) []],\_ _ _ _ _ l r -> 
                         if l == r then return [(l,())] else return [] )
     where x = "__eps"
 
@@ -498,7 +534,7 @@
 -- Use 'mkNt' to form a new unique non-terminal name based on
 -- the symbol of a given 'SymbExpr' and a 'String' that is unique to
 -- the newly defined combinator.
-mkNt :: (Show t, Ord t, IsSymbExpr s) => s t a -> String -> Nt
+mkNt :: (Show t, Ord t, IsSymbExpr s) => s t a -> String -> String 
 mkNt p str = let SymbExpr (myx,_,_) = mkRule p
                 in "_(" ++ show myx ++ ")" ++ str
 
@@ -528,20 +564,84 @@
 infixl 4 <**
 
 -- | 
--- Left-biased version of '<::='
+-- Version of '<::=' that prioritises productions from left-to-right (or top-to-bottom).
 x <::= altPs = mkNtRule True True x altPs 
 infixl 2 <::=
 
--- | Try to apply a parser `many' (0 or more) times. The results are returned in a list.
+-- | Try to apply a parser multiple times (0 or more). The results are returned in a list.
+-- In the case of ambiguity the largest list is returned.
 many :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t [a]
-many p = let fresh = mkNt p "*" --TODO using <:=> or <::=> ? 
-            in fresh <::=> (:) <$$> p <**> many p <||> satisfy []
+many = multiple_ rassoc 
+-- | Try to apply a parser multiple times (1 or more). The results are returned in a list.
+-- In the case of ambiguity the largest list is returned.
+many1 :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t [a]
+many1 = multiple1_ rassoc 
 
--- | Try to apply a parser `some' (1 or more) times. The results are returned in a list.
+-- | Try to apply a parser multiple times (0 or more). The results are returned in a list.
+-- In the case of ambiguity the largest list is returned.
 some :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t [a]
-some p = let fresh = mkNt p "+"
-            in fresh <::=> (:) <$$> p <**> many p 
+some = multiple_ lassoc 
 
+-- | Try to apply a parser multiple times (1 or more). The results are returned in a list.
+-- In the case of ambiguity the largest list is returned.
+some1 :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t [a]
+some1 = multiple1_ lassoc
+
+-- | Try to apply a parser multiple times (0 or more). The results are returned in a list.
+-- In the case of ambiguity the largest list is returned.
+multiple :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t [a]
+multiple = multiple_ id
+
+-- | Try to apply a parser multiple times (1 or more). The results are returned in a list.
+-- In the case of ambiguity the largest list is returned.
+multiple1 :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t [a]
+multiple1 = multiple1_ id
+
+-- | Internal
+multiple_ :: (Show t, Ord t, IsSymbExpr s) => (AltExpr t [a] -> AltExpr t [a]) ->
+                s t a -> SymbExpr t [a]
+multiple_ disa p = let fresh = mkNt p "*" 
+                    in fresh <::=> disa ((:) <$$> p <**> multiple p) <||> satisfy []
+
+-- | Internal
+multiple1_ :: (Show t, Ord t, IsSymbExpr s) => (AltExpr t [a] -> AltExpr t [a]) ->
+                s t a -> SymbExpr t [a]
+multiple1_ disa p = let fresh = mkNt p "+"
+                     in fresh <::=> disa ((:) <$$> p <**> multiple p)
+
+-- | Same as 'many' but with an additional separator.
+manySepBy :: (Show t, Ord t, IsSymbExpr s, IsSymbExpr s2, IsAltExpr s2) => 
+                s t a -> s2 t b -> SymbExpr t [a]
+manySepBy = sepBy many
+-- | Same as 'many1' but with an additional separator.
+manySepBy1 :: (Show t, Ord t, IsSymbExpr s, IsSymbExpr s2, IsAltExpr s2) => 
+                s t a -> s2 t b -> SymbExpr t [a]
+manySepBy1 = sepBy1 many
+-- | Same as 'some1' but with an additional separator.
+someSepBy :: (Show t, Ord t, IsSymbExpr s, IsSymbExpr s2, IsAltExpr s2) => 
+                s t a -> s2 t b -> SymbExpr t [a]
+someSepBy = sepBy some
+-- | Same as 'some1' but with an additional separator.
+someSepBy1 :: (Show t, Ord t, IsSymbExpr s, IsSymbExpr s2, IsAltExpr s2) => 
+                s t a -> s2 t b -> SymbExpr t [a]
+someSepBy1 = sepBy1 some
+-- | Same as 'multiple' but with an additional separator.
+multipleSepBy :: (Show t, Ord t, IsSymbExpr s, IsSymbExpr s2, IsAltExpr s2) => 
+                    s t a -> s2 t b -> SymbExpr t [a]
+multipleSepBy = sepBy multiple 
+-- | Same as 'multiple1' but with an additional separator.
+multipleSepBy1 :: (Show t, Ord t, IsSymbExpr s, IsSymbExpr s2, IsAltExpr s2) => 
+                    s t a -> s2 t b -> SymbExpr t [a]
+multipleSepBy1 = sepBy1 multiple 
+
+sepBy :: (Show t, Ord t, IsSymbExpr s1, IsSymbExpr s2, IsAltExpr s2) => 
+           (AltExpr t a -> SymbExpr t [a]) -> s1 t a -> s2 t b -> SymbExpr t [a]
+sepBy mult p c = mkRule $ satisfy [] <||> (:) <$$> p <**> mult (c **> p)
+
+sepBy1 :: (Show t, Ord t, IsSymbExpr s1, IsSymbExpr s2, IsAltExpr s2) => 
+           (AltExpr t a -> SymbExpr t [a]) -> s1 t a -> s2 t b -> SymbExpr t [a]
+sepBy1 mult p c = mkRule $ (:) <$$> p <**> mult (c **> p)
+
 -- | Try to apply a parser once, but proceed if unsuccessful 
 -- (yielding 'Nothing' as a result in that case).
 optional :: (Show t, Ord t, IsSymbExpr s) => s t a -> SymbExpr t (Maybe a)
@@ -564,8 +664,8 @@
 
 instance IsSymbExpr AltExprs where
     toSymb a = mkName <:=> a 
-        where mkName = "_(" ++ concat (intersperse "|" (map op (unOO a))) ++ ")_"
-                where op (AltExpr (rhs,_,_)) = concat (intersperse "*" (map show rhs))
+        where mkName = "_toSb(" ++ intercalate ")|(" (map op (unOO a)) ++ ")_"
+                where op (AltExpr (rhs,_,_)) = "(" ++ intercalate ")*(" (map show rhs) ++ ")"
 -- | 
 -- Class for lifting to 'AltExprs'. 
 class HasAlts a where
diff --git a/src/GLL/Combinators/Lexer.hs b/src/GLL/Combinators/Lexer.hs
new file mode 100644
--- /dev/null
+++ b/src/GLL/Combinators/Lexer.hs
@@ -0,0 +1,78 @@
+
+module GLL.Combinators.Lexer (
+    default_lexer, lexer, LexerSettings(..), emptyLanguage,
+    ) where
+
+import GLL.Types.Abstract (Token(..), SubsumesToken(..))
+import Data.Char (isSpace, isDigit, isAlpha, isUpper, isLower)
+import Text.Regex.Applicative
+
+-- | Settings for changing the behaviour of the builtin lexer 'lexer'.
+-- Lexers are built using "Text.Regex.Applicative".
+data LexerSettings = LexerSettings {
+        -- | Which keychars to recognise? Default: none.
+        keychars        :: [Char]
+        -- | Which keywords to recognise? Default: none.
+    ,   keywords        :: [String]
+        -- | What is considered a whitespace character? Default: 'Data.Char.isSpace'.
+    ,   whitespace      :: Char -> Bool
+        -- | How does a line comment start? Default: '"'//'"'.
+    ,   lineComment     :: String
+        -- | How to recognise identifiers? Default alphanumerical with lowercase alpha start.
+    ,   identifiers     :: RE Char String
+        -- | How to recognise alternative identifiers? Default alphanumerical with uppercase alpha start.
+    ,   altIdentifiers  :: RE Char String
+        -- | Arbitrary tokens /(a,b)/. /a/ is the token name, /b/ is a regular expression.
+    ,   tokens          :: [(String, RE Char String)]
+    }
+
+-- | The default 'LexerSettings'.
+emptyLanguage :: LexerSettings
+emptyLanguage = LexerSettings [] [] isSpace "//"
+    ((:) <$> psym isLower <*> lowercase_id)
+    ((:) <$> psym isUpper <*> lowercase_id)
+    []
+ where lowercase_id = many (psym (\c -> isAlpha c || c == '_' || isDigit c))
+
+-- | A lexer using the default 'LexerSettings'.
+default_lexer :: SubsumesToken t => String -> [t]
+default_lexer = lexer emptyLanguage 
+
+-- | A lexer parameterised by 'LexerSettings'.
+lexer :: SubsumesToken t => LexerSettings -> String -> [t]
+lexer _ [] = []
+lexer lexsets s =
+    let re =    (Just <$> lTokens lexsets)
+            <|> (Nothing <$ some (psym (whitespace lexsets)))
+            <|> (Nothing <$ string (lineComment lexsets) <* many (psym ((/=) '\n')))
+    in case findLongestPrefix re s of
+        Just (Just tok, rest)   -> tok : lexer lexsets rest
+        Just (Nothing,rest)     -> lexer lexsets rest
+        Nothing                 -> error ("lexical error at: " ++ show (take 10 s))
+
+lTokens :: SubsumesToken t => LexerSettings -> RE Char t 
+lTokens lexsets =
+        lCharacters
+    <|> lKeywords
+    <|> charsToInt  <$> optional (sym '-') <*> some (psym isDigit)
+    <|> upcast . IDLit . Just <$> identifiers lexsets 
+    <|> upcast . AltIDLit . Just <$> altIdentifiers lexsets
+    <|> upcast . StringLit . Just <$> lStringLit
+    <|> lMore
+    where   
+            charsToInt Nothing n = upcast (IntLit (Just (read n)))
+            charsToInt (Just _) n = upcast (IntLit (Just (-(read n))))
+
+            lChar c = upcast (Char c) <$ sym c
+            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
+
+            lStringLit = toString <$ sym '\"' <*> many strChar <* sym '\"'
+             where strChar =  sym '\\' *> sym '\"'
+                              <|> psym ((/=) '\"')
+                   toString inner = read ("\"" ++ inner ++ "\"")
diff --git a/src/GLL/Combinators/Options.hs b/src/GLL/Combinators/Options.hs
--- a/src/GLL/Combinators/Options.hs
+++ b/src/GLL/Combinators/Options.hs
@@ -34,6 +34,10 @@
 minimumPivot :: CombinatorOption
 minimumPivot opts = opts {pivot_select = Just (flip compare)}
 
+-- | Discards a pivot select option (internal use only)
+anyPivot :: CombinatorOption
+anyPivot opts = opts {pivot_select = Nothing}
+
 -- | Enables 'longest-match' at non-terminal level. 
 maximumPivotAtNt :: CombinatorOption
 maximumPivotAtNt opts = opts {pivot_select_nt = True, pivot_select = Just compare}
diff --git a/src/GLL/Combinators/Test/Interface.hs b/src/GLL/Combinators/Test/Interface.hs
--- a/src/GLL/Combinators/Test/Interface.hs
+++ b/src/GLL/Combinators/Test/Interface.hs
@@ -34,6 +34,7 @@
 import Data.IORef
 
 import GLL.Combinators.Interface
+import GLL.Parseable.Char ()
 
 -- | Defines and executes some unit-tests 
 main = do
@@ -233,6 +234,4 @@
 
     _EEE_3 = ["00111","01011","01101","01110","10011","10101","10110","11001","11010","111","11100"]
 
-instance Parseable Char where
-    eos = '$'
-    eps = '#'
+
diff --git a/src/GLL/Combinators/Visit/Sem.hs b/src/GLL/Combinators/Visit/Sem.hs
--- a/src/GLL/Combinators/Visit/Sem.hs
+++ b/src/GLL/Combinators/Visit/Sem.hs
@@ -19,7 +19,8 @@
 sem_nterm use_ctx left_biased x alts ps opts ctx sppf arr l r =
         let ctx' = ctx `toAncestors` (x,l,r)
             sems = zip alts ps 
-            seq (alt@(Prod _ rhs), va3) = va3 opts (alt,length rhs) ctx' sppf arr l r 
+            seq (alt@(Prod _ rhs), va3) = 
+                va3 opts (alt,length rhs) ctx' sppf arr l r 
         in if use_ctx && ctx `inAncestors` (Nt x, l, r) 
                 then return []
                 else do ass <- forM sems seq
@@ -70,5 +71,4 @@
                     Just m  -> Just $ IM.insertWith (S.union) r singleX m
         singleRX = IM.singleton r singleX
         singleX  = S.singleton x
-
 
diff --git a/src/GLL/Parseable/Char.hs b/src/GLL/Parseable/Char.hs
--- a/src/GLL/Parseable/Char.hs
+++ b/src/GLL/Parseable/Char.hs
@@ -1,6 +1,6 @@
 
 -- | Exports an instance for 'Parseable' 'Char' 
--- that sssumes '$' and '#' never appear in the inpur string.
+-- that assumes '$' and '#' never appear in the inpur string.
 module GLL.Parseable.Char () where
 
 import GLL.Types.Abstract
@@ -9,3 +9,4 @@
 instance Parseable Char where
     eos = '$'
     eps = '#'
+    matches = (==)
diff --git a/src/GLL/Parser.hs b/src/GLL/Parser.hs
--- a/src/GLL/Parser.hs
+++ b/src/GLL/Parser.hs
@@ -115,14 +115,15 @@
 @
 
 This instance mandates that \'$\' and '#' are 'reserved tokens' 
-and not part of the input string.
+and not part of the input string. This instance is available as an import: 
+"GLL.Parseable.Char".
 
-"GLL.Parser" exports 'Prod' for constructing 'Grammar's.
+"GLL.Parser" exports smart constructors for constructing 'Grammar's.
 
 @
-grammar1 = (\"X\", [Prod \"X\" [Nt \"A\", Nt \"A\"]
-                 ,Prod \"A\" [Term \'a\']
-                 ,Prod \"A\" [Term \'a\', Term \'a\']
+grammar1 = (start \"X\" , [prod \"X\" [nterm \"A\", nterm \"A\"]
+                      , prod \"A\" [term \'a\']
+                      , prod \"A\" [term \'a\', term \'a\']
                  ] )
 
 fail1       = "a"
@@ -158,7 +159,9 @@
 -}
 module GLL.Parser (
         -- * Grammar
-        Grammar(..), Prods(..), Prod(..), Symbols(..), Symbol(..), Slot(..),
+        Grammar(..), Prods(..), Prod(..), Symbols(..), Symbol(..), Slot(..), 
+        -- ** Smart constructors for creating 'Grammar's
+        start, prod, nterm, term,
         -- ** Parseable tokens 
         Parseable(..),
         -- * Run the GLL parser
@@ -181,10 +184,31 @@
 import qualified Data.Array as A
 import qualified Data.Set as S
 import qualified Data.IntSet as IS
+import Data.Text (pack)
 import Text.PrettyPrint.HughesPJ as PP
 
 import GLL.Types.Abstract
 import GLL.Types.Grammar
+
+-- | Create an 'Nt' (nonterminal) from a String.
+string2nt :: String -> Nt
+string2nt = pack
+
+-- | A smart constructor for creating a start 'Nt' (nonterminal).
+start :: String -> Nt
+start = string2nt
+
+-- | A smart constructor for creating a 'Prod' (production).
+prod :: String -> Symbols t -> Prod t
+prod x = Prod (string2nt x)
+
+-- | A smart constructor for creating a nonterminal 'Symbol'.
+nterm :: String -> Symbol t
+nterm = Nt . string2nt
+
+-- | A smart constructor for creating a terminal 'Symbol'.
+term :: t -> Symbol t
+term = Term
 
 -- | Representation of the input string
 type Input t        =   A.Array Int t 
diff --git a/src/GLL/Types/Abstract.hs b/src/GLL/Types/Abstract.hs
--- a/src/GLL/Types/Abstract.hs
+++ b/src/GLL/Types/Abstract.hs
@@ -3,12 +3,14 @@
 
 -- UUAGC 0.9.52.1 (src/GLL/Types/Abstract.ag)
 module GLL.Types.Abstract where
+
+import Data.Text
 {-# LINE 1 "src/GLL/Types/Abstract.ag" #-}
 
 {-# LINE 12 "dist/build/GLL/Types/Abstract.hs" #-}
 
 -- | Identifier for nonterminals.
-type Nt  = String
+type Nt  = Text 
 -- Prod ---------------------------------------------------------
 
 -- | 
@@ -56,6 +58,8 @@
            | BoolLit    (Maybe Bool)
            | StringLit  (Maybe String)
            | IDLit      (Maybe String)
+           -- | alternative identifiers, for example functions vs. constructors (as in Haskell).
+           | AltIDLit   (Maybe String) 
            | Token String (Maybe String)
 -- Tokens ------------------------------------------------------
 -- | 
@@ -78,8 +82,16 @@
     -- Override this method if, for example, your input tokens store lexemes
     -- while the grammar tokens do not
     matches :: a -> a -> Bool
-    matches = (==)
 
+-- | Class whose members are super-types of 'Token'.
+class SubsumesToken a where
+    upcast :: Token -> a
+    downcast :: a -> Maybe Token
+
+instance SubsumesToken Token where
+    upcast = id
+    downcast = Just . id
+
 deriving instance Ord Token
 deriving instance Eq Token
 
@@ -94,6 +106,8 @@
     show (BoolLit _)          = "<bool>"
     show (StringLit (Just s)) = "string(\"" ++ s ++ "\")"
     show (StringLit _)        = "<string>"
+    show (AltIDLit (Just id)) = "altid(\"" ++ id ++ "\")"
+    show (AltIDLit Nothing)   = "<altid>"
     show (IDLit  (Just id))   = "id(\"" ++ id ++ "\")"
     show (IDLit Nothing)      = "<id>"
     show (Token nm (Just s))  = nm ++ "(\"" ++ s ++ "\")"
@@ -111,6 +125,7 @@
     StringLit _ `matches` StringLit _  = True
     IntLit _    `matches` IntLit _     = True
     BoolLit _   `matches` BoolLit _    = True
+    AltIDLit _  `matches` AltIDLit _   = True
     IDLit _     `matches` IDLit _      = True
     _           `matches` _            = False
 
diff --git a/src/GLL/Types/Grammar.hs b/src/GLL/Types/Grammar.hs
--- a/src/GLL/Types/Grammar.hs
+++ b/src/GLL/Types/Grammar.hs
@@ -310,12 +310,12 @@
 -}
 
 instance (Show t) => Show (Slot t) where
-    show (Slot x alpha beta) = x ++ " ::= " ++ showRhs alpha ++ "." ++ showRhs beta    
+    show (Slot x alpha beta) = show x ++ " ::= " ++ showRhs alpha ++ "." ++ showRhs beta    
      where  showRhs [] = ""
             showRhs ((Term t):rhs) = show t ++ showRhs rhs
-            showRhs ((Nt x):rhs)   = x ++ showRhs rhs
+            showRhs ((Nt x):rhs)   = show x ++ showRhs rhs
 
 instance (Show t) => Show (Symbol t) where
-    show (Nt s)         = s
+    show (Nt s)         = show s
     show (Term t)       = show t
 
