SWEET S-Expression Grammar Describing a

Schematic Part String Format Specification

Authors:

Wayne Stambaugh

Dick Hollenbeck

Original Edits: January 2011

Latest Edits: April 2011

Introduction
The purpose of this document is to define the new format for the Kicad schematic part descriptions, as expressed using the new SWEET grammar. This format supersedes the old file format defined in the file “library_file_format_EN.odt. The idea of component library files is no longer valid. The unit of retrieval from the new distributed library system is the part, not a library. To learn more about the new distributed library system see the design.h document in the Kicad source tree, or better yet, the Doxygen generated material therefrom.
The SWEET grammar format is based on the Specttra DSN lexer[1] work graciously coded and contributed by Dick Hollenbeck. For those not familiar with the DSN format, it is very similar the the LISP programming language in that keywords are delimited by braces. It is also known as an S-expression format. A keyword may have zero or more tokens that behave like parameters for the keyword. Tokens may be defined as additional keywords creating a programming language like structure. The decision to change to this format is driven by a desire to provide a more robust file lexer, a human readable file format, better retrieval error reporting, and improved extensibility. The other driving factor is to provide a more robust format for handling the various requirements of the component library developers.
[1] See source files dsnlexer.cpp and dsnlexer.h in the Kicad source code for more information about how the DSN lexer works.

Front Matter
This is a living document designed to be kept synchronized with the actual source code. If you modify the lexer, please update this specification as courtesy to other developers. There are many third party tools that are used to generate, manipulate, and parse component library files. Keeping this document current is vital to developers of these tools.

Formatting
The DSN lexer enforces strict formatting requirements. Files must be encoded in UTF8 format. All lexer keywords are comprised of lower case letters, numbers, and underscores. Tokens may be any alphanumeric character delimited by a white space character. Each new delimited level of keywords is indented to make files easier to read and edit with a plain text editor. Comments are supported as separate lines indented at the same level as the current keyword delimiter and begin with the # character. In line comments are not allowed. There is more information on s-expression support in the Kicad source tree in file Documentation/s-expressions.txt.

Using this document
This document is nothing more than several well commented part files. You should always be able to copy the text from the opening delimiter “(“ to the closing delimeter “)” into a file and open it with the library part file editor or library part viewer in Kicad's schematic capture program EESchema. It may not actually draw a useful component or be a very useful part but it should always be syntactically correct. The comments for a specific keyword always appears above the keyword it describes. Keywords defined within brackets [] are optional. A simple syntax coloring scheme has been employed to make this document more readable. Keywords are highlighted in blue, comments are highlighted in turquoise, and strings are highlighted in red.

Logical coordinates.
The SWEET grammar expresses schematic parts using a coordinate system without units of measure. That is, logical coordinates used are dimensionless. The advantage of having coordinates without units is any item that has an integer (non-fractional) coordinate in x and y, will be “on grid”. This helps ensure all connectable items such as pins, wires, junctions, etc., can be easily connected using normal grid snap. The normal spacing between neighboring part pins is 1 logical unit, and it is dimensionless. In fact, this is the definition of what a logical unit is, the normal spacing between two neighboring pins. Only non-connectable objects (e.g. arcs, text, etc.) should have non-integer coordinates. The zoom factor at time of printing or plotting determines the physical size of any drawing output.

Line Widths
Line widths are given as a percent of a logical unit. In other words, a line width of 1 means 1/100th of a logical unit. Recall that a logical unit of 1 is the normal spacing between two neighboring schematic pins. So a line width of 50 would mean 50/100 of a pin interval, or half the normal space between two pins. A line width of 50 represents a very wide line indeed, a more normal line width would be about 1-5 (percent).

