# Ifc Syntax Step Physical File

> Use when reading, writing, or debugging the .ifc STEP Physical File: the ISO-10303-21 skeleton, the HEADER section (FILE_DESCRIPTION, FILE_NAME, FILE_SCHEMA), the DATA section instance syntax, the special tokens, value notation, string escaping, or the ifcZIP container. Prevents emitting attributes out of declared order, serializing inverse or derived attributes, confusing the unset token with the derived token, writing raw non-ASCII bytes into a string, and putting more than one model file in an ifcZIP. Covers the file skeleton, the three header entities and the ViewDefinition convention, hash-id instance syntax, forward and backward references, dollar and asterisk tokens, enum and boolean dot notation, typed-value wrapping, aggregates, the control directives, and PKZip 2.04g ifcZIP packaging. Keywords: STEP physical file, SPF, .ifc, ISO 10303-21, Part 21, ISO-10303-21, HEADER, DATA, ENDSEC, FILE_DESCRIPTION, FILE_NAME, FILE_SCHEMA, ViewDefinition, positional attributes, dollar sign, asterisk, forward refere

- Skill: `impertio-studio/ifc-syntax-step-physical-file` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add impertio-studio/ifc-syntax-step-physical-file`
- Raw SKILL.md: https://api.skillmd.com/api/skills/impertio-studio/ifc-syntax-step-physical-file/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: Impertio-Studio (https://skillmd.com/u/impertio-studio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/impertio-studio/ifc-syntax-step-physical-file

---


# IFC STEP Physical File Syntax

The `.ifc` file is a STEP Physical File (SPF, also called Part 21 or p21),
governed by ISO 10303-21. It is a clear-text encoding in which each entity
instance is a line and attribute values are an ordered sequence of unnamed
values. This skill covers the file skeleton, the HEADER section, the DATA
section instance syntax, value notation, string escaping, and the ifcZIP
container.

Verified against the buildingSMART IFC formats documentation, the IFC
Header Data Implementation Guide v1.0.2, the ifcZIP implementation
agreement CV-2x3-154, and ISO 10303-21. Applies to IFC2x3, IFC4, IFC4.3:
the SPF syntax is identical across all three; only the `FILE_SCHEMA`
identifier and the entity set differ.

## Quick Reference

### The file skeleton

A `.ifc` file ALWAYS has exactly this frame:

```
ISO-10303-21;
HEADER;
  ...three header entities...
ENDSEC;
DATA;
  ...entity instances...
ENDSEC;
END-ISO-10303-21;
```

The file ALWAYS begins with `ISO-10303-21;` and ends with
`END-ISO-10303-21;`. Each section ALWAYS closes with `ENDSEC;`. IFC files
use only the `HEADER` and `DATA` sections. NEVER emit the optional Part 21
`ANCHOR` or `REFERENCE` sections: IFC tooling does not expect them.

### The three header entities

The `HEADER` section ALWAYS contains exactly three entities, in this fixed
order: `FILE_DESCRIPTION`, `FILE_NAME`, `FILE_SCHEMA`.

| Entity | Carries |
|--------|---------|
| `FILE_DESCRIPTION` | A description list (used for the ViewDefinition) and `implementation_level` |
| `FILE_NAME` | Name, timestamp, author, organization, preprocessor, originating system, authorization |
| `FILE_SCHEMA` | The schema identifier list: `IFC2X3`, `IFC4`, or `IFC4X3` |

A reader ALWAYS dispatches its parser by the `FILE_SCHEMA` value. Full
signatures are in `references/methods.md`.

### The data instance syntax

Each DATA-section line is one entity instance:

```
#<id>=ENTITYNAME(attr1,attr2,...);
```

| Element | Rule |
|---------|------|
| `#<id>` | `#` plus a positive integer. Unique within the file. Numbering need not be contiguous and carries NO meaning. |
| `ENTITYNAME` | The entity keyword in UPPER CASE (`IFCWALL`, `IFCPROJECT`). |
| `(...)` | Attributes in EXPRESS declared order, including all inherited explicit attributes. |
| `;` | Every instance line ends with a semicolon. |

ALWAYS serialize explicit attributes only. NEVER serialize INVERSE or
DERIVED attributes: they are omitted from the positional sequence.

### The special tokens

| Token | Meaning |
|-------|---------|
| `$` | An unset OPTIONAL attribute. The slot exists; there is no value. |
| `*` | A slot whose value is derived in this entity but was explicit in a supertype. The slot is held by `*`; the value is computed, not stored. |
| `#id` | A reference to another instance. May point forward (later in the file) or backward. |

### Value notation cheat sheet

