Skip to content

Let one analyzer run another's passes on a node (4.1.0) - #739

Merged
ddehilster merged 1 commit into
masterfrom
feat/call-analyzer
Sep 13, 2026
Merged

ddehilster merged 1 commit into
masterfrom
feat/call-analyzer

Conversation

@ddehilster

Copy link
Copy Markdown
Member

What

A new NLP++ builtin, callanalyzer(pnode, concept, "name"), lets one analyzer be built from several separately written analyzers that all share one parse tree and one knowledge base. callconcept() is how the called analyzer gets the concept it was handed.

  • Works on part of the caller's tree. The called analyzer's passes run on the subtree under pnode (its rules see pnode's children, and pnroot() is pnode). Its changes stay in the caller's tree.
  • Uses the caller's KB directly. callconcept() returns the caller's concept itself; nothing is copied.
  • Loaded once. The first call builds its passes and reads its kb/user .dict and .kbb files into the shared KB; *full files are registered for lazy lookup. Later calls read nothing. Its .kb files are not read, because they would add every attribute value a second time.
  • On each call: tokenizer passes are skipped; a dicttok/dicttokz pass instead looks up the subtree's words, lazy *full files included, gives them their dictionary attributes, and matches phrases (DICTTok::applyToSubtree); G() variables start empty; G("$apppath") is the called analyzer's folder; no per-pass .tree dumps, which are named by pass number and would overwrite the caller's.
  • Refused: an analyzer calling itself, directly or through another analyzer. Returns 0 with the reason in err.log.

Also

  • CG::openFullDict/openFullKBB now clear fullMissCache_. A word looked up before a lazy file was registered was cached as absent and never searched for in that file.
  • NlpDebug::suspend/resume: the debugger does not stop inside a called analyzer, and a nested analysis no longer leaves it disarmed.
  • Version bumped to 4.1.0; the help pages name that release.

Tests

New CI step (Windows and Linux) with fixtures tests/call-analyzer and tests/call-analyzer-callee. It checks that only the given nodes change, a word found only in the callee's lazy shades-full.dict is resolved, the callee loads once for two calls, G() stays separate, and self-calls, back-calls and unknown names return 0.

Locally on Windows: every fixture step in build-windows.yml passes, including the rule-level debugger step, and parse-en-us produces a final.tree byte-identical to the golden copy.

Not tested: compiled analyzers calling callanalyzer (the Arun forms build but have not been run), and a call made with a debugger attached.

Known, not fixed here

An analyzer whose kb/user holds .dict files but no hier.kb segfaults on its first attribute add (seen while writing the fixtures, which now include a hier.kb).

Help pages: separate PR in VisualText/visualtext-files; merge it after this ships.

🤖 Generated with Claude Code

callanalyzer(pnode, concept, "name") runs the named analyzer's passes
on the subtree under pnode, in the caller's parse tree and KB.
callconcept() gives the called analyzer the concept it was handed.

The called analyzer is built on first use and stays in the VTRun
registry, together with its .dict and .kbb files read into the shared
KB and its *full files registered for lazy lookup. On each call its
tokenizer passes are skipped, a dicttok pass looks up the subtree's
words (lazy files included) via the new DICTTok::applyToSubtree, G()
variables start empty, and no per-pass .tree dumps are written.
Self-calls and cycles are refused.

CG::openFullDict/openFullKBB now clear the lazy-lookup miss cache, so
a word missed before a lazy file was registered is looked up in it.

NlpDebug::suspend/resume keep the debugger's pause points off inside a
called analyzer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ddehilster
ddehilster merged commit 626e7a8 into master Sep 13, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant