Markdown railroad diagram maker
Turn a grammar into a railroad diagram. These syntax diagrams show the valid paths through a language or command, and read more easily than EBNF.
Railroad syntax
Railroad is a small indented text format made for this editor. The first line is the word railroad. Every line after it is one node: a type word, and for a few types a "text" in quotes. Indentation makes the tree — two spaces per level, so a line indented under another is its child. The top level is a row of nodes read left to right. Blank lines and lines starting with # are ignored.
railroad
term "SELECT"
choice
term "*"
nonterm columns
term "FROM"
nonterm table
optional
term "WHERE"
nonterm condition
Terminals and non-terminals
A term is a literal — the exact text a reader must type, drawn in a rounded box. A nonterm is the name of another rule, drawn in a plain box. Both take a "text". Quotes are optional for a single word, so nonterm table and nonterm "table" are the same.
railroad
term "print"
nonterm expression
Sequence and choice
A seq draws its children in a row, one after another. A choice stacks its children as branches — the reader takes any one. The first child of a choice is the straight-through line across the middle.
railroad
nonterm sign
choice
nonterm digit
seq
nonterm digit
nonterm digits
Optional and repeat
An optional draws a bypass around its child, so it can be skipped. A repeat draws a loop back over its child for one or more passes; a repeat0 loops for zero or more. Each of these wraps a single child — give it several lines and they are read as a sequence.
railroad
nonterm name
term "("
optional
nonterm args
term ")"
repeat0
nonterm statement
Comment and skip
A comment writes italic text on the line with no box, for an aside. A skip draws a bare line with nothing on it, useful as the empty branch of a choice.
railroad
comment "one or more"
repeat
nonterm item
choice
skip
term "!"
Cheat sheet
| Write this | You get |
|---|---|
railroad | First line — starts the diagram |
term "text" | A literal, in a rounded box |
nonterm "name" | A reference to another rule, in a plain box |
seq | Container — draws its children in a row |
choice | Container — stacks its children as branches (first = straight through) |
optional | Container — draws a bypass around its child |
repeat | Container — loops its child one or more times |
repeat0 | Container — loops its child zero or more times |
comment "text" | Italic text with no box |
skip | An empty line — nothing to match |
| two-space indent | Makes the indented node a child of the one above |
# note | A source comment line — ignored |