DEV Community

星野夢華
星野夢華

Posted on

Building a single-pass rich-text DSL parser (no regex)

I built this while trying to replace Markdown in my personal blog.
Markdown is convenient, but once you start adding custom syntax, parsing rules quickly become hard to reason about.

I wanted something with:

  • predictable parsing behavior
  • nested structures without ambiguity
  • extensible semantics
  • minimal syntax surface

So instead of a regex-driven approach, I implemented a single-pass recursive descent parser with no backtracking.
The parser handles three forms — inline, block, and raw — all using the same core state machine.

For example:

$$bold(hello)$$

$$info()*
This is a block tag
*end$$

Handlers are pluggable, so the grammar stays small while behavior is defined externally.
This keeps the parser focused on structure, not rendering.

The result is a lightweight DSL that works well for structured rich text, especially in static site generators or blog engines.

GitHub: https://github.com/chiba233/yumeDSL
npm: https://www.npmjs.com/package/yume-dsl-rich-text
demo: https://qwwq.org/blog/dsl-fallback-museum

Top comments (0)