Skip to content

Instantly share code, notes, and snippets.

@thomasdunn
Last active March 7, 2019 05:13
Show Gist options
  • Save thomasdunn/d70be5cc43a2b29ae93ffb07e7e9c067 to your computer and use it in GitHub Desktop.
Save thomasdunn/d70be5cc43a2b29ae93ffb07e7e9c067 to your computer and use it in GitHub Desktop.
Run Length Encoded (RLE) File Format Augmented BNF Style Grammar

Run Length Encoded (RLE) File Format Grammar

See http://www.conwaylife.com/wiki/Run_Length_Encoded

For description of this Augmented BNF Style Grammar, see https://tools.ietf.org/html/rfc2616/#section-2.1

RLE files general structure:

    - Zero or more comment lines that can specify metadata
    - Optional header line that specifies height, width, and rule
    - The pattern itself encoded with run lengths

RLE generators SHOULD NOT create lines that exceed 70 characters.
RLE parsers SHOULD allow parsing of lines that exceed 70 characters.
DOS, Unix, and Mac newline conventions are all acceptable.
The final "!" should be present but its best to treat it as optional.

    rle-file        = *(hash-line)
                      [header-line]                           
                      1*(run-item [LWS]) ["!"] [end-matter]

"# Lines" allow for comments and metadata.  These lines appear before the header.
For the rule set, semi-totalistic format is common, but should allow for
formats for other types of cellular automata, as well as rule nicknames.

    hash-line       = "#" line-type LWS (comment | hash-rule-set | *TEXT) CRLF
    line-type       = "C" | "c"  ; comment
                    | "N"        ; pattern name
                    | "O"        ; file creator
                    | "P" | "R"  ; top-left corner coordinates
                    | "r"        ; rule-set
    comment         = *TEXT
    hash-rule-set   = (hash-semi-totalistic-rule-set | *TEXT)
    hash-semi-totalistic-rule-set   = survival-counts "/" birth-counts
    birth-counts                    = *(DIGIT)  ; # of live neighbors for cell birth
    survival-counts                 = *(DIGIT)  ; # of live neighbors for cell survival

Header lines are optional.  If "#r" is omitted and a header line with a specified "rule"
is omitted the rule set S23/B3 MAY be assumed, or use simulator rule settings.

    header-line     = "x = " pattern-width ", y = " pattern-height
                      [", rule = " rule-set] CRLF
    pattern-width   = *DIGIT     ; the width, in cells, of the pattern
    pattern-height  = *DIGIT     ; the height, in cells, of the pattern
    rule-set        = (semi-totalistic-rule-set | *TEXT)
    semi-totalistic-rule-set  = ("b" | "B") birth-counts "/" ("s" | "S") survival-counts

Patterns are encoded with a number that describes how many times to repeat the following
character.  Dead cells at the end of a pattern line do not need to be encoded, nor
does the end of the last line of the pattern.  RLE writers should adhere to the status
spacing shown, but RLE readers are best not to assume it.  Letters other than b and o
may be used for the <tag>s to represent extra states. Unless the cellular automaton has
more than 26 states it is a good idea to stick to lowercase letters. RLE readers that
cannot handle more than two states should treat all letters other than b (and perhaps B)
as equivalent to o.

    run-item        = [run-count] tag ; run-count can be omitted if it is 1
    run-count       = ("1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9") *(DIGIT)   
    tag             = "b" | "B"  ; dead cell
                    | "o" | "O"  ; alive cell
                    | "$"        ; end of line
                    | CHAR       ; for additional states; if not understood, treat as o

End matter follows the final "!".  It is mainly used for comments.  # Lines here would
likely be the "#C" comment type.

    end-matter       = *(CRLF) *(end-file-comment) 
    end-file-comment = (hash-line | comment *(CRLF))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment