Parsing and Checking Inputs#
Fandango can also use its specifications to parse given inputs and to check if they conform to the specification - both
syntactically (according to the grammar); and
semantically (according to the constraints).
The parse
command#
To parse an existing input, Fandango provides a parse
command.
Its arguments are any files to be parsed; if no files are given, parse
reads from standard input.
As with the fuzz
command, providing a specification (with -f FILE.fan
) is mandatory.
Let us use parse
to check some dates against the ISO 8601 format we have written a Fandango spec for.
The command echo -n
outputs the string given as argument (-n
suppresses the newline it would normally produce); the pipe symbol |
feeds this as input into Fandango:
$ echo -n '2025-01-27' | fandango parse -f iso8601.fan
If we do this, nothing happens. That is actually a good sign: it means that Fandango has successfully parsed the input.
If we pass an invalid input, however, Fandango will report this. This holds for syntactically invalid inputs:
$ echo -n '01/27/2025' | fandango parse -f iso8601.fan
FandangoParseError: '<stdin>', line 1, column 4: mismatched input '2'
FandangoParseError: 1 error(s) during parsing
And also for semantically invalid inputs:
$ echo -n '2025-02-29' | fandango parse -f iso8601.fan
FandangoError: '<stdin>': constraint is_valid_iso8601datetime(str(<iso8601datetime>)) not satisfied
FandangoParseError: 1 error(s) during parsing
In both cases, the return code will be non-zero:
$ echo $?
1
Validating Parse Results#
By default, the parse
command produces no output.
However, to inspect the parse results, you can output the parsed string again.
The -o FILE
option writes the parsed string to FILE
, with -
being the standard output.
$ echo -n '2025-01-27' | fandango parse -f iso8601.fan -o -
2025-10-27
We see that input and output are identical (as should always be with parsing and unparsing).
Tip
As it comes to producing and storing outputs, the parse
command has the same options as the fuzz
command.
Since parsing and unparsing should always be symmetrical to each other, Fandango provides a --validate
option to run this check automatically:
$ echo -n '2025-01-27' | fandango parse -f iso8601.fan --validate
Again, if nothing happens, then the (internal) check was successful.
The --validate
option can also be passed to the fuzz
command; here, it ensures that the produced string can be parsed by the same grammar (again, as should be).
Tip
If you find that --validate
fails, please report this as a Fandango bug.
Alternate Output Formats#
In order to debug grammars, Fandango provides a number of alternate formats in which to output the parsed tree, controlled by the --format
flag.
String#
The option --format=string
outputs the parsed tree as a string. This is the default.
$ echo -n '2025-01-27' | fandango parse -f iso8601.fan -o - --format=string
2025-10-27
Tree#
The option --format=string
outputs the parsed tree as a Python Tree()
expression. This is useful for evaluating and visualizing the tree.
$ echo -n '2025-01-27' | fandango parse -f iso8601.fan -o - --format=tree
Tree('<start>', Tree('<iso8601datetime>',
Tree('<iso8601date>', Tree('<iso8601calendardate>',
Tree('<iso8601year>',
Tree(''),
Tree('<digit>', Tree('<_digit>', Tree('2'))),
Tree('<digit>', Tree('<_digit>', Tree('0'))),
Tree('<digit>', Tree('<_digit>', Tree('2'))),
Tree('<digit>', Tree('<_digit>', Tree('5')))
),
Tree('-'),
Tree('<iso8601month>', Tree('10')),
Tree('-'),
Tree('<iso8601day>', Tree('27'))
)),
Tree('')
))
Here comes this tree, visualized:

Grammar#
The option --format=grammar
outputs the parsed tree as a (highly specialized) grammar, in which
children are indented under their respective parents.
This is useful for debugging, but also for creating a grammar from a sample file and then generalizing it.
$ echo -n '2025-01-27' | fandango parse -f iso8601.fan -o - --format=grammar
<start> ::= <iso8601datetime>
<iso8601datetime> ::= <iso8601date> '' # Position 0x0000 (0); '2025-10-27'
<iso8601date> ::= <iso8601calendardate>
<iso8601calendardate> ::= <iso8601year> '-' <iso8601month> '-' <iso8601day> # Position 0x0000 (0); '2025-10-27'
<iso8601year> ::= '' <digit> <digit> <digit> <digit> # Position 0x0002 (2); '2025'
<digit> ::= <_digit>
<_digit> ::= '2' # Position 0x0002 (2)
<digit> ::= <_digit>
<_digit> ::= '0' # Position 0x0003 (3)
<digit> ::= <_digit>
<_digit> ::= '2' # Position 0x0004 (4)
<digit> ::= <_digit>
<_digit> ::= '5' # Position 0x0005 (5)
<iso8601month> ::= '10' # Position 0x0006 (6)
<iso8601day> ::= '27' # Position 0x0008 (8)
Bits#
The option --format=bits
outputs the parsed tree as a bit sequence.
$ echo -n '2025-01-27' | fandango parse -f iso8601.fan -o - --format=bits
00110010001100000011001000110101001011010011000100110000001011010011001000110111
This is useful for debugging binary formats that contain bits.