Namespace Hi.NcParsers.ParsingSyntaxs.Heidenhain
Classes
- HeidenhainApprDepSyntax
Heidenhain klartext contour approach and departure statements, the Cartesian forms:
APPR LT/APPR LN/APPR CT/APPR LCTandDEP LT/DEP LN/DEP CT/DEP LCT(Klartext Programming User's Manual, “Approaching and departing a contour”; the syntax elements of each form in the TNC7 manual §9.6). The statement head is consumed and the block is recorded as a nestedParsing.APPRorParsing.DEPrecord —{ “Form”: “LT” | “LN” | “CT” | “LCT” }plus every parameter word of the family the line carries,LEN,CCAandR(the form takes its own:LENon LT / LN,CCAandRon CT,Ron LCT, WordsOf(string)) — for the PostLogic-stage HeidenhainApproachDepartureSyntax, which computes the auxiliary point PH and writes the motion. A parameter word a form does not take (anRon an LT, aCCAon an LN) lands in the record all the same, for that stage to report (HeidenhainApprDep–WordNotTaken) and drop: left on the line, the shared capture would read it and the DIN/ISO arc twin would take a strayRafter a klartext arc as an arc of its own, with no message at all. The DIN/ISO arc wordsI/J/K, which no form takes, are kept in the record for the same reason. A word written more than once lands in the record'sRepeatedWords(RepeatedWordsKey), which that stage reports (HeidenhainApprDep–WordRepeated, the first occurrence used) before the record is dropped; the words are read case-insensitively and taken as the word they spell (alen15is the LEN 15; a second spelling of a word already read is a repeat of it). A parameter word's value may stand apart from the word (CCA 180, as the iTNC 530 manual prints its DEP CT example), as an F value may on this brand.The approach block's coordinates are the first contour point PA, so they land on the root of Parsing exactly like an
Lendpoint (the shared Logic consumers resolve them into the block's nominalProgramXyz, which is the first contour point the compensated path then offsets), its rotary and parallel words with them; the radius compensation wordsRL/RR/R0are captured like on HeidenhainLSyntax — the manual programs the compensation of the whole contour on the APPR block; the record lists the axis letters the block states (Axes), which the PostLogic stage reads to tell a plane-normal coordinate the block leaves unstated — kept at the level an M140 retract on the block lifted the tool to — from a stated one. A departure block's principal-axis words stay inside theParsing.DEPrecord: on aDEP LCTthe coordinates are the end point PN, which the tool reaches only after the tangential arc, and on a DEP LT / LN / CT, whose forms take none, a coordinate is reported by the PostLogic stage and dropped — none may reach the root, where the shared capture that follows this owner in the bundle would read it as the block's own endpoint (a motion of the block, and the corner partner of the contour's last element). The rotary and parallel words of aDEP LCTare coordinates of PN too (the TNC7 syntax of the form lists A, B, C, U, V and W with X, Y and Z) and go to the root like an approach's; on the other departure forms they stay in the record with the rest, reported and dropped. ADEPblock always writesR0as well, because "the DEP blocks automatically discard the tool radius compensation" — the cancel reaches the compensation pass through the sameR0word a programmer writes; a loneR0spelled on a DEP LT / LN is absorbed as that word, on a DEP CT / LCT it is the radius 0 (no DEP form has a compensation word), and anRL/RRon a DEP block, which no form takes, stays unread.Incremental words (
APPR LT X+20 IY+20 …,DEP LCT IX-20 …) land under the plain axis keys of their section — the Parsing root for an approach,Parsing.DEPfor a departure's end point — with the block-rootPositioningOverridestamp, through HeidenhainIncrementalAxisWordUtil; the brand's IncrementalResolveSyntax instance walks theParsing.DEPrecord as it walksParsing.CC.The polar forms (
APPR PLT/PLN/PCT/PLCT,DEP PLCT) are not claimed here: they take the polarPA/PRvocabulary of theLP/CPstatements, which has no owner yet, so the line stays unread and surfaces as residue like today. The comp wordR0is grabbed before the radius wordRand rejects a digit or a dot follower, so a radiusR0.5is never read as the compensation-off word.
- HeidenhainBlkFormSyntax
Syntax for Heidenhain BLK FORM command (workpiece blank definition).
- HeidenhainCSyntax
Heidenhain circular-motion statement (
C X+5.361 Y+23.064 DR-). Mirrors HeidenhainLSyntax: endpoint axis words promote to the Parsing root (shared Logic consumers), a“CArc”: truestatement marker (deliberately NOT the bareCkey — that is a rotary axis word which McAbcSyntax owns and consumes on rotary machines) gates HeidenhainCircularMotionSyntax, the rotation direction lands inParsing.DR("-"= CW = G02,"+"= CCW = G03) and radius-compensation words are captured like on L statements. The word-boundary head guard rejectsCC/CT/CR/CPstatements, and a value follower rejects a leading rotary-axis word — a DIN/ISO block likeC-90.(modal C-axis positioning, the same mixed-dialect list) is an axis coordinate for the root tag capture, never a klartext arc statement head (klartext always separates the C head from its X/Y/DR words, so a sign/digit/dot follower cannot be an arc statement). Incremental endpoint words (C IX+20 IY+0 DR-) are captured like on L statements — plain axis keys plus the block-rootPositioningOverridestamp, see HeidenhainIncrementalAxisWordUtil.
- HeidenhainCallSyntax
Syntax for Heidenhain CALL commands (CALL PGM and CALL LBL).
- HeidenhainCcSyntax
Heidenhain circle-center statement (
CC X+12.7 Y+12.7). The coordinates land in the nestedParsing.CCrecord — deliberately not on the Parsing root, where ProgramXyzSyntax would mistake the center for a motion endpoint. The Logic-stage HeidenhainCircleCenterSyntax turns the record into the modal circle-center section consumed by the arc syntax. Must run before HeidenhainCSyntax in the bundle (the\bguard keeps aCstatement from matchingCCand vice versa, but CC-first is the safe order).An incremental center (
CC IX+0 IY+11) is a distance from the last programmed tool position, not from the previous center: the words land in the same nested record with the block-rootPositioningOverridestamp (see HeidenhainIncrementalAxisWordUtil), and the Heidenhain IncrementalResolveSyntax instance walks theCCrecord so the center is absolute by the time the circle-center syntax freezes it.
- HeidenhainCyclCallSyntax
Captures the klartext cycle-call statement into a
Parsing[“CYCL CALL”]record:CYCL CALL—{ Bare: true }; any trailing M words stay in the text for the shared flag captures.CYCL CALL POS X±n Y±n Z±n …—{ Pos: true }plus the axis words grabbed into the record (never onto theParsingroot: the POS coordinates are the call position — the X/Y feed the ISO cycle section, while the pre-position Z must not be mistaken for the hole-bottom Z slot).FMAX/F/M140words stay in the text for their own captures. A klartext I-prefixed word (CYCL CALL POS IX+20— the general "I before an axis word" rule; the manual prints no example) lands under the plain key like anLendpoint and stamps the block-root PositioningOverride through HeidenhainIncrementalAxisWordUtil; the cycle syntax resolves it on the spot, ahead of the shared resolve.
- HeidenhainCyclDefSyntax
Initialization Syntax of Heidenhain fixed head block for
.CYCL DEFThe cycle's name on the
x.0line is optional. A post-processor that writes a bareCYCL DEF 7.0ahead of the axis lines (NX's klartext post does) yields an empty CyclHead, and the first axis line stays an axis line: the prefix strip eats blanks within the line only, never the line break, so7.1 X-30can never be read as the name and lost.
- HeidenhainFnAssignmentSyntax
Heidenhain FN variable assignment syntax. Extends TagAssignmentSyntax with FN opcode prefix.
- HeidenhainFnFeatureSyntax
Structured skip for the Heidenhain FN opcodes the simulation does not implement (
FN 14error display,FN 16print,FN 18SYSREAD, table/pallet opcodes …): the whole statement is consumed and a single warning names the opcode —HeidenhainFn–Unsupported, orHeidenhainFn–UnsupportedSysreadfor theFN 18wording. Two opcode families pass through untouched:FN 0-5belong to HeidenhainFnAssignmentSyntax (which runs earlier), and the jump familyFN 9-12belongs to HeidenhainGotoParsingSyntax (also earlier) — the pass-through here is the malformed-jump safety net: a jump line the owner's grammar rejects surfaces as visible residue instead of a fabricated skip.Claiming the statement here is load-bearing, not cosmetic: an FN 18 line like
FN18: SYSREAD Q94= ID50 NR11contains aQ94=token that the bare Q-assignment capture (later in the Parsing bundle) would otherwise grab, storing the garbage stringID50into Q94. The target parameter must instead stay vacant so dependent expressions fail soft (VariableExpression--Unevaluated) — no fabricated values.
- HeidenhainGotoParsingSyntax
Captures the Heidenhain FN 9–12 conditional jump statement whole into
Parsing.HeidenhainGoto. All four opcodes share one phrase shape (FN n: IF <value> <comparator> <value> GOTO LBL <label>); both the spaced standard spelling and the compressed post spelling (FN12:IF+Q94 LT+1GOTOLBL"SLOW_FEED"— glued opcode head, glued value/target run, quoted name label) are recognised.Pre-normalisation happens here, per the P2 expression-grammar decision (the Heidenhain dialect deliberately has no comparison layer): the comparator spelling collapses to the shared comparison words (
EQU→EQ), and the two operands are captured as separate values — a pure numeric literal is typed numeric at capture (the P0GetParsedDouble-string-trap discipline), a Q reference stays a string for VariableEvaluatorSyntax's pass-2 substitution. The comparison and the label redirect happen in HeidenhainGotoSyntax.Placement: whole-statement owner right after HeidenhainCallSyntax — before HeidenhainLblSyntax (whose definition regex already excludes the
GOTO LBLspellings, but the jump owner claiming the full line first keeps the exclusion a backstop rather than a load-bearing gate) and before HeidenhainFnFeatureSyntax (whose FN 9–12 pass-through remains the malformed-jump safety net: a line this regex rejects surfaces as visible residue, never a fabricated skip).
- HeidenhainIncrementalAxisWordUtil
The klartext I-prefixed incremental axis word —
IX+20,IY-15,IZ+Q1, rotaryIC+90: the same axis word as the absoluteX+20, read as a distance from the last programmed position instead of a coordinate. Any word of a block may be incremental on its own (L X+60 IY-10mixes both), which is exactly the per-word shape the shared PositioningOverride section models for the SiemensIC()wrapper. So the grab here writes the value under the plain axis key of the caller's section (Parsing.Xfor anL/LN/Cendpoint or anAPPRblock's first contour point,Parsing.CC.Xfor a circle center,Parsing[“CYCL CALL”].Xfor a cycle-call position,Parsing.DEP.Xfor aDEP LCTend point) and stamps“PositioningOverride”: { “X”: “Incremental” }on the block root; the conversion to absolute stays with the existing consumers — IncrementalResolveSyntax for linear axes (the Heidenhain instance also walks theCCand theDEPrecords), McAbcSyntax for rotary axes, and HeidenhainCannedCycleSyntax on the spot for the words it consumes ahead of the resolve — and no second incremental mechanism exists. The one klartextIword that is NOT a distance from the tool position, theCYCL DEF 7datum shift, deliberately does not use this helper (see HeidenhainDatumShiftSyntax).The plain axis grab (
NcSyntaxUtil.GrabTagValue) cannot see theXinsideIX: RegexFlagPrefix demands a word boundary, a digit or whitespace before the tag, andIis a word character. That guard is what keeps the plain grab from half-reading an incremental block (L X+60 IY-10used to take X and drop the Y — a motion to the wrong place, not a missing one), so the incremental words are grabbed by their own two-letter tags (IX,IY, …) instead of relaxing the guard. The value grammar is the shared one (signed number,Qvariable, bracket expression), and a glued run (LIX+20IY-15) parses like the absolute glued shape because the digit alternative of the prefix guard admits the second word.
- HeidenhainLSyntax
Heidenhain linear movement (the leading L) syntax. Strips the leading
L— spaced (L X+10) or glued directly to an axis/F word (LX+153.933Y+4.196A-77.516, the dominant shape of post-processed turbine files) — writes theParsing.L = truestatement marker, and grabs axis-tag values for any of AxisTagList (X, Y, Z, U, V, W, A, B, C) that appear afterwards as{axis}{signed-value}pairs; values are parsed as floats via ToFloat(string).LN/LP/LBLlines are excluded by the gate's lookahead: a glued axis letter only counts when followed by a sign, digit, dot or Q variable, so the B ofLBL(followed by another L) never matches. Glued M words (LM09) are accepted — stripping the L exposes the M word for the numbered-flag syntax; the richerLM140/LM128statements never reach this gate because their dedicated owners run earlier in the Heidenhain Parsing bundle.Axis words land on the root of Parsing (not nested under
L) so the shared Logic consumers — ProgramXyzSyntax, McAbcSyntax, MachineCoordSelectSyntax, IncrementalResolveSyntax — read them without per-brand path configuration. TheLmarker is consumed by HeidenhainMotionModeSyntax which maps the statement (plus a one-shotFMAXflag) onto the shared G00/G01 motion-mode vocabulary.The radius-compensation words
RL/RR/R0are captured as boolean records on the Parsing root; the Logic-stage HeidenhainRadiusCompSyntax maps them onto the shared G41/G42/G40 vocabulary consumed by the radius compensation pass.Incremental axis words (
L IX+20 IY-15, mixed with absolute ones at will) land under the same plain axis keys, with a per-axis"PositioningOverride": { "X": "Incremental" }stamp on the block root for the shared resolve consumers — see HeidenhainIncrementalAxisWordUtil. The glued gate admits the prefixed spelling too (LIX+20).
- HeidenhainLblSyntax
Syntax for Heidenhain LBL command (label definition). Label can be a number (1-65535) or a text name (e.g., “MyLabel”). LBL 0 is reserved for end of subprogram.
Only a DEFINITION is captured:
CALL LBL(any spacing) and the FN 9–12 jump spellings (GOTO LBL n, gluedGOTOLBL) are excluded — this syntax doubles as the label-scan probe of the P4 call machinery, where mistaking a jump line (or the call line itself) for a definition splices the wrong program section.
- HeidenhainLnSyntax
Heidenhain LN (surface-normal block) syntax — the CAM-generated straight line carrying the endpoint plus up to two normalized vectors, in the manual's fixed element order
X,Y,Z → NX,NY,NZ → TX,TY,TZ: the surface-normal vectorNX/NY/NZ(the 3D tool-compensation direction) and the optional tool vectorTX/TY/TZ(the tool-axis orientation, acted on only under M128 / FUNCTION TCPM). Strips the leadingLN— spaced or glued straight onto an axis or vector word — writes the shared StatementKey statement marker (an LN block is a feed-rate linear move, so the shared motion-mode mapping serves it unchanged), sweeps the six vector components into the nestedParsing.LNrecord, and grabs endpoint axis words andRL/RR/R0onto the Parsing root exactly like HeidenhainLSyntax. TheParsing.LNrecord — created even when the block carries no vector words, so the LN identity always reaches the Logic stage — is consumed by HeidenhainLnOrientationSyntax, which applies the manual's posture rules and writes the brand-agnosticToolOrientation/SurfaceNormalsections.Vector words are grabbed before the root axis words as ordering hygiene; correctness does not depend on it — RegexFlagPrefix rejects a tag preceded by a letter, so a bare
Xcan never claim the X ofNX. Runs ahead of HeidenhainLSyntax in the bundle; the L gate's lookahead already excludesLN, so this is ordering hygiene as well, not a claim race.Incremental endpoint words (
LN IX+20 IY-15 …, mixed with absolute ones at will) land under the same plain axis keys with the per-axis"PositioningOverride": { "Y": "Incremental" }stamp on the block root, exactly like HeidenhainLSyntax — see HeidenhainIncrementalAxisWordUtil. The manual states theIprefix as a general rule for programmed positions and gives the LN endpoint no exception (its syntax table says only "coordinates of the straight-line end point"), so the endpoint follows that rule; the vector words have no incremental form. The glued gate admits the prefixed spelling too (LNIX+20).
- HeidenhainM128Syntax
Captures the klartext
M128word (RTCP on) together with its optional feed-limit argument (M128 F6000.) intoParsing.M128 { F? }. Must run before the shared F tag-value syntax — the F belongs to M128 (feed limit for compensating movements), and letting it reach the Parsing root would pollute the modal feedrate (HardNc has exactly this defect). Accepted spellings: the leading/glued L statement (LM128, mirroring the M140 sibling), the fully gluedM128F6000, and a Q-parameter feed limit (M128 FQ8, 1.H corpus) captured as the string token for the evaluator pass to resolve.M129(RTCP off) carries no argument and stays on the shared numbered-flag path.
- HeidenhainM140Syntax
Captures the klartext
M140 MBtool-axis retract statement intoParsing.M140 { MB, F? }.MB MAXretracts to the traverse limit (recorded as the string“MAX”);MB+nretracts bynmm along the tool axis. Handles the corpus formsM140 MB+50 F6000,L M140 MB MAX(M word carried on an L statement) and the gluedLM140 MB MAX(TongTai post). Must run before HeidenhainLSyntax (it claims the whole retract statement including a leadingL) and before the shared F tag-value syntax (the F is the retract feed).
- HeidenhainMirrorImageSyntax
Heidenhain DIN/ISO
G28= MIRROR IMAGE (the CYCL DEF 8 twin; basic course 62192:G28 Xflips the X sign about the current datum,G28 X Yflips both, bareG28resets) — the exact opposite of the Fanuc reference-point return the shared G28Syntax would read it as. Claims the whole statement (code plus trailing axis words) ahead of the generic kit and records each statement underParsing.MirrorImageKey for the Logic-stage HeidenhainMirrorTransformSyntax, which simulates the mirror as a ProgramToMcTransform entry.Axis words are the manual's bare letters; a glued numeric or Q-variable follower (
G28 X0 Y0— the Fanuc idiom a mislabeled.Ifile could carry — orG28 XQ1) is claimed too so the value can never fall through to the root tag captures as a ghost coordinate, and the statement is stamped ValuedKey so the Logic stage keeps it recognized-but-not-simulated (mirroring on the Fanuc-shaped form would wreck a mislabeled reference-return file). A bare axis letter glued to another word (G28 CC…) stops the claim run — the leftover surfaces through the residue sentinels instead of being guessed at.
- HeidenhainPlaneSyntax
Syntax for the Heidenhain PLANE statement family. Fully structured (simulated by the Logic-stage tilt consumer):
PLANE RESET [STAY|MOVE|TURN]PLANE SPATIAL SPA SPB SPC [SEQ±] [COORD ROT|TABLE ROT] [MOVE [DIST..] [F..]|TURN|STAY]
PLANE PROJECTED PROPR PROMIN ROT ...PLANE VECTOR BX BY BZ NX NY NZ ...(corpus: 1.H)PLANE EULER/POINTS/RELATIV/AXIAL ...— the mode word is captured and the unmodeled argument text is swept verbatim into the record'sArgsso no token can leak to the shared tag captures (e.g. aPLANE AXIAL B+45B word must never become a rotary axis move).
MOVE DIST100 F8000is the repositioning feed and would otherwise pollute the modal feedrate (house.H corpus form; HardNc has exactly this defect).
- HeidenhainProgramSyntax
Syntax for Heidenhain BEGIN PGM and END PGM commands.
- HeidenhainTcpmSyntax
Captures the modern-TNC RTCP statement pair into
Parsing.TCPM:FUNCTION TCPM [args](RTCP on — the M128 successor) andFUNCTION RESET TCPM(RTCP off). The behavior-tuning argument words (F TCP / F CONT / AXIS POS / AXIS SPAT / PATHCTRL AXIS / PATHCTRL VECTOR) are corpus-zero and swept verbatim into the record'sArgs— recognized-but-not-simulated (the Logic RTCP consumer warns); activation/deactivation itself is simulated. Must run before the shared F tag-value syntax so an argument likeF TCPcan never be misread as a feed word.
- HeidenhainTildeTrimSyntax
Strips the TNC
~line-continuation markers from a grouped sentence'sUnparsedText. The raw BlockText keeps them (write-back authority); parsing only needs the joined lines. Both corpus spellings are removed —"… ;STRATEGIE ~"(space before, line tail) and"DATUM SETTING~"(glued). Placed at the head of the Parsing bundle, before the comment strippers, so a trailing~after a;comment never lands in the recorded comment text.
- HeidenhainToolCallSyntax
Syntax for Heidenhain TOOL CALL command. Handles: TOOL CALL [ToolId|“ToolName”] [X|Y|Z] [S…] [DL…] [DR…]
- HeidenhainToolDefSyntax
Syntax for the Heidenhain
TOOL DEFblock. With a tool table active the block pre-selects a tool —TOOL DEF 5readies tool 5 in the magazine for the nextTOOL CALL, no change happens — and the older in-program definition adds the tool's length and radius (TOOL DEF 5 L+10 R+5). A bareTOOL DEF— NX's klartext post writes one after everyTOOL CALL— names nothing and is consumed with no record. Handles: TOOL DEF [ToolId|“ToolName”] [L…] [R…]. The record is consumed by HeidenhainToolPreselectSyntax.