Fixed infinite loop

- fixed infinite loop when parsing
```{;}```
diff --git a/parser/parser.go b/parser/parser.go
index 6a2d7ee..a0132ea 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -127,7 +127,6 @@
 	if parser.tokenAtKeyword() {
 		return parser.parseAtRule()
 	}
-
 	return parser.parseQualifiedRule()
 }
 
@@ -286,6 +285,10 @@
 
 			// finished
 			break
+		} else if parser.tokenChar(";") {
+			parser.shiftToken()
+			// finished
+			break
 		} else {
 			// parse prelude
 			prelude, err, tokens := parser.parsePrelude()
diff --git a/parser/parser_test.go b/parser/parser_test.go
index f4f98e8..89d0ecc 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -11,11 +11,11 @@
 func MustParse(t *testing.T, txt string, nbRules int) *css.Stylesheet {
 	stylesheet, err := Parse(txt)
 	if err != nil {
-		t.Fatal("Failed to parse css", err, txt)
+		t.Fatal("Failed to parse CSS", err, txt)
 	}
 
 	if len(stylesheet.Rules) != nbRules {
-		t.Fatal("Failed to parse Qualified Rules", txt)
+		t.Fatal(fmt.Sprintf("Failed to parse CSS \"%s\", expected %d rules but got %d", txt, nbRules, len(stylesheet.Rules)))
 	}
 
 	return stylesheet
@@ -858,3 +858,25 @@
 
 	MustEqualRule(t, rule, expectedRule)
 }
+
+func TestInfiniteLoop(t *testing.T) {
+	input := "{;}"
+
+	expectedRule := &css.Rule{
+		Kind:    css.QualifiedRule,
+		Prelude: "",
+		Selectors: []*css.Selector{
+			{
+				Value:  "",
+				Line:   0,
+				Column: 0,
+			},
+		},
+		Declarations: []*css.Declaration{},
+	}
+
+	stylesheet := MustParse(t, input, 1)
+	rule := stylesheet.Rules[0]
+
+	MustEqualRule(t, rule, expectedRule)
+}