| Value kind | Written as | Example |
|------------|-----------|---------|
| String | Single-quoted | `'Wall-001'` |
| Embedded apostrophe | Doubled | `'don''t'` |
| Real / integer | Plain; reals carry a dot | `3.14`, `0.`, `255` |
| Enumeration | Dot-delimited, upper case | `.SOLIDWALL.` |
| Boolean | `.T.` or `.F.` | `.T.` |
| Logical | `.T.`, `.F.`, or `.U.` | `.U.` |
| Typed (select / measure) value | Type keyword wrapping the value | `IFCBOOLEAN(.T.)`, `IFCINTEGER(255)` |
| Aggregate (LIST, SET, BAG, ARRAY) | Comma-separated in parentheses | `(#84,#85,#86)`, `(0.,0.,0.)` |
| Reference | `#id` token | `#5` |
| Unset optional | `$` | `$` |

## Decision Trees

### Which token does this attribute slot get?

```
The attribute in this positional slot is...
|
+- An explicit attribute with a value
|    -> write the value (string, number, enum, #id, aggregate, ...).
|
+- An explicit OPTIONAL attribute with no value
|    -> write $ . The slot stays; no value is given.
|
+- Explicit in a supertype but re-declared DERIVE in this entity
|    -> write * . The slot is held; the value is computed.
|
+- Declared DERIVE or INVERSE in this entity itself
     -> the slot does NOT exist. Omit it entirely. NEVER write $ or *.
```

NEVER confuse `$` with `*`. `$` means "optional, not set". `*` means
"this slot's value is derived". Using `$` for a derived re-declared slot,
or `*` for a plain unset optional, produces an attribute the importer
reads with the wrong semantics.

### Is this attribute serialized at all?

```
What kind of attribute is it (from the EXPRESS schema)?
|
+- Explicit (declared directly or inherited as explicit)
|    -> YES, it occupies a positional slot. Always present.
|
+- Re-declared from explicit to DERIVE in this entity
|    -> YES, the slot is present, held by * .
|
+- DERIVE declared in this entity
|    -> NO. Omitted. The value is computed by the reader.
|
+- INVERSE
     -> NO. Omitted. The reader rebuilds it by scanning references.
```

The positional attribute count of an instance ALWAYS equals the number of
explicit attributes (direct plus inherited) of that entity. A mismatch is
the most common parse failure. See `references/anti-patterns.md`.

### Raw character or escape directive?

```
The string contains a character that is...
|
+- Printable ASCII (U+0020 to U+007E), except the apostrophe
|    -> write it directly.
|
+- An apostrophe
|    -> double it: ' becomes '' .
|
+- A backslash
|    -> double it: \ becomes \\ .
|
+- Non-ASCII (accented letter, symbol, CJK, emoji)
     -> encode with a control directive: \X\, \X2\..\X0\, or \X4\..\X0\.
        NEVER write the raw byte. See the escaping pattern below.
```

## Patterns

Verified snippets. Full notation detail is in `references/methods.md`;
complete files are in `references/examples.md`.

### Pattern: write the HEADER section

```step
HEADER;
  FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');
  FILE_NAME(
    'project.ifc',
    '2026-05-20T11:35:07',
    ('A. Author'),
    ('Example Organization'),
    'IfcOpenShell 0.8',
    'ExampleApp 1.0',
    'A. Author');
  FILE_SCHEMA(('IFC4'));
ENDSEC;
```

`FILE_DESCRIPTION` carries the Model View Definition in its description
list. The agreed convention is a `ViewDefinition [Name]` keyword string.
`implementation_level` is ALWAYS `'2;1'` for IFC files. `FILE_NAME` fields
that are unknown ALWAYS take `''` or `$`, NEVER an invented value. Each
header string is limited to 256 characters.

### Pattern: write a DATA instance in declared order

The positional order is the EXPRESS declared order, inherited attributes
first. For `IfcWall` (IFC4, IFC4.3) the 9 explicit attributes are:

```step
#21=IFCWALL(
  '3t3TDZl_D9NOIWB0BSjzJI',  /* 1 GlobalId       IfcRoot    */
  #5,                        /* 2 OwnerHistory   IfcRoot    */
  'Wall-001',                /* 3 Name           IfcRoot    */
  $,                         /* 4 Description    IfcRoot    */
  $,                         /* 5 ObjectType     IfcObject  */
  #18,                       /* 6 ObjectPlacement IfcProduct */
  #19,                       /* 7 Representation  IfcProduct */
  'A-101',                   /* 8 Tag            IfcElement */
  .SOLIDWALL.                /* 9 PredefinedType IfcWall    */
);
```

In a real file the instance is written on one line. ALWAYS emit every
explicit slot. See `ifc-syntax-building-elements` for per-entity layouts.

