Skip to content

Parser API

Parse and validate the Boukamp DSL (11 element codes, optional {…} / […] parameters).

Supported element codes

Longest-match order: Pdw, Ws, Wo, CC, HN, then R, C, L, Q, W, G.

CodeKind
RResistor
CCapacitor
LInductor
QCPE
WWarburg (infinite)
WsWarburg (short)
WoWarburg (open)
GGerischer
PdwParallel Diffusion Warburg
CCCole-Cole
HNHavriliak-Negami

Unknown codes produce a lex error. After parsing, validate() checks duplicate IDs, embedded parameter counts, value ranges (CC/HN exponents, CPE n, etc.), DC resistive path, and conflicting reactive branches.

parseBoukamp

ts
import { parseBoukamp } from 'velo-circuit'

const result = parseBoukamp('R0-p(R1,C1)')

if ('type' in result && result.type === 'lex') {
  console.error(result.position, result.message)
} else if ('type' in result && result.type === 'parse') {
  console.error(result.expected, result.found)
} else {
  const ast = result
}

Embedded parameters:

ts
parseBoukamp('Q1{5e-5,0.8}')
parseBoukamp('CC1[50,1e-3,0.8]')  // bracket alias

tokenize

ts
import { tokenize } from 'velo-circuit'

const tokens = tokenize('R0-p(R1,C1)')

serialize

ts
import { serialize } from 'velo-circuit'

const dsl = serialize(ast)
// → 'R0-p(R1,C1)-Wo2'

validate

ts
import { validate } from 'velo-circuit'

const result = validate(ast)
// → { issues: [...], hasErrors: false, hasWarnings: false }

Use validateParameterValues(ast, params) when a flat parameter vector is supplied separately from the DSL.

Validate modes

ts
validate(ast, { strict: true, mode: 'editor' })  // lighter checks while typing
validate(ast, { strict: true, mode: 'full' })   // full topology / DC path checks

createAdapter

Stateful parser with configurable strictness:

ts
import { createAdapter, type StrictOptions } from 'velo-circuit'

const adapter = createAdapter({
  strict: true,
  blockInvalidSetValue: true,
  validateParamsOnEdit: true,
})

const out = adapter.parse('R0-C1')
adapter.validate(ast)

resolveCircuitParams

ts
import { resolveCircuitParams, formatMissingParams } from 'velo-circuit'

const { values, missing } = resolveCircuitParams(ast, paramVector)
if (missing.length) console.warn(formatMissingParams(missing))

ElementRegistry

ts
import { ElementRegistry, assignParamOffsets, parameterCount } from 'velo-circuit'

const registry = ElementRegistry.fromCircuit(ast)
const names = registry.paramNames()

Error Types

ts
interface LexError {
  type: 'lex'
  position: number
  found: string
  message: string
}

interface ParseError {
  type: 'parse'
  position: number
  expected: string
  found: string
  message: string
}

Round-Trip

ts
const dsl = 'R0-p(R1,C1)-Wo2'
const ast = parseBoukamp(dsl)
const output = serialize(ast)
assert(output === dsl) // true for valid input without embedded params reordering