diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -23,10 +23,7 @@
 ----------------------
 
 The following are all valid expression forms which can be parsed by Hatt, where
-ϕ and ψ are metalinguistic variables standing in for any valid expression. The
-parser isn't as smart about parentheses as it could be, so you have to follow
-these rules quite literally. This shouldn't be a great hardship, but it does
-mean that, for example, while `(A -> B)` is a valid expression, `A -> B` isn't.
+ϕ and ψ are metalinguistic variables standing in for any valid expression.
 
 * Variables: `P`, `Q`, `a`, `b` etc.---basically anything in the character
   class `[a-zA-Z]`
@@ -35,6 +32,13 @@
 * Disjunction: `(ϕ | ψ)`
 * Conditional: `(ϕ -> ψ)`
 * Biconditional: `(ϕ <-> ψ)`
+
+For top-level formulae where the primary connective is a binary one, parentheses
+are not required. For example, the expression `a | b` is valid and will be
+parsed correctly.
+
+There is currently no support for operator precedence, so nested expressions
+must be parenthesised correctly for the parser to make sense of them.
 
 
 Using the `hatt` command-line program
diff --git a/hatt.cabal b/hatt.cabal
--- a/hatt.cabal
+++ b/hatt.cabal
@@ -1,5 +1,5 @@
 Name:               hatt
-Version:            1.3.1
+Version:            1.4.0
 
 Synopsis:           A truth table generator for classical propositional logic.
 Description:        Hatt is a command-line program which prints truth tables
diff --git a/src/Data/Logic/Propositional/Parser.hs b/src/Data/Logic/Propositional/Parser.hs
--- a/src/Data/Logic/Propositional/Parser.hs
+++ b/src/Data/Logic/Propositional/Parser.hs
@@ -8,7 +8,7 @@
 import Data.Logic.Propositional.Core (Expr (..))
 
 import Text.ParserCombinators.Parsec
-    (char, choice, eof, oneOf, parse, spaces, string)
+    ((<|>), char, choice, eof, letter, parse, spaces, string, try)
 
 import Text.ParserCombinators.Parsec.Error (ParseError)
 import Text.ParserCombinators.Parsec.Pos (SourceName)
@@ -36,7 +36,7 @@
 
 statement :: GenParser Char st Expr
 statement = do spaces
-               x <- expr
+               x <- try binary <|> expr
                spaces
                eof
                return x
@@ -45,33 +45,34 @@
 expr = choice [binaryP, negation, variable]
 
 variable :: GenParser Char st Expr
-variable = do c <- oneOf variableChars
+variable = do c <- letter
               return $ Variable [c]
 
 negation :: GenParser Char st Expr
 negation = do char '~'
+              spaces
               x <- expr
               return $ Negation x
 
 binaryP :: GenParser Char st Expr
 binaryP = do char '('
+             spaces
              x <- binary
+             spaces
              char ')'
              return x
 
 binary :: GenParser Char st Expr
 binary = do x1 <- expr
             spaces
-            s  <- choice [string "&", string "|", string "->", string "<->"]
+            s  <- choice $ map string ["&", "|", "->", "<->"]
             spaces
             x2 <- expr
             return $ connective s x1 x2
   where
-    connective "&"   = Conjunction
-    connective "|"   = Disjunction
-    connective "->"  = Conditional
-    connective "<->" = Biconditional
-    connective _     = error "Impossible case"
-
-variableChars :: String
-variableChars = ['a'..'z'] ++ ['A'..'Z']
+    connective c = case c of
+      "&"   -> Conjunction
+      "|"   -> Disjunction
+      "->"  -> Conditional
+      "<->" -> Biconditional
+      _     -> error "Impossible case"
diff --git a/src/hatt.hs b/src/hatt.hs
--- a/src/hatt.hs
+++ b/src/hatt.hs
@@ -31,7 +31,7 @@
   , interactive = False &= help "Enter interactive mode"
   , pretty      = False &= help "Use Unicode logic symbols"
   , coloured    = False &= help "Use colour-coded symbols"
-  } &= summary "Hatt 1.3.1, (c) Benedict Eastaugh 2011"
+  } &= summary "Hatt 1.4.0, (c) Benedict Eastaugh 2011"
     &= program "hatt"
 
 main :: IO ()