An example file showing syntax for all drawable item types.
# The schematic part element is the largest entity addressed by the SWEET grammar.
# A schematic part can inherited from another part by using the “extends” keyword.
# The part name is normally the file name, although SWEET parts will not always
# exist as mere files. They are actually best thought of as strings held in a
# a container called a lib_source. The NAME_HINT is to be used in a manner yet to
# be determined, depending on the context from which the SWEET part came from.
(part NAME_HINT[ extends LPID]
# Change the anchor position to something other than 0, 0. Anchor coordinates
# must be integers.
[(anchor (at X Y))]
# The reference token is a reserved property. Other reserved properties are
# value, footprint, datasheet, model, and keywords.
[(reference REF
# Effects define how a property is displayed. If no effect is defined then
# the property is not displayed. Effects can also be used to override the
# effects of a property in an inherited part. When (effects...) is used
# in a COMPONENT to override the effects of a PART, the PROPERTY
# specifier must be present.
[(effects [PROPERTY]
# Position requires an X and Y coordinates. Position coordinates can be
# non-intergr. Angle is in degrees and defaults to 0 if not defined.
(at X Y [ANGLE])
# The FONT value needs to be defined. Currently, EESchema does not support
# different fonts. In the future this feature may be implemented and at
# that time FONT will have to be defined. Initially, only the font size &
# style are required. Italic and bold styles are optional. The font size
# height and width are in units yet to be determined. Only a variance
# from defaults needs to be stated.
[(font [FONT] (size HEIGHT WIDTH) [italic] [bold])]
# Default visiblity for fields is no, only a variance from the
# the default needs to be stated.
[(visible yes)]
)]
)]
# Add a new user definable property to this part. Also can be use to override
# a property defined in extended part.
[(property NAME VALUE
[( effects
( at X Y [ANGLE])
( font [FONT] (size HEIGHT WIDTH) [italic] [bold])
# Default visiblity for fields is no, only a variance from the
# the default needs to be stated.
[(visible yes)]
)]
)]
# Either polyline or line are can be used to define a line or series of lines.
# Coordinates can be non-integer.
(polyline or
(line
(pts (xy X Y)(xy X Y)(xy X Y)(xy X Y)(xy X Y))
# Line widths are in units as defined above.
[(stroke [WIDTH] [(style [(dashed...)]...)])]
# Valid fill types are none, filled, and transparent. Default fill for
# a poly_line is none. Only a variance from the default needs to be stated.
[(fill FILL_TYPE)]
)
(rectangle ( start X Y) (end X Y) (stroke WIDTH) (fill FILL_TYPE))
(circle
(center X Y)
# Radius length is in units if defined or mils.
(radius LENGTH)
(stroke WIDTH)
(fill FILL_TYPE)
)
(arc ( pos X Y) ( radius RADIUS) ( start X Y) (end X Y)
( stroke WIDTH)
(fill FILL_TYPE)
)
(bezier
(pts ( xy X Y) (xy X Y) (xy X Y) (xy X Y) (xy X Y) (xy X Y))
(stroke WIDTH)
(fill FILL_TYPE)
)
(text “This is the text that gets drawn.”
( at X Y [ANGLE])
# Valid horizontal justification values are center, right, and left. Valid
# vertical justification values are center, top, bottom. Defaults are
# left and bottom. Only need to state a non-default.
[(justify [HORIZONTAL_JUSTIFY] [VERTICAL_JUSTIFY])]
[(font [FONT] (size HEIGHT WIDTH) [italic] [bold])]
# default visibility is yes, only need to state a non-default
[(visible no)]
# default fill type for text is filled, only need to state a non-default
[(fill FILL_TYPE)]
)
# A pin's type is it's electrical connection. Valid connection types are
# input, output, bidirectional, tristate, passive, unspecified, power_in,
# power_out, open_collector, open_emitter, unconnected. Valid pin shape
# values are none, line, inverted, clock, inverted_clk, input_low, clock_low,
# falling_edge, and non_logic.
(pin TYPE SHAPE
# Pin coordinates must be integers. The angle values 0, 180, 90, and 270
# replace the current right, left, up, and down specifiers respectively,
# and are the only angles currently supported.
(at X Y [ANGLE])
# Length of the pin in logical units. This is optional, depending on
# SHAPE, which in some cases may imply a fixed length
[(length LENGTH)]
# Use signal to describe the purpose of the pin. Signals do not have to be
# uniquely named within a part. Signal can be blank.
[ ( signal “NAME” ( font [FONT] (size HEIGHT WIDTH) [italic][bold])
(visible YES))]
# Use pad to uniquely identify the pin, according to the pin number
# in the datasheet for the part. Padnames may not be blank and must be
# be unique within the part.
(pad “NUMBER” ( font [FONT] (size HEIGHT WIDTH) [italic][bold])
(visible YES))
# default visibility for pins is yes, so only a deviation from the
# the default needs to be stated.
[(visible no)]
)
# Pin merge is used to group a number of pins that are connected to the same
# net externally and show only one pin symbolizing the group. The group is
# called a merge set or merge group. It is typically used to hide all but
# one power pin on parts that have a large number of power connections
# such as FPGAs and micro-contollers. VISIBLE_PAD is the pad of
# the one pin which remains visible within the merge set. Pins with pads
# listed within the (pads...) element are all made invisible, and so
# are are all pins which may have any of the signal names listed in the
# (signals...) element. A pin may only exist within one merge group.
# Any number of (pin_merge...) statements maybe made, including more than
# one re-stating the same VISIBLE_PAD, which is the anchor pin for the
# merge set.
[(pin_merge VISIBLE_PAD
[(pads HIDDEN_PAD1 …)][(signals HIDDEN_SIGNAL1 …)])]
# The pin swap hinting flag is used to indicate to an external tool ( i.e. an
# auto router ) that the pins defined are functionally equivalent and
# interchangeable.
[(hint_pin_swap NUMBER1 NUMBER2 ...)]
)

Inheritance syntax example file.
(part NAME_HINT extends LPID
# Remove pin PAD defined in the base part. Only valid for extended parts.
[(pin_del PAD)]
# Swap pin PAD1 and pin PAD2 in the base part.
# Only valid for extended parts.
[(pin_swap PAD1 PAD2)]
# Change the pad of pin OLDPAD to NEWPAD in the base part.
# Only valid for extended parts.
[(pin_renum OLDPAD NEWPAD)]
# Change the signal of pin PAD to NEWSIGNAL in the base part.
# Only valid for extended parts.
[(pin_rename PAD NEWSIGNAL)]
# Remove property NAME from the base part. Only valid for extended parts.
[(property_del NAME)]
# Alternates are used to define multiple part per package devices and/or
# alternate body styles (DeMorgan). Parts must be defined in order. There
# can more than one alternates defined.
[(alternates LPID [LPID...])]
# Add a new property to this part. Also can be use to override a property
# defined in the base part.
[(property NAME VALUE
[( effects ( at X Y [ANGLE])
( font [FONT] (size HEIGHT WIDTH) [italic] [bold])
(visible YES)]
)]
# The alternates swap hinting flag is used to indicate to an external tool
# that the parts defined in the alternates list are functionally equivalent
# and interchangeable.
[(hint_alt_swap LPID1 LPID2 ...)]
)
# This is an example of a dual input NAND gate A of a 7400.
(part “dual_input_nand_a”
(reference “U”)
(arc (pos 2 0) ( radius 0.4) ( start 2 -4) (start_angle -90) (end 2 4)
(end_angle 90) ( stroke 0) (fill none))
(polyline (xy 2 4) (xy -6 4) (xy -6 -4) (xy 2 -4)
(stroke 0) (fill none))
(pin input line (at -12 2 3.6 180)
(signal “” ( font (size 1.2 1.2)) (visible yes))
(pad “1” ( font (size 1.2 1.2)) (visible yes))
(visible yes))
(pin input line (at -12 -2 3.6)
(signal “” ( font (size 1.2 1.2)) (visible yes))
(pad “2” ( font (size 1.2 1.2)) (visible yes))
(visible yes))
(pin output line (at -12 0)
(signal “” ( font (size 1.2 1.2)) (visible yes))
(pad “3” ( font (size 1.2 1.2)) (visible yes))
(visible yes))
(pin power_in none (at -4 -4 90)
(signal “GND” ( font (size 1.2 1.2)) (visible no))
(pad “7” ( font (size 1.2 1.2)) (visible no))
(visible no))
(pin power_in none (at -4 4 90)
(signal “VCC” ( font (size 1.2 1.2)) (visible no))
(pad “7” ( font (size 1.2 1.2)) (visible no))
(visible no))
(hint_pin_swap “1” “2”)
)
# All LPIDs below this point assume that the base part is located in the same
# library as the parts that are derived from them. See the “Distributed Library
# & EESchema Parts List Design Documentation” in the Kicad source file “design.h”
# for more information on LPIDs.
# This is the B gate of a 7400.
(part “dual_input_nand_b” inherits “dual_in_nand_a/rev1”
(pin_del 7)
(pin_del 14)
(pin_renum 1 4)
(pin_renum 2 5)
(pin_renum 3 6)
)
# This is the C gate of a 7400.
(part “dual_input_nand_c” inherits “dual_in_nand_a/rev1”
(pin_del 7)
(pin_del 14)
(pin_renum 8 4)
(pin_renum 9 5)
(pin_renum 10 6)
)
# This is the D gate of a 7400.
(part “dual_input_nand_b” inherits “dual_in_nand_a/rev1”
(pin_del 7)
(pin_del 14)
(pin_renum 1 11)
(pin_renum 2 12)
(pin_renum 3 13)
)
# This is a DeMorgan representation of a dual input NAND gate A.
(part “dual_input_nand_ demorgan _a”
(reference “U”)
(arc (pos -9.3 0) ( radius 0.518) ( start -6 4) (start_angle 50.4)
(end -6 -4) (end_angle -50.4) ( stroke 0) (fill none))
(arc (pos -0.22 2.86) ( radius 7.06) ( start 0 -200) (start_angle -88.1)
(end 6 0) (end_angle -24.6) ( stroke 0) (fill none))
(arc (pos -0.2 2.82) ( radius 6.8) ( start 6 0) (start_angle -24.4) (end 0 4)
(end_angle 88.3) ( stroke 0) (fill none))
(polyline (xy -6 4) (xy 0 4) (xy 0 -4) (xy -6 -4)
(stroke 0) (fill none))
(pin input line (at -12 2 180) (length 6)
(signal “” ( font (size 1.2 1.2)) (visible yes))
(pad “1” ( font (size 1.2 1.2)) (visible yes))
(visible yes))
(pin input line (at -12 -2 180) (length 6)
(signal “” ( font (size 1.2 1.2)) (visible yes))
(pad “2” ( font (size 1.2 1.2)) (visible yes))
(visible yes))
(pin output line (at -12 0) (length 7.4)
(signal “” ( font (size 1.2 1.2)) (visible yes))
(pad “3” ( font (size 1.2 1.2)) (visible yes))
(visible yes))
(pin power_in none (at -4 -4 90) (length 0)
(signal “GND” ( font (size 1.2 1.2)) (visible no))
(pad “7” ( font (size 1.2 1.2)) (visible no))
(visible no))
(pin power_in none (at -4 4 90) (length 0)
(signal “VCC” ( font (size 1.2 1.2)) (visible no))
(pad “7” ( font (size 1.2 1.2)) (visible no))
(visible no))
(hint_pin_swap 1 2)
)
# This is the DeMorgan representation of gate B of a 7400.
(part “dual_input_nand_demorgan_b”
inherits “dual_in_nand_demorgan_a/rev1”
(pin_del 7)
(pin_del 14)
(pin_renum 1 4)
(pin_renum 2 5)
(pin_renum 3 6)
(pin_rename 1 “D”)
(pin_rename 2 “E”)
(pin_rename 3 “F”)
)
# This is the DeMorgan representation of gate C of a 7400.
(part “dual_input_nand_demorgan_c”
inherits “dual_in_nand_demorgan_a/rev1”
(pin_del 7)
(pin_del 14)
(pin_renum 1 8)
(pin_renum 2 9)
(pin_renum 3 10)
)
# This is the DeMorgan representation of gate D of a 7400.
(part “dual_input_nand_demorgan_d”
inherits “dual_in_nand_demorgan_a/rev1”
(pin_del 7)
(pin_del 14)
(pin_renum 1 11)
(pin_renum 2 12)
(pin_renum 3 13)
)
# An example of putting it all together to create a 7400.
(part “7400”
(value “7400”)
(alternates
“dual_in_nand_a/rev1”
“dual_in_nand_b/rev1”
“dual_in_nand_c/rev1”
“dual_in_nand_d/rev1”
)
(alternates
“dual_in_nand_demorgan_a/rev1”
“dual_in_nand_demorgan_b/rev1”
“dual_in_nand_demorgan_c/rev1”
“dual_in_nand_demorgan_d/rev1”
)
(hint_alt_swap
“dual_in_nand_a/rev1”
“dual_in_nand_b/rev1”
“dual_in_nand_c/rev1”
“dual_in_nand_d/rev1”
)
)
# A 74LS00 is as simple as this.
(part “74LS00” inherits “7400/rev1” ( value “74LS00” ))
# This is a so called heavy weight part definition of a Texas Instruments
# part number SN74HCT00NSR.
(part “SN74HCT00NSR” inherits “7400/rev1”
( value “SN74HCT00NSR” )
( footprint “14-SOP” )
( datasheet “http://focus.ti.com/general/docs/lit/getliterature.tsp?genericPartNumber=sn74hct00&fileType=pdf” )
( keywords “LOGIC” “NAND” )
( property “Description” “IC GATE POS-NAND QD 2IN 14-SOP” )
( property “Manufacturer” “Texas Instruments” )
( property “Vendor” “Digikey” )
( property “Vendor Part Number” “SN74HCT00NSR-ND” )
)