diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,7 @@
+0.1.10.0
+-------
+* allow parsing empty `<sum>`. https://github.com/msakai/pseudo-boolean/pull/5
+
 0.1.9.0
 -------
 * fix compilation error with `megaparsec <4.4` due to the lack of MonadPlus requirement
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,7 +1,8 @@
 # pseudo-boolean
 Haskell library for parsing/generating OPB/WBO files used in pseudo boolean competition.
 
-[![Build Status](https://travis-ci.org/msakai/pseudo-boolean.svg?branch=master)](https://travis-ci.org/msakai/pseudo-boolean)
+[![Build Status (Travis-CI)](https://travis-ci.org/msakai/pseudo-boolean.svg?branch=master)](https://travis-ci.org/msakai/pseudo-boolean)
+[![Build Status (GitHub Actions)](https://github.com/msakai/pseudo-boolean/workflows/build/badge.svg)](https://github.com/msakai/pseudo-boolean/actions)
 [![Coverage Status](https://coveralls.io/repos/msakai/pseudo-boolean/badge.svg)](https://coveralls.io/r/msakai/pseudo-boolean)
 [![Hackage](https://img.shields.io/hackage/v/pseudo-boolean.svg)](https://hackage.haskell.org/package/pseudo-boolean)
 [![Hackage Deps](https://img.shields.io/hackage-deps/v/pseudo-boolean.svg)](https://packdeps.haskellers.com/feed?needle=pseudo-boolean)
diff --git a/pseudo-boolean.cabal b/pseudo-boolean.cabal
--- a/pseudo-boolean.cabal
+++ b/pseudo-boolean.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                pseudo-boolean
-version:             0.1.9.0
+version:             0.1.10.0
 synopsis:            Reading/Writing OPB/WBO files used in pseudo boolean competition
 description:         Reading\/Writing OPB\/WBO files used in pseudo boolean competition
 homepage:            https://github.com/msakai/pseudo-boolean
@@ -27,7 +27,9 @@
    GHC ==8.0.2
    GHC ==8.2.2
    GHC ==8.4.4
-   GHC ==8.6.3
+   GHC ==8.6.5
+   GHC ==8.8.4
+   GHC ==8.10.4
 
 source-repository head
   type:     git
@@ -53,13 +55,13 @@
      FlexibleContexts
      OverloadedStrings
   build-depends:
-     base >=4.6.0.1 && <4.14,
+     base >=4.6.0.1 && <4.16,
      containers >=0.4.2.1,
      parsec >=3.1.2 && <4,
-     megaparsec >=4 && <8,
-     bytestring >=0.9.2.1 && <0.11,
+     megaparsec >=4 && <10,
+     bytestring >=0.9.2.1 && <0.12,
      bytestring-builder,
-     dlist >=0.7.0 && <0.9.0,
+     dlist >=0.7.0 && <1.1.0,
      attoparsec >=0.10.4.0,
      deepseq >=1.3.0.0,
      hashable >=1.1.2.5 && <1.4.0.0,
diff --git a/src/Data/PseudoBoolean/Attoparsec.hs b/src/Data/PseudoBoolean/Attoparsec.hs
--- a/src/Data/PseudoBoolean/Attoparsec.hs
+++ b/src/Data/PseudoBoolean/Attoparsec.hs
@@ -126,7 +126,7 @@
 
 -- <sum>::= <weightedterm> | <weightedterm> <sum>
 sum :: Parser Sum
-sum = many1 weightedterm
+sum = many' weightedterm -- we relax the grammer to allow empty sum
 
 -- <weightedterm>::= <integer> <oneOrMoreSpace> <term> <oneOrMoreSpace>
 weightedterm :: Parser WeightedTerm
diff --git a/src/Data/PseudoBoolean/Megaparsec.hs b/src/Data/PseudoBoolean/Megaparsec.hs
--- a/src/Data/PseudoBoolean/Megaparsec.hs
+++ b/src/Data/PseudoBoolean/Megaparsec.hs
@@ -184,7 +184,7 @@
 
 -- <sum>::= <weightedterm> | <weightedterm> <sum>
 sum :: C e s m => m Sum
-sum = some weightedterm
+sum = many weightedterm -- we relax the grammer to allow empty sum
 
 -- <weightedterm>::= <integer> <oneOrMoreSpace> <term> <oneOrMoreSpace>
 weightedterm :: C e s m => m WeightedTerm
diff --git a/src/Data/PseudoBoolean/Parsec.hs b/src/Data/PseudoBoolean/Parsec.hs
--- a/src/Data/PseudoBoolean/Parsec.hs
+++ b/src/Data/PseudoBoolean/Parsec.hs
@@ -126,7 +126,7 @@
 
 -- <sum>::= <weightedterm> | <weightedterm> <sum>
 sum :: Stream s m Char => ParsecT s u m Sum
-sum = many1 weightedterm
+sum = many weightedterm -- we relax the grammer to allow empty sum
 
 -- <weightedterm>::= <integer> <oneOrMoreSpace> <term> <oneOrMoreSpace>
 weightedterm :: Stream s m Char => ParsecT s u m WeightedTerm
diff --git a/test/TestPBFile.hs b/test/TestPBFile.hs
--- a/test/TestPBFile.hs
+++ b/test/TestPBFile.hs
@@ -41,6 +41,10 @@
 case_normalized_opt_market_split_4_30_2 = checkOPBFile "test/samples/normalized-opt-market-split_4_30_2.opb"
 case_pigeonhole_5_4 = checkOPBFile "test/samples/pigeonhole_5_4.opb"
 
+case_invalid_obj_empty_sum = checkOPBFile "test/samples/invalid-obj-empty-sum.opb"
+case_invalid_lhs_empty_sum = checkOPBFile "test/samples/invalid-lhs-empty-sum.opb"
+case_invalid_lhs_empty_sum_wbo = checkWBOFile "test/samples/invalid-lhs-empty-sum.wbo"
+
 case_trailing_junk = do
   isError (parseOPBString "" trailingJunk) @?= True
   isError (M.parseOPBString "" trailingJunk) @?= True
diff --git a/test/samples/invalid-lhs-empty-sum.opb b/test/samples/invalid-lhs-empty-sum.opb
new file mode 100644
--- /dev/null
+++ b/test/samples/invalid-lhs-empty-sum.opb
@@ -0,0 +1,4 @@
+* #variable= 0 #constraint= 1
+* This is invalid according to the grammer of http://www.cril.univ-artois.fr/PB11/format.pdf ,
+* but we relax the grammar to allow it.
+>= 0;
diff --git a/test/samples/invalid-lhs-empty-sum.wbo b/test/samples/invalid-lhs-empty-sum.wbo
new file mode 100644
--- /dev/null
+++ b/test/samples/invalid-lhs-empty-sum.wbo
@@ -0,0 +1,6 @@
+* #variable= 0 #constraint= 2 #soft= 1 mincost= 1 maxcost= 1 sumcost= 1
+* This is invalid according to the grammer of http://www.cril.univ-artois.fr/PB11/format.pdf ,
+* but we relax the grammar to allow it.
+soft: ;
+[1] >= 1;
+>= 0;
diff --git a/test/samples/invalid-obj-empty-sum.opb b/test/samples/invalid-obj-empty-sum.opb
new file mode 100644
--- /dev/null
+++ b/test/samples/invalid-obj-empty-sum.opb
@@ -0,0 +1,4 @@
+* #variable= 0 #constraint= 0
+* This is invalid according to the grammer of http://www.cril.univ-artois.fr/PB11/format.pdf ,
+* but we relax the grammar to allow it.
+min: ;