### Pattern: forward and backward references

A `#id` reference may point to an instance defined later in the file:

```step
#21=IFCWALL('3t3TDZl_D9NOIWB0BSjzJI',#5,'Wall-001',$,$,#18,#19,'A-101',.SOLIDWALL.);
#5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,$,$,$,1700000000);
```

Here `#21` references `#5` before `#5` is defined. This is legal. A
conformant reader ALWAYS does a two-pass parse: index every `#id` first,
then resolve references. NEVER assume an instance is defined before its
first use.

### Pattern: aggregates and typed values

An aggregate is comma-separated values in parentheses. `IfcCartesianPoint`
has exactly ONE explicit attribute, a coordinate list, so the instance
holds a list nested inside the attribute parentheses:

```step
#100=IFCCARTESIANPOINT((0.,0.,0.));
```

A typed value wraps the value in its type keyword. Used for `SELECT` and
measure types where the reader must know the concrete type:

```step
#46=IFCPROPERTYSINGLEVALUE('LoadBearing',$,IFCBOOLEAN(.T.),$);
```

NEVER write a bare `.T.` where a typed value is required: the select type
needs `IFCBOOLEAN(.T.)` so the reader resolves the right member.

### Pattern: escape non-ASCII characters

IFC follows the ISO 10303-21:2002 string model: non-ASCII characters use
control directives, NOT raw bytes.

```step
/* the section sign U+00A7 */        'see \X\A7 4.1'
/* the Greek letter pi U+03C0 */     '\X2\03C0\X0'
/* an emoji U+1F600 */               '\X4\0001F600\X0'
```

`\X\` takes two hex digits (U+0000 to U+00FF). `\X2\` takes groups of four
hex digits and is closed by `\X0\`. `\X4\` takes groups of eight hex
digits and is closed by `\X0\`. ALWAYS encode non-ASCII this way for
interoperability across IFC2x3, IFC4, and IFC4.3. NEVER write a raw UTF-8
octet into an SPF string: the IFC4.3 documentation references ISO
10303-21:2002, whose string model is the control-directive model.

### Pattern: package an ifcZIP

ifcZIP is a plain ZIP archive holding exactly one model file:

- The archive ALWAYS uses PKZip 2.04g (DEFLATE) compression. NO encryption,
  NO deflate64, NO ZIP unicode extensions.
- The archive ALWAYS contains exactly ONE `.ifc` file OR exactly ONE
  ifcXML file in its main directory. NEVER more than one model file.
- The extension is `.ifcZIP`; the MIME type is `application/zip`.

NEVER place two `.ifc` files in one ifcZIP: a conformant reader expects
exactly one and the result is ambiguous.

## Anti-Patterns

Full detail with the failure mechanism is in `references/anti-patterns.md`.
The five that matter most:

- Wrong attribute count: omitting an explicit slot or adding an extra one.
  The whole instance fails to parse.
- Serializing an INVERSE or DERIVED attribute as a positional value.
  Shifts every following attribute by one slot.
- Using `$` for a derived re-declared slot, or `*` for a plain optional.
  The reader applies the wrong semantics.
- Writing a raw non-ASCII byte into a string instead of a control
  directive. Produces garbled text or a decode failure.
- Putting more than one model file in an ifcZIP. The reader cannot decide
  which file is the model.

## Reference Links

### This skill

- `references/methods.md`: the file skeleton, the three header entity
  signatures, the special tokens, the value-notation table, the control
  directives, and the ifcZIP rules.
- `references/examples.md`: complete minimal valid `.ifc` files and
  verified syntax fragments.
- `references/anti-patterns.md`: parse-failure modes and their causes.

### Related skills

- `ifc-syntax-express`: the EXPRESS schema language whose declared order
  this file's positional attributes follow.
- `ifc-syntax-ifcxml`: the XML encoding governed by ISO 10303-28.
- `ifc-syntax-data-types`: the IFC measure and defined types written as
  typed values here.
- `ifc-errors-encoding-issues`: diagnosing and repairing broken string
  escaping and character-encoding faults.

### Official sources

- IFC file formats: https://technical.buildingsmart.org/standards/ifc/ifc-formats/
- IFC Header Data Implementation Guide v1.0.2: https://standards.buildingsmart.org/documents/Implementation/ImplementationGuide_IFCHeaderData_Version_1.0.2.pdf
- ifcZIP agreement CV-2x3-154: https://standards.buildingsmart.org/documents/Implementation/IFC_Implementation_Agreements/CV-2x3-154.html
- ISO 10303-21 edition 3 reference: https://www.steptools.com/stds/step/IS_final_p21e3.html

