cdl-parser
Parse and validate Crystal Description Language (CDL) expressions. Zero external dependencies.
pip install cdl-parser Functions
parse_cdl(expression: str) → CrystalDescription Parse a CDL expression string into a structured CrystalDescription object.
from cdl_parser import parse_cdl
desc = parse_cdl("cubic[m3m]:{111}@1.0 + {100}@1.3")
print(desc.system) # CrystalSystem.CUBIC
print(desc.point_group) # "m3m"
print(desc.forms) # [Form({111}, 1.0), Form({100}, 1.3)] Parameters:
expression- CDL expression string
Returns: CrystalDescription object
Raises: CDLParseError if the expression is invalid
validate_cdl(expression: str) → ValidationResult Validate a CDL expression without fully parsing it. Returns detailed error information.
from cdl_parser import validate_cdl
result = validate_cdl("cubic[m3m]:{111}")
print(result.is_valid) # True
result = validate_cdl("invalid[xyz]:{abc}")
print(result.is_valid) # False
print(result.errors) # [ValidationError(...)] tokenize(expression: str) → list[Token] Tokenize a CDL expression into a list of tokens. Useful for syntax highlighting.
from cdl_parser import tokenize
tokens = tokenize("cubic[m3m]:{111}")
for token in tokens:
print(f"{token.type}: {token.value}")
# SYSTEM: cubic
# LBRACKET: [
# POINT_GROUP: m3m
# ... Classes
CrystalDescription
Represents a parsed CDL expression.
| Attribute | Type | Description |
|---|---|---|
system | CrystalSystem | Crystal system enum |
point_group | str | Point group symbol |
forms | list[Form] | List of crystal forms |
twin_law | str | None | Optional twin law name |
modifiers | dict[str, Any] | Optional modifiers (elongate, etc.) |
Form
Represents a single crystal form (set of Miller indices with distance).
| Attribute | Type | Description |
|---|---|---|
miller_indices | MillerIndex | Miller indices for this form |
distance | float | Distance from origin (default 1.0) |
MillerIndex
Represents Miller indices (hkl or hkil for hexagonal/trigonal).
from cdl_parser import MillerIndex
# 3-index notation
mi = MillerIndex(1, 1, 1)
print(mi) # {111}
# 4-index notation (Miller-Bravais)
mi = MillerIndex(1, 0, -1, 0)
print(mi) # {10-10}
# Convert between notations
mi_3 = mi.to_3index()
mi_4 = mi.to_4index() CrystalSystem
Enum of the seven crystal systems.
from cdl_parser import CrystalSystem
CrystalSystem.CUBIC
CrystalSystem.HEXAGONAL
CrystalSystem.TRIGONAL
CrystalSystem.TETRAGONAL
CrystalSystem.ORTHORHOMBIC
CrystalSystem.MONOCLINIC
CrystalSystem.TRICLINIC Exceptions
CDLParseError
Raised when parsing fails. Contains detailed error information.
from cdl_parser import parse_cdl, CDLParseError
try:
parse_cdl("invalid")
except CDLParseError as e:
print(e.message) # Error message
print(e.line) # Line number (1-based)
print(e.column) # Column number (1-based)
print(e.context) # Surrounding text Constants
POINT_GROUPS
Dictionary mapping crystal systems to valid point groups.
from cdl_parser import POINT_GROUPS
print(POINT_GROUPS[CrystalSystem.CUBIC])
# ['m3m', '432', '-43m', 'm3', '23']