# @danielx/hera 中文文档

规范地址：https://npmcn.com/package/%40danielx/hera/

版本：0\.9\.9
npm 元数据更新时间：2026-10-13T16:41:19.741Z
中文译文更新时间：2026-11-11T10:56:06.662Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40danielx/hera
原文对照：https://npmcn.com/package/%40danielx/hera/?lang=original
项目主页：https://danielx.net/hera/docs/README.html
源码仓库：https://github.com/DanielXMoore/hera

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：199 kB，40 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2022-03-09T01:59:33.577Z
- 最新版本发布：2026-10-13T16:41:19.351Z
- 近 30 天下载量：2381（2026-10-12 至 2026-11-10，npm 官方下载统计）
- 已发布版本数：48（近 12 个月 14 个）

## 中文简介

小而快的表达式语法

## 安装

```sh
npm install @danielx/hera
```

也可以使用：`pnpm add @danielx/hera`、`yarn add @danielx/hera`、`bun add @danielx/hera`

## README

# 贺拉

> 我唱的是Rhea赤裸的金色的Hera. 永生之后是她,在美丽中超越了一切:她是大声的宙斯的姐妹和妻子,是整个奥林波斯高地所祝福的光荣之人,即使像在雷霆中喜悦的宙斯一样荣耀.
> 
> ——霍梅克·海姆12到赫拉 (转写:Evelyn-White)(希腊史诗C7到公元前4期)

