Score files are meant to be easily parsable, but yet extremely malleable. It was decided that something that had the same read syntax as an Emacs Lisp list would fit that spec.
Here’s a typical score file:
(("summary" ("Windows 95" -10000 nil s) ("Gnus")) ("from" ("Lars" -1000)) (mark -100))
BNF definition of a score file:
score-file = "" / "(" *element ")" element = rule / atom rule = string-rule / number-rule / date-rule string-rule = "(" quote string-header quote space *string-match ")" number-rule = "(" quote number-header quote space *number-match ")" date-rule = "(" quote date-header quote space *date-match ")" quote = <ascii 34> string-header = "subject" / "from" / "references" / "message-id" / "xref" / "body" / "head" / "all" / "followup" number-header = "lines" / "chars" date-header = "date" string-match = "(" quote <string> quote [ "" / [ space score [ "" / space date [ "" / [ space string-match-t ] ] ] ] ] ")" score = "nil" / <integer> date = "nil" / <natural number> string-match-t = "nil" / "s" / "substring" / "S" / "Substring" / "r" / "regex" / "R" / "Regex" / "e" / "exact" / "E" / "Exact" / "f" / "fuzzy" / "F" / "Fuzzy" number-match = "(" <integer> [ "" / [ space score [ "" / space date [ "" / [ space number-match-t ] ] ] ] ] ")" number-match-t = "nil" / "=" / "<" / ">" / ">=" / "<=" date-match = "(" quote <string> quote [ "" / [ space score [ "" / space date [ "" / [ space date-match-t ] ] ] ] ")" date-match-t = "nil" / "at" / "before" / "after" atom = "(" [ required-atom / optional-atom ] ")" required-atom = mark / expunge / mark-and-expunge / files / exclude-files / read-only / touched optional-atom = adapt / local / eval mark = "mark" space nil-or-number nil-or-number = "nil" / <integer> expunge = "expunge" space nil-or-number mark-and-expunge = "mark-and-expunge" space nil-or-number files = "files" *[ space <string> ] exclude-files = "exclude-files" *[ space <string> ] read-only = "read-only" [ space "nil" / space "t" ] adapt = "adapt" [ space "ignore" / space "t" / space adapt-rule ] adapt-rule = "(" *[ <string> *[ "(" <string> <integer> ")" ] ")" local = "local" *[ space "(" <string> space <form> ")" ] eval = "eval" space <form> space = *[ " " / <TAB> / <NEWLINE> ]
Any unrecognized elements in a score file should be ignored, but not discarded.
As you can see, white space is needed, but the type and amount of white space is irrelevant. This means that formatting of the score file is left up to the programmer—if it’s simpler to just spew it all out on one looong line, then that’s ok.
The meaning of the various atoms are explained elsewhere in this manual (see Score File Format).