2011-01-30 19:26:03 +00:00
|
|
|
|
|
|
|
S-Expression Support in Kicad
|
|
|
|
============================================================================
|
|
|
|
Author: Dick Hollenbeck
|
|
|
|
Date: Jan 2011
|
|
|
|
|
|
|
|
|
|
|
|
An s-expression is a text stream or string, in the same vain as XML, consisting
|
|
|
|
of a sequence of elements. Each element is either an atom or list. An atom
|
|
|
|
corresponds to a string, while a list corresponds to an s-expression. The
|
|
|
|
following grammar represents our definition of an s-expression:
|
|
|
|
|
|
|
|
sexpr ::= ( sx )
|
2011-01-30 20:58:15 +00:00
|
|
|
sx ::= atom sxtail | sexpr sxtail | NULL
|
2011-01-30 19:26:03 +00:00
|
|
|
sxtail ::= sx | NULL
|
|
|
|
atom :: quoted | value
|
|
|
|
quoted :: "ws_string"
|
|
|
|
value :: nws_string
|
|
|
|
|
|
|
|
An atom can either be a quoted string, which is a string containing whitespace
|
|
|
|
surrounded by double quotes, or a non-whitespace string that does not require
|
|
|
|
surrounding quotes.
|
|
|
|
|
|
|
|
The s-expression syntax used in Kicad uses two quoting/syntax strategies, given
|
|
|
|
by the needs of the Specctra DSN specification and of our own non-specctra
|
|
|
|
needs. The Specctra DSN specification is not very clear with regard to quoting
|
|
|
|
and on top of that there is Freerouter's interpretation, which would actually
|
|
|
|
supercede anything in the Specctra DSN spec anyway, due to a desire to be
|
|
|
|
compatible with Freerouter.
|
|
|
|
|
|
|
|
We have our own needs, which go beyond those of the Specctra DSN spec, so we
|
|
|
|
support the two syntaxes or quoting protocols for quoted atoms:
|
|
|
|
|
|
|
|
1) Specctra quoting protocol (specctraMode)
|
|
|
|
2) Kicad quoting protocol (non-specctraMode)
|
|
|
|
|
|
|
|
We can control our own destiny better by having a separately defined mode for
|
|
|
|
non Specctra DSN files.
|
|
|
|
|
|
|
|
To summarize, in specctraMode Freerouter dictates to us what we need to do. In
|
|
|
|
non-specctraMode, which can be thought of as Kicad mode, we have our own quoting
|
|
|
|
protocol and can make changes without breaking the specctraMode.
|
|
|
|
|
|
|
|
There needs to be agreement between how a file is saved, and how a file is read
|
|
|
|
back in, in either mode, to fulfill the round-tripping requirements. A file
|
|
|
|
written using one mode may not necessarily be readable using the other mode,
|
|
|
|
although it might be. Just don't count on it.
|
|
|
|
|
|
|
|
|
|
|
|
In Kicad mode:
|
|
|
|
|
|
|
|
OUTPUTFORMATTER::Quoted() is the tool to wrap s-expression atoms.
|
|
|
|
DSNLEXER::NexTok() is basically the inverse function, and reads tokens back in.
|
|
|
|
These two must agree, so that what is written out comes back in un-altered.
|
|
|
|
|
|
|
|
The decision to wrap the string or not is left to the Quoted() function. If the
|
|
|
|
string is wrapped, it will also escape internal double quotes, \n's and \r's.
|
|
|
|
Any null string is wrapped in quotes, and so is any string which starts with
|
|
|
|
'#', so that it is not confused with an s-expression comment.
|
|
|
|
|
|
|
|
|
|
|
|
Kicad S-expression Syntax and Quoting Protocol (non-specctraMode):
|
|
|
|
==================================================================
|
|
|
|
|
2011-01-30 20:58:15 +00:00
|
|
|
*) Some atoms are considered keywords, and constitute a grammar superimposed on
|
|
|
|
the s-expressions. All keywords are ASCII and lowercase. International characters
|
|
|
|
are not to be used here.
|
2011-01-30 19:26:03 +00:00
|
|
|
|
2011-01-30 20:58:15 +00:00
|
|
|
*) All Kicad s-expression files are saved using a UTF8 encoding and should
|
|
|
|
support any international characters in the atoms which are not keywords.
|
2011-01-30 19:26:03 +00:00
|
|
|
|
|
|
|
*) DSNLEXER::NextTok() requires that any token be on a single line of input. If
|
|
|
|
you want to save a multi-line string, Quoted() will automatically escape the \n
|
|
|
|
or \r for you and put the output on a single line. It should round-trip fine.
|
|
|
|
|
2011-01-30 20:58:15 +00:00
|
|
|
*) There can be escape sequences in a quoted string only. Escape sequences allow
|
|
|
|
foreign tools to generate byte patterns in the input stream. C style 2 byte hex
|
|
|
|
codes are supported, and so are 3 byte octal escape sequences. See
|
|
|
|
DSNLEXER::NextTok() for the full list of escape sequences, by searching file
|
|
|
|
dsnlexer.cpp for the string "ESCAPE SEQUENCES". Any use of the escape mechanism
|
|
|
|
must still produce UTF-8 encoded text after the escape handling is applied.
|
2011-01-30 19:26:03 +00:00
|
|
|
|
|
|
|
*) Just because an escape sequence is supported on input, does not mean that
|
|
|
|
OUTPUTFORMATTER::Quoted() must generate such an escape sequence for output. For
|
|
|
|
example, having true tabs in the s-expression file is OK. So that will not be
|
|
|
|
escaped on output. Other similar cases exist.
|
|
|
|
|
|
|
|
*) Backslash is the escape byte.
|
|
|
|
|