diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+### 0.1.0.2
+
+- Changed the loop of `tokenize` from `many1` to `untilEnd` (internal parser in Token.hs). That’s
+  due to the fact `many1` silently ignores failures while `untilEnd` does not.
+- Changed implementation of `tokenize` to use `choice`, which is implemented exactly as we had.
+- Removed `identifier` and use `name` instead to relax conditions on formatting names.
+
 ### 0.1.0.1
 
 - Added forgotten Codec.Wavefront.
diff --git a/src/Codec/Wavefront/Token.hs b/src/Codec/Wavefront/Token.hs
--- a/src/Codec/Wavefront/Token.hs
+++ b/src/Codec/Wavefront/Token.hs
@@ -19,7 +19,7 @@
 import Codec.Wavefront.TexCoord
 import Control.Applicative ( Alternative(..) )
 import Data.Attoparsec.Text as AP
-import Data.Char ( isDigit, isLetter, isSpace )
+import Data.Char ( isSpace )
 import Data.Maybe ( catMaybes )
 import Data.Text ( Text, unpack )
 import qualified Data.Text as T ( empty )
@@ -45,9 +45,9 @@
 type TokenStream = [Token]
 
 tokenize :: Text -> Either String TokenStream
-tokenize = fmap cleanupTokens . analyseResult False . parse (many1 tokenizer)
+tokenize = fmap cleanupTokens . analyseResult False . parse (untilEnd tokenizer)
   where
-    tokenizer = foldl1 (<|>)
+    tokenizer = choice
       [
         fmap (Just . TknV) location
       , fmap (Just . TknVN) normal
@@ -147,13 +147,13 @@
 -- Groups ------------------------------------------------------------------------------------------
 
 groups :: Parser [Text]
-groups = skipSpace *> string "g " *> skipHSpace *> identifier `sepBy1` skipHSpace <* eol
+groups = skipSpace *> string "g " *> skipHSpace *> name `sepBy1` skipHSpace <* eol
 
 ----------------------------------------------------------------------------------------------------
 -- Objects -----------------------------------------------------------------------------------------
 
 object :: Parser Text
-object = skipSpace *> string "o " *> skipHSpace *> identifier <* eol
+object = skipSpace *> string "o " *> skipHSpace *> name <* eol
 
 ----------------------------------------------------------------------------------------------------
 -- Material libraries ------------------------------------------------------------------------------
@@ -187,10 +187,6 @@
 eol :: Parser ()
 eol = skipMany (satisfy isHorizontalSpace) *> (endOfLine <|> endOfInput)
 
--- Parse a digital and/or alpha identifier.
-identifier :: Parser Text
-identifier = takeWhile1 $ \c -> isDigit c || isLetter c
-
 -- Parse a name (any character but space).
 name :: Parser Text
 name = takeWhile1 $ not . isSpace
@@ -200,3 +196,13 @@
 
 float :: Parser Float
 float = fmap realToFrac double
+
+-- Loop a parser and collect its values until we hit the end of the stream. Fails on the first
+-- failure.
+untilEnd :: Parser a -> Parser [a]
+untilEnd p = go
+  where
+    go = do
+      a <- p
+      end <- atEnd
+      if end then pure [] else fmap (a:) go
diff --git a/wavefront.cabal b/wavefront.cabal
--- a/wavefront.cabal
+++ b/wavefront.cabal
@@ -1,5 +1,5 @@
 name:                wavefront
-version:             0.1.0.1
+version:             0.1.0.2
 synopsis:            Wavefront OBJ loader
 description:         A Wavefront OBJ loader. Currently supports polygonal information. More could
                      be added if needed (like curves and surface) if people contribute. Feel free
