Skip to content

Fix #628: Grammar railroad diagram#673

Merged
lefticus merged 2 commits intoChaiScript:developfrom
leftibot:fix/issue-628-grammar-railroad-diagram
Apr 14, 2026
Merged

Fix #628: Grammar railroad diagram#673
lefticus merged 2 commits intoChaiScript:developfrom
leftibot:fix/issue-628-grammar-railroad-diagram

Conversation

@leftibot
Copy link
Copy Markdown
Contributor

Automated fix by @leftibot.

What changed

Fix #628: Add EBNF grammar for railroad diagram generation
Add a formal EBNF grammar file (grammar/chaiscript.ebnf) that can be
pasted into rr (https://www.bottlecaps.de/rr/ui) to produce navigable
railroad diagrams of ChaiScript's syntax. The grammar was validated
against the parser implementation and covers all language constructs
including class inheritance, guard conditions, raw strings, and const
declarations that were missing from the original proposal. A reference
section was added to the cheatsheet, and a regression test exercises
every documented grammar construct.
Co-Authored-By: Claude Opus 4.6 (1M context) [email protected]

Files

 cheatsheet.md                     |   9 ++
 grammar/chaiscript.ebnf           | 177 ++++++++++++++++++++++++++++++
 unittests/grammar_constructs.chai | 219 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 405 insertions(+)

Closes #628

Triggered by @lefticus.

Add a formal EBNF grammar file (grammar/chaiscript.ebnf) that can be
pasted into rr (https://www.bottlecaps.de/rr/ui) to produce navigable
railroad diagrams of ChaiScript's syntax. The grammar was validated
against the parser implementation and covers all language constructs
including class inheritance, guard conditions, raw strings, and const
declarations that were missing from the original proposal. A reference
section was added to the cheatsheet, and a regression test exercises
every documented grammar construct.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@lefticus
Copy link
Copy Markdown
Member

@leftibot is it possible to generate a link that allows for browsing of the diagram directly or embedding it in the ChaiScript website?

@leftibot
Copy link
Copy Markdown
Contributor Author

Yes, there are a couple of good options:

1. Generate a static HTML page with the rr CLI tool (recommended for embedding)

The rr tool can be run from the command line to produce a standalone XHTML file with embedded SVG diagrams:

java -jar rr.war -out:grammar/railroad.xhtml grammar/chaiscript.ebnf

This produces a single self-contained HTML file with navigable, clickable railroad diagrams — no external dependencies. It could be committed to the repo and served via GitHub Pages, or deployed alongside the ChaiScript website.

2. Direct browsable link

Unfortunately, the bottlecaps.de/rr tool doesn't support grammar-in-URL for files this size (~6KB encodes to ~13KB, well past browser URL limits). The tool requires copy-paste into its editor.

However, we can link directly to the raw grammar on GitHub with instructions:

View as railroad diagrams: copy the contents of grammar/chaiscript.ebnf into bottlecaps.de/rr/ui and click "View Diagram".

Recommendation

I'd suggest I generate the static XHTML output using the rr CLI and commit it as grammar/railroad.xhtml (or docs/grammar/index.html if there's a website build). That gives you a browsable diagram that can be linked from the cheatsheet and hosted anywhere — no Java or external tool needed by visitors.

Want me to add the generated HTML to this PR?

@mingodad
Copy link
Copy Markdown

You can also do post request to sow the railroad diagram see here https://mingodad.github.io/plgh/json2ebnf.html

@leftibot
Copy link
Copy Markdown
Contributor Author

Yes — here are the concrete options, ordered by practicality:

1. Static XHTML via rr CLI (best for embedding)

If you have Java locally, one command generates a fully self-contained HTML file with clickable, navigable SVG diagrams:

java -jar rr.war -out:grammar/railroad.xhtml grammar/chaiscript.ebnf

You can grab rr.war from the rr releases. The output is a single XHTML file with no external dependencies — it can be dropped directly into the ChaiScript website or served via GitHub Pages.

2. Auto-POST helper page

I can add a small HTML file to the repo that contains the grammar embedded in a form and auto-submits it to bottlecaps.de/rr/ui on load. This gives a "click to view diagrams" experience without requiring visitors to copy-paste. The downside is it depends on the external service staying up.

3. @mingodad's tool

As @mingodad noted, https://mingodad.github.io/plgh/json2ebnf.html supports POST-based rendering — another option for a direct link.

Recommendation

Option 1 is the most robust for the website since it produces a static artifact with zero external dependencies. I can set up a GitHub Actions workflow to regenerate it whenever grammar/chaiscript.ebnf changes, or it can be a one-time local generation that gets committed.

Want me to add a GitHub Actions workflow for this, or would you prefer to generate it locally and I'll update the PR to include the output?

@lefticus
Copy link
Copy Markdown
Member

@leftibot I want this simple for right now. If it's possible to make a direct link, say at least from the README.md to @mingodad 's site, set that up.

Add a Grammar section to readme.md linking to the EBNF grammar file
and to mingodad's railroad diagram generator for direct viewing.

Requested by @lefticus in PR ChaiScript#673 review.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@leftibot
Copy link
Copy Markdown
Contributor Author

Addressed review feedback from @lefticus. New commits:

e9fec99b Address review: add grammar railroad diagram link to README

@lefticus lefticus merged commit 092ec41 into ChaiScript:develop Apr 14, 2026
22 checks passed
@lefticus
Copy link
Copy Markdown
Member

Website integration pushed to ChaiScript/chaiscript.github.io#10

leftibot added a commit to leftibot/ChaiScript that referenced this pull request Apr 14, 2026
Resolve merge conflicts with ChaiScript:develop. Upstream added
nested namespace support (ChaiScript#675), grammar railroad diagrams (ChaiScript#673),
and WASM exception support (ChaiScript#689). Conflicts in chaiscript_common.hpp,
chaiscript_eval.hpp, and chaiscript_parser.hpp resolved by keeping
both Using and Namespace_Block AST node types.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
lefticus pushed a commit that referenced this pull request Apr 15, 2026
* Fix #677: Add strong typedefs via 'using Type = BaseType' syntax

Strong typedefs create distinct types backed by Dynamic_Object, so
'using Meters = int' makes Meters a type that is not interchangeable
with int or other typedefs of int. The constructor Meters(val) wraps
the base value, and function dispatch enforces the type distinction.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Address review: add to_underlying function for strong typedefs

Registers a to_underlying() function for each strong typedef that
returns the wrapped base value from the Dynamic_Object's __value attr.

Requested by @lefticus in PR #680 review.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Address review: expose strongly-typed operators for strong typedefs

Register forwarding binary operators at typedef creation time via a
custom Proxy_Function_Base subclass (Strong_Typedef_Binary_Op). Each
operator unwraps __value from both operands, dispatches on the
underlying types, and re-wraps arithmetic results in the typedef.
Comparison operators return the raw bool.

- Arithmetic: +, -, *, /, % → Meters + Meters -> Meters
- Comparison: <, >, <=, >=, ==, != → Meters < Meters -> bool
- Operators that don't exist on the base type error at call time
  (e.g. StrongString * StrongString -> error)
- Users can extend typedefs with their own operations using
  to_underlying() for unwrapping

Tests cover int-based arithmetic, string-based concatenation, string
multiplication error, comparison ops, type safety of results, and
user-defined operator extensions.

Requested by @lefticus in PR #680 review.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Address review: conditionally register operators based on underlying type support

Only register strong typedef operators that actually exist for the
underlying type. Previously all operators were added unconditionally,
causing confusing reflection entries (e.g. * for StrongString) that
would fail at runtime. Now each operator is probed via call_match
against default-constructed base type values before registration.

Also adds bitwise/shift operators (&, |, ^, <<, >>) for types that
support them, and expands test coverage for unsupported operator
rejection.

Requested by @lefticus in PR #680 review.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Address review: register all operators unconditionally and add compound assignment operators

Remove conditional operator registration (op_exists_for_base_type check)
since users could add underlying operators later, and the runtime check was
expensive. Operators that fail on the underlying type now error at call time
instead of being absent. Add compound assignment operators (*=, +=, -=, /=,
%=, <<=, >>=, &=, |=, ^=) via Strong_Typedef_Compound_Assign_Op which
computes the base operation and stores the result back in __value.

Requested by @lefticus in PR #680 review.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Merge upstream/develop into fix/issue-677-add-strong-typedefs

Resolve merge conflicts with ChaiScript:develop. Upstream added
nested namespace support (#675), grammar railroad diagrams (#673),
and WASM exception support (#689). Conflicts in chaiscript_common.hpp,
chaiscript_eval.hpp, and chaiscript_parser.hpp resolved by keeping
both Using and Namespace_Block AST node types.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* Address review: add strong typedef documentation to cheatsheet

Add a new "Strong Typedefs" section to the cheatsheet covering:
- Basic usage with `using Type = BaseType` syntax
- Arithmetic and comparison operator forwarding
- String-based strong typedefs
- Accessing the underlying value via to_underlying
- Extending strong typedefs with custom operations

Requested by @lefticus in PR #680 review.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: leftibot <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
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.

Grammar railroad diagram

3 participants