[![Build](https://github.com/DanielXMoore/hera/actions/workflows/build.yml/badge.svg)](https://github.com/DanielXMoore/hera/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/DanielXMoore/hera/branch/main/graph/badge.svg)](https://codecov.io/gh/DanielXMoore/hera)

诸释迦之母.

-   [解析表达式语法 : 基于表彰的银河基金会](https://bford.info/pub/lang/peg.pdf)
-   [维基百科](https://en.wikipedia.org/wiki/Parsing_expression_grammar)
-   [开发者指南](https://npmcn.com/package/%40danielx/hera/docs/developer-guide.md)
-   [变动情况](https://npmcn.com/package/%40danielx/hera/CHANGELOG.md)

## 快速启动

```bash
npm install @danielx/hera
```

将“ a” 数与“ b” 数相接的示例语法 然后返回差数.

```hera
# parser.hera
Program
  A:a B:b ->
    return a.length - b.length
A
  "a"*
B
  "b"*
```

将解析器导入您的 JS/ TS 文件 :

```javascript
// index.mjs
import { parse } from "./parser.hera"

console.log(parse("aaaa"), parse("bbb"), parse("aabb")) // 4 -3 0

parse("c") // throws error
```

在命令行上运行 :

```bash
node --import '@danielx/hera/register' index.mjs
```

您语法中的处理器块也可以被写入 [类型脚本](https://www.typescriptlang.org/) 或者说 [密码](https://civet.dev/) 语法. 在这种情况下,使用适当的装载器:

```bash
node --import '@danielx/hera/register/tsc' index.mjs
# or
node --import '@danielx/hera/register/civet' index.mjs
```

使用 Hera 构建插件来捆绑 :

```javascript
import esbuild from "esbuild"
import heraPlugin from "@danielx/hera/esbuild"

await esbuild.build({
  entryPoints: ['index.mjs'],
  bundle: true,
  outfile: 'out.js',
  plugins: [heraPlugin()],
})
```

如果您的处理器块使用 TypeScript 或 Civet 语法, 通过 `language: "typescript"` 或者说 `language: "civet"` 输入 `heraPlugin(...)`。 。 。 .

## 概览

Hera 使用解析表达式语法为程序创建解析器 语言.

赫拉语法以缩入为主,每个规则由一个名字组成, 缩进的选择,名称可以扩展至,以及 用于每个选项的可选再缩进代码块( handler):

```
RuleName
  Choice1
  Choice2 ->
    ...code...
```

解析大量使用内置正则表达式能力 Java脚本. 终端要么是字面字符串,要么是正则表达式. 规则由其他规则和终端的选择或顺序组成.

文法中列出的第一条规则是起步点. 每一个选项 规则按顺序检查,然后返回第一次匹配.

## 定义

**规则**:一种取名出品. 名称由自己用一行未缩入的行来书写,选择(可能的扩展)则用相通的缩入来书写. 例如:

```
RuleName
  Choice1
  Choice2
```

选择按顺序进行尝试,第一个成功者获胜. 注意此属性具有递归性,因此可能涉及回溯. 每种选择都可以是下文定义的任何表达式,同时包括: 可选处理器.

**表达式**:一个表达式可以是一个序列,选择表达式,或者重复终端,规则名称,或者表达式(重复序列,选择表达式,或者重复). 在混合序列,选择表达式,和重复时,用括号将其分出. 譬如说, `Part ( "," Part )*` 是一个规则名称的序列和一个终端和一个规则名称的重复,代表一个或多个 `Part`以逗号分隔.

**选择表达式** (单位:千美元)`/`:一个简短的内置方式来指定两个或多个子选择之间的选择. 譬如说, `This / That / Other` 匹配 `This` 或者说 `That` 或者说 `Other`,以先成功为准。 这相当于 `AnonymousRule` 地点

```
AnonymousRule
  This
  That
  Other
```

选择表达式返回匹配的( 第1)表达式 .

**顺序** (单位:千美元) :一个接一个,由空格分隔. 譬如说, `"(" Expr ")"` 匹配字符 `"("` 接下来是 匹配数 `Expr` 接下来是字符 `")"`。 。 。 . 多个部分的序列返回多个部分的数组. 譬如说, `"(" Expr ")"` 返回由三个项目组成的数组: 字符串 `"("`,返回值为 `Expr`字符串 `")"`。 。 。 . 值得注意的是,如果一个表达是仅一个项目的"序列", 它不会被长到1个阵列包裹.

**终端字符串** (单位:千美元)`"..."`: 字符串正文(以双引号相绕). 整个字符串必须在准确的位置匹配. 终端字符串匹配时返回匹配的字符串 .

**终端正则表达式** (单位:千美元)`/.../`: 正则表达式,通常被前向鞭打所包围. 由 Just `.` 或字符类 喜欢 `[A-Z][a-z]*` 不需要周围的鞭打. 整个正则表达式必须在准确位置匹配 (好像正则表达式开始于 `^` 它被应用到弦的其余部分. 终端正则表达式返回 [`match`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) 数组: 索引上的匹配字符串 `[0]`,然后是任何匹配的组合 指数 `[1]`, (中文(简体) ), `[2]`,, , , , , , , , . (字符串或 `undefined` 用于未匹配的可选组. 例如,以下规则通过 `$1` 然后通过 `$1[0]`数字 :

```
Name
  /[A-Za-z][A-Za-z0-9]*/ "=" /\d+/ -> $1[0]
```

作为一种特殊的情况,如果整个表达式是一个正则表达式, 然后返回值是匹配的字符串而不是匹配数组, 和处理器变量取自匹配数组 : `$0` 是匹配的字符串(默认返回值), 财务报告和审定财务报表 `$1`, (中文(简体) ), `$2`被俘虏的团体 例如:

```
Name
  # Returns matched string:
  /([A-Za-z])[A-Za-z0-9]*/
  # Returns matched string:
  /([A-Za-z])[A-Za-z0-9]*/ -> $0
  # Returns matched first letter:
  /([A-Za-z])[A-Za-z0-9]*/ -> $1
```

**三斜正则表达式** (单位:千美元)`///...///`: 白空间不敏感正则表达式,类似于 [Civet 格氏语法](https://civet.dev/reference#regular-expressions)。 。 。 . 空白空间和 `//` 身体内部的评论被忽略,如此之大 表达式可以分行:

```
Identifier
  ///
    [A-Za-z_]  // first character
    [A-Za-z0-9_]*
  ///
```

三斜正则表达式也支持插入. `${expr}` 实值 动态: 生成的剖析器重新评价 `expr` 当规则运行时,重建 页:1 `RegExp` 当生成源字符串时,并重用缓存 解析器,直到源代码更改.

```
Close
  /// ${closingPattern} ///
```

使用 `${const expr}` 用于插值应被捕获一次的插值. 如果每个插入部分都是 `const`,生成解析器计算 正则表达式一次再使用和普通正则相同的解析器 表达式。 在混合静态/动力表达式中,复杂 `const` 表达式 被缓存一次,而仅使用标识符 `const` 表达式是直接发射的.

```
Open
  /// ${const openingPattern} /// ->
    closingPattern = $0 === "(" ? "\\)" : "\\]"
    return $0

Close
  # Returns matched string:
  /// ${closingPattern} ///
```

取决于分析状态的动态内插需要与 处理器的突变解析器状态。 如果启用结果缓存, 该状态 必须是缓存密钥/状态的一部分,而规则更改它不应是 已缓存 .

**重复** (单位:千美元)`*`, (中文(简体) ), `+`: `...*` 表示零或以上 `...`" ,和 `...+` 表示一次或多次重复 `Choice`。 。 。 . 重复返回匹配的数组 . 特别是,数组的长度正是匹配的数量.

**可选** (单位:千美元)`?`: `...?` 表示零或一次扩张 `...`" . 如果 `...` 匹配时, `...?` 直接返回该值。 否则它成功而不消耗输入和返回 `undefined`不同 `*` 财务报告和审定财务报表 `+`, (中文(简体) ), `?` 不将其结果包成数组.

**寻找上游** (单位:千美元)`&`, (中文(简体) ), `!`: `&...` 财务报告和审定财务报表 `!...` 分别声称存在或不存在与 `...`,不推进位置或消耗任何投入。 譬如说, `&/\s/` 就像正则表情 `/(?=\s)/`。 。 。 . 两者 `&` 财务报告和审定财务报表 `!` 上游回归 `true`,这样匹配 vs 在标记为可选时无法区分 `?` (例如:. `(&Pattern)?`) (中文(简体) ).

**字符串** (单位:千美元)`$`: `$...` 匹配 `...` 但返回的只是匹配的输入的字符串,而不是匹配过程中的计算返回值(来自处理器和序列和重复的数组). 譬如说, `$/\d+/` 返回比对数字的字符串,而不是匹配数组,当表达式不仅仅是一个正则表达式时,该数组是有用的.

**返回类型**: 选择的返回类型(或更确切地说,其处理者) 可明确使用 `::type` 选择之后和之前 处理器( 如果有—— 否则它返回默认值) . 此返回类型在生成 TypeScript 或 Civet 输出时会被释放 . 您也可以写 `RuleName ::type` 在规则标题上使用该类型作为 默认规则中的每个选项.

**处理器**:从匹配的选择到语言原始的映射. 处理器附加到规则选择上 `->` 选择之后. 最普通的处理器是 JavaScript, TypeScript, 或者 Civet 代码缩进 在选择之下 `return`s 匹配选择的理想值. 或者,单一表达式可以在与 `->`并会隐含 `return`编. 处理器代码可以指代默认值 (终端字符串的字符串,序列或重复的数组)通过 `$0`, (中文(简体) ), 如果不提供处理器,选择会得到回报. 这个 `n`最顶端序列中的 sth 匹配项目可以通过 `$n`· ; 最高序列中的每个项目也可以通过一个 `:name` 后缀 (例如, `Block:name`),然后代码也可以称为 `name`。 。 。 . 作为一种特殊的情况,如果扩张是单一的正则表达, `$0` 指匹配的字符串(而不是匹配数组)和 `$n` 提及 `n`(原始内容存档于2018-03-21). th group in the regex. 处理器代码可以返回特殊值 `$skip` 以显示失败的匹配.

**注释** (单位:千美元)`#...`: 处理器之外,线路从 `#` (在可能缩进之后)作为评论处理. 内部处理器,使用处理器语言的评论,例如,, `//` 或者说 `/*...*/`。 。 。 .

## 代码块

您可以使用三个回击创建直接插入的代码块 输入编译文件,使用与处理器相同的语言. 这对于创建公用功能或增加出口都是有益的.

````
```
function toInt(n) {
  return parseInt(n)
}
```

Number
  [0-9]+ ->
    return toInt($0)
````

## 演示文稿

如果这些演示不能交互, 请查看此页面 [https://danielx.net/hera/docs/README.html (中文(简体) )](https://danielx.net/hera/docs/README.html)

* * *

URL 解析器 [https://tools.itf.org/html/rfc3986 (中文(简体) )](https://tools.ietf.org/html/rfc3986)

> ```
> #! hera url
> ```

* * *

数学实例.

> ```
> #! hera math
> ```

* * *

赫拉是自我生成的:

> ```
> #! hera hera
> ```

* * *

脚本位置示例

> ```
> #! hera
> Grammar
>   Punctuation? A+ Punctuation? ->
>     return [$1, ...$2, $3].filter((token) => token !== undefined)
> 
> A
>   ("a" / "A") ->
>     return {type: "A", loc: $loc, value: $1}
> 
> Punctuation
>   "!" / "." / "?" ->
>     return {type: "Punctuation", loc: $loc, value: $1}
> ```

* * *

Regex 组

> ```
> #! hera
> Phone
>   /1-(\d{3})-(\d{3})-(\d{4})/ -> [$1, $2, $3]
> ```

* * *

> ```
> #! hera
> Grammar
>   NamedMapping NamedMapping
> 
> NamedMapping
>   Punctuation -> ["P", $0]
> 
> Punctuation
>   "."
> ```

## 实验

编译解析器到 TypeScript .

## 词汇表

`EOS` - 发言结束

`EOF` - 文件/输入结束

## V2 构想

从匹配序列的一部分输出字符串的简单方式 。 也许添加 护理/选择前缀操作员.

优化选项、顺序和regexes(合并)的重复 减少调用.

平面图和其他平面图.

为处理者命名参数 .

减少常见子序列的回溯:

```
RuleBody
  Indent Sequence EOS (Indent ^Sequence EOS)+ -> ["/", [2, 4...]]
  Indent Sequence EOS -> 2
```

上述规则应该能够高效(不需要回溯) 因为它有一个共同的子序列 它应该 能够重新使用已经完成的工作.

一种选择是把它变成一条带可选部分的规则,并添加 逻辑进入处理器, 但似乎粗糙.

* * *

> ```
> #! setup
> require("./interactive")(register)
> ```

## CJS/ESM装载机

实现直接 `import` 或者说 `require` 联 合 国 `.hera` 文档, 在操作语言中使用适当的加载器:

### `--import/--require @danielx/hera/register`

装入编译到 JavaScript 的.hera 文件 .

### `--import/--require @danielx/hera/register/tsc`

装入编译到 TypeScript 的.hera 文件.

试图装入 `typescript` npm 模块将生成的 TypeScript 转换为 JavaScript .

### `--import/--require @danielx/hera/register/civet`

装入编译到 Civet 的.hera 文件 .

试图装入 `@danielx/civet` npm 模块将生成的 Civet 转换为 JavaScript .

### 指定 Hera 编译器选项

见 [`loader-examples/hera-custom`](https://npmcn.com/package/%40danielx/hera/loader-examples/hera-custom) 用于将选项传递到赫拉编译器的示例.

支持的 Hera 编译器选项在 [选项](https://npmcn.com/package/%40danielx/hera/#readme-options)。 。 。 .

#### 无害环境管理

而不是使用 `--import @danielx/hera/register`,登记 `@danielx/hera/register/esm` 钩并传递编译器选项.

举个例子.

```js
// loader.js
const heraOptions = { ... }
register("@danielx/hera/register/esm", pathToFileURL(__filename), { data: heraOptions })
```

```sh
node --import ./loader.js my-script.mjs
```

#### 司法理事会

而不是使用 `--require @danielx/hera/register`,要求和设置选项 `@danielx/hera/register/cjs` 模块.

举个例子.

```js
require("@danielx/hera/register/cjs").options.hera = { inlineMap: false }

const { parse } = require("./my-typed-grammar.hera")
```

见 [`loader-examples/hera-custom/register.js`](https://npmcn.com/package/%40danielx/hera/loader-examples/hera-custom/register.js) 例如,同时登记无害环境管理和CJS两种选择.

### 设置类型脚本或 Civet 编译器选项

见 [`loader-examples/tsc-custom`](https://npmcn.com/package/%40danielx/hera/loader-examples/tsc-custom) 或者说 [`loader-examples/civet-custom`](https://npmcn.com/package/%40danielx/hera/loader-examples/civet-custom) 用于将选项传递到 TypeScript 或 Civet 编译器.

#### 无害环境管理

而不是使用 `--import @danielx/hera/register/tsc` 或者说 `--import @danielx/hera/register/civet`,登记 `register/esm` 财务报告和审定财务报表 `register/tsc/esm` 或者说 `register/civet/esm` 模块并传递您想要的选项. (注意您还需要注册基地) `register/esm` 模块,因为无害环境管理装载器连锁在一起。 )

举个例子.

```js
// custom-loader.js
const { register } = require("node:module")
const { pathToFileURL } = require("node:url")

register("@danielx/hera/register/esm", pathToFileURL(__filename), {
  data: heraOptions
})

register("@danielx/hera/register/tsc/esm", pathToFileURL(__filename), {
  data: tscCompilerOptions,
})
// OR
register("@danielx/hera/register/civet/esm", pathToFileURL(__filename), {
  data: civetCompilerOptions,
})
```

```sh
node --import ./custom-loader.js ./my-script.mjs
```

#### 司法理事会

而不是使用 `--require @danielx/hera/register/tsc` 或者说 `--require @danielx/hera/register/civet`,要求和设置选项 `@danielx/hera/register/tsc/cjs` 或者说 `@danielx/hera/register/civet/cjs` 模块.

举个例子.

```js
const loader = require("@danielx/hera/register/tsc/cjs")
loader.options.hera = heraOptions
loader.options.tsc = tscCompilerOptions

const { parse } = require("./typed-grammar.hera")
```

```js
const loader = require("@danielx/hera/register/civet/cjs")
loader.options.hera = heraOptions
loader.options.civet = civetCompilerOptions

const { parse } = require("./civet-grammar.hera")
```

见 [`loader-examples/tsc-custom/register.js`](https://npmcn.com/package/%40danielx/hera/loader-examples/tsc-custom/register.js) 财务报告和审定财务报表 [`loader-examples/civet-custom/register.js`](https://npmcn.com/package/%40danielx/hera/loader-examples/civet-custom/register.js) 以实例说明同时登记无害环境管理和CJS的选项.

## 新建插件

使用 `heraPlugin()` 要导入 `.hera` 正在构建的文件.

如果处理器机构或代码块使用 TypeScript 或 Civet, 请设置插件 明确语言:

```js
heraPlugin({ language: "typescript" })
heraPlugin({ language: "civet" })
```

插件自动选择合适的 esbuild 加载器, 虽然你可以用 `loader` 选项.

## 编辑器工具

VS 代码扩展和语言服务器支持 `hera.language` 用于控制 如何解释处理者的尸体.

在 VS 代码设置中 :

```json
{
  "hera.language": "civet"
}
```

在你的工作空间 `package.json`数字 :

```json
{
  "hera": {
    "language": "civet"
  }
}
```

见 [`lsp/README.md`](https://npmcn.com/package/%40danielx/hera/lsp/README.md)。 。 。 .

## API 密码

无害环境管理:

```js
import { compile } from "@danielx/hera"
```

CJS: 贾克:

```js
const { compile } = require("@danielx/hera")
```

### `compile(grammar, options?)`

将一个赫拉语法编译为解析源代码.

-   以原始语法源为字符串通过.
-   默认返回代码字符串 .
-   回返 `{ code, sourceMap }` 何时 `options.sourceMap` 实值 `true`。 。 。 .

### 选项

`compile()` 接受这些选项:

-   `language?: "javascript" | "typescript" | "civet"`: 处理器体和代码块所使用的语言. 默认 : `"javascript"`。 。 。 .
-   `types?: boolean`: 生成 TypeScript-flavored 剖析器输出. 默认 : `false` 何时 `language` 未说明或 `"javascript"`,以及 `true` 何时 `language` 实值 `"typescript"` 或者说 `"civet"`。 。 。 .
-   `module?: boolean`: 消除无害环境管理,而不是CJS产出。 默认 : `false`。 。 。 .
-   `filename?: string`: 生成源地图中使用的文件名. 默认 : `"anonymous"`。 。 。 .
-   `source?: string`:原始语法源文本. 需要时间 `inlineMap` 或者说 `sourceMap` 已启用.
-   `inlineMap?: boolean`: 在生成的输出中添加内置源代码注释。 默认 : `false`。 。 。 .
-   `sourceMap?: boolean`编号: 返回 `{ code, sourceMap }` 而不是代码串。 默认 : `false`。 。 。 .
-   `libPath?: string`: 导入生成解析器所使用的 Hera 运行时库的路径 。 默认 : `"@danielx/hera/lib"`。 。 。 .

## 常见问题

### @danielx/hera 是什么？

小而快的表达式语法

### 如何安装 @danielx/hera？

在项目目录运行 npm install @danielx/hera，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 hera，可以用 npx hera 直接运行。

### @danielx/hera 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @danielx/hera 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @danielx/hera 可以商用吗？

@danielx/hera 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @danielx/hera 的下载量有多少？

根据 npm 官方下载统计，@danielx/hera 在 2026/10/12 – 2026/11/10 这 30 天内被下载 2,381 次，日均约 79 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @danielx/hera 还在维护吗？

最新版本 0\.9\.9 发布于 2026/10/14（28 天前）；至今共发布 48 个版本，其中过去 12 个月发布了 14 个；首次发布于 2022/03/09。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

