objectionary/phino
GitHub: objectionary/phino
用于 𝜑-演算表达式的命令行规范化、重写与数据化工具,支持自定义规则、模式匹配和多程序合并,服务于 EO 语言的形式化研究与工具链构建。
Stars: 17 | Forks: 6
# 𝜑-Calculus 表达式的命令行操作器
[](https://www.rultor.com/p/objectionary/phino)
[](http://hackage.haskell.org/package/phino)
[](https://github.com/objectionary/phino/actions/workflows/cabal.yml)
[](https://github.com/objectionary/phino/actions/workflows/stack.yml)
[](https://app.codecov.io/gh/objectionary/phino)
[](https://objectionary.github.io/phino/)
[](LICENSES/MIT.txt)
[](https://hitsofcode.com/github/objectionary/phino/view?branch=master&label=Hits-of-Code)
[](https://www.0pdd.com/p?name=objectionary/phino)
这是一个针对 [𝜑-calculus](https://www.eolang.org) 表达式的命令行规范化器、重写器和数据化器。
首先,在 `hello.phi` 文件中编写一个简单的 [𝜑-calculus](https://www.eolang.org) 程序:
```
Φ ↦ ⟦ φ ↦ ⟦ Δ ⤍ 68-65-6C-6C-6F ⟧, t ↦ ξ.k, k ↦ ⟦⟧ ⟧
```
## 安装
然后你可以通过两种方式安装 `phino`:
首先安装 [Cabal][cabal],然后执行:
```
cabal update
cabal install --overwrite-policy=always phino-0.0.0.67
phino --version
```
或者使用 [curl](https://curl.se/) 或 [wget](https://en.wikipedia.org/wiki/Wget) 从互联网下载二进制文件:
```
sudo curl -o /usr/local/bin/phino http://phino.objectionary.com/releases/macos-15/phino-latest
sudo chmod +x /usr/local/bin/phino
phino --version
```
下载路径如下:
* Ubuntu 22.04:
* Ubuntu 24.04:
* MacOS (ARM):
* MacOS (Intel):
* Windows:
## 构建
要从源代码构建 `phino`,请克隆此代码库:
```
git clone git@github.com:objectionary/phino.git
cd phino
```
然后,运行以下命令(请确保已安装 [Cabal][cabal]):
```
cabal build all
```
接下来,运行以下命令以在全局范围内安装 `phino`:
```
sudo cp "$(cabal list-bin phino)" /usr/local/bin/phino
```
验证 `phino` 是否安装成功:
```
$ phino --version
0.0.0.0
```
## 数据化
然后,对该程序进行数据化:
```
$ phino dataize hello.phi
68-65-6C-6C-6F
```
## 重写
你可以借助定义在 `my-rule.yml` YAML 文件中的[规则](#rule-structure)来重写此表达式(这里的 `!d` 是一个捕获组,类似于正则表达式):
```
name: My custom rule
pattern: Δ ⤍ !d
result: Δ ⤍ 62-79-65
```
然后,进行重写:
```
$ phino rewrite --rule=my-rule.yml hello.phi
Φ ↦ ⟦ φ ↦ ⟦ Δ ⤍ 62-79-65 ⟧, t ↦ ξ.k, k ↦ ⟦⟧ ⟧
```
如果你想使用多个规则,只需根据需要多次使用 `--rule` 即可:
```
phino rewrite --rule=rule1.yaml --rule=rule2.yaml ...
```
你也可以使用[内置规则](resources),这些规则旨在对表达式进行规范化:
```
phino rewrite --normalize hello.phi
```
如果未提供输入文件,𝜑-表达式将从 `stdin` 获取:
```
$ echo 'Φ ↦ ⟦ φ ↦ ⟦ Δ ⤍ 68-65-6C-6C-6F ⟧ ⟧' | phino rewrite --rule=my-rule.yml
Φ ↦ ⟦ φ ↦ ⟦ Δ ⤍ 62-79-65 ⟧ ⟧
```
你可以传入 [`XMIR`][xmir] 作为输入。使用 `--input=xmir`,`phino` 将从文件或 `stdin` 解析给定的 `XMIR` 并将其转换为 `phi` AST。
```
phino rewrite --rule=my-rule.yaml --input=xmir file.xmir
```
此外,`phino` 支持 [ASCII](https://en.wikipedia.org/wiki/ASCII) 格式及带有语法糖的 𝜑-表达式。`rewrite` 命令还允许你去除表达式的语法糖,并以规范语法打印输出:
```
$ echo 'Q -> [[ @ -> Q.io.stdout("hello") ]]' | phino rewrite
Φ ↦ ⟦
φ ↦ Φ.io.stdout(
α0 ↦ Φ.string(
α0 ↦ Φ.bytes(
α0 ↦ ⟦ Δ ⤍ 68-65-6C-6C-6F ⟧
)
)
)
⟧
```
## 合并
你可以通过合并顶层 formations,将多个 𝜑-程序合并为一个:
```
$ cat bytes.phi
{⟦ bytes(data) ↦ ⟦ φ ↦ data ⟧ ⟧}
$ cat number.phi
{⟦
number(as-bytes) ↦ ⟦
φ ↦ as-bytes,
plus(x) ↦ ⟦ λ ⤍ L_number_plus ⟧
⟧
⟧}
$ cat minus.phi
{⟦ number ↦ ⟦ minus(x) ↦ ⟦ λ ⤍ L_number_minus ⟧ ⟧ ⟧}
$ phino merge bytes.phi number.phi minus.phi --sweet
{⟦
bytes(data) ↦ ⟦ φ ↦ data ⟧,
number(as-bytes) ↦ ⟦
φ ↦ as-bytes,
plus(x) ↦ ⟦ λ ⤍ L_number_plus ⟧,
minus(x) ↦ ⟦ λ ⤍ L_number_minus ⟧
⟧
⟧}
```
## 匹配
你可以测试 𝜑-程序是否与[规则](#rule-structure)模式相匹配。结果输出包含已匹配的替换项:
```
$ phino match --pattern='⟦ Δ ⤍ !d, !B ⟧' hello.phi
B >> ⟦ ρ ↦ ∅ ⟧
d >> 68-65-6C-6C-6F
```
## 解释
你可以通过以 [LaTeX][latex] 格式打印来_解释_重写规则:
```
$ phino explain --normalize
\begin{tabular}{rl}
\trrule{alpha}
{ [[ B_1, \tau_1 -> ?, B_2 ]] ( \tau_2 -> e ) }
{ [[ B_1, \tau_1 -> ?, B_2 ]] ( \tau_1 -> e ) }
{ if $ \indexof{ \tau_2 } = \vert B_1 \vert $ }
{ }
\trrule{dc}
{ T ( \tau -> e ) }
{ T }
{ }
{ }
...
\trrule{stop}
{ [[ B ]] . \tau }
{ T }
{ if $ \tau \notin B \;\text{and}\; @ \notin B \;\text{and}\; L \notin B $ }
{ }
\end{tabular}
```
有关更多详细信息,请使用 `phino [COMMAND] --help` 选项。
## 规则结构
这是类似 BNF 的 yaml 规则结构。这里以撇号结尾的类型(如 `Attribute'`)是从 𝜑-程序 [AST](src/AST.hs) 构建的类型。
```
Rule:
name: String
pattern: String
result: String
when: Condition? # predicate, works with substitutions before extension
where: [Extension]? # substitution extensions
having: Condition? # predicate, works with substitutions after extension
Condition:
= and: [Condition] # logical AND
| or: [Condition] # logical OR
| not: Condition # logical NOT
| alpha: Attribute' # check if given attribute is alpha
| eq: # compare two comparable objects
- Comparable
- Comparable
| in: # check if attributes exist in bindings
- Attribute'
- Binding'
| nf: Expression' # returns True if given expression in normal form
# which means that no more other normalization rules
# can be applied
| xi: Expression' # special condition for Rcopy normalization rule to
# avoid infinite recursion while the condition checking
# returns True if there's no ξ outside of the formation
# in given expression.
| matches: # returns True if given expression after dataization
- String # matches to given regex
- Expression
| part-of: # returns True if given expression is attached to any
- Expression' # attribute in ginve bindings
- BiMeta'
Comparable: # comparable object that may be used in 'eq' condition
= Attribute'
| Number
| Expression'
Number: # comparable number
= Integer # just regular integer
| index: Attribute' # calculate index of alpha attribute
| length: BiMeta' # calculate length of bindings by given meta binding
Extension: # substitutions extension used to introduce new meta variables
meta: [ExtArgument] # new introduced meta variable
function: String # name of the function
args: [ExtArgument] # arguments of the function
ExtArgument
= Bytes' # !d
| Binding' # !B
| Expression' # !e
| Attribute' # !a
```
以下为支持用于扩展的函数列表:
* `contextualize` - 具有两个参数的函数,根据[规则](assets/contextualize.jpg)提供的上下文重写给定表达式。
* `scope` - 解析给定表达式的作用域。仅适用于表示为 `𝑒` 或 `!e` 的元表达式。作用域是最近的外部 formation(如果存在)。在所有其他情况下,使用默认作用域,即匿名 formation `⟦ ρ ↦ ∅ ⟧`。
* `random-tau` - 创建具有随机唯一名称的属性。接受绑定和属性。确保创建的属性不存在于提供的属性列表中,并且不存在于提供的绑定中作为属性。
* `dataize` - 对给定表达式进行数据化并返回字节。
* `concat` - 接受字节或可数据化的表达式作为参数,将它们连接成单一序列,并将其转换为可美观打印为人类可读字符串的表达式:`Φ.string(Φ.bytes⟦ Δ ⤍ !d ⟧)`。
* `sed` - 模式替换器,其工作方式类似于 unix 的 `sed` 函数。接受两个参数:目标表达式和模式。模式必须以 `s/` 开头,由三部分组成,以 `/` 分隔,例如,模式 `s/\\s+//g` 会将所有空格替换为空字符串。要在模式和替换部分中转义大括号和斜杠,请使用 `\\`,例如 `s/\\(.+\\)//g`。
* `random-string` - 接受可数据化的表达式或字节作为模式。将 `%x` 和 `%d` 格式化符号分别替换为随机的十六进制数字和十进制数字。在一次 `phino` 执行期间可保证唯一性。
* `size` - 仅接受一个元绑定并返回其大小以及 `Φ.number`。
* `tau` - 接受 `Φ.string`,对其进行数据化并将其转换为属性。如果数据化后的字符串无法转换为属性,将引发错误。
* `string` - 接受 `Φ.string`、`Φ.number` 或属性并将其转换为 `Φ.string`。
* `number` - 接受 `Φ.string` 并将其转换为 `Φ.number`。
* `sum` - 接受 `Φ.number` 或 `Φ.bytes` 的列表并返回它们的总和作为 `Φ.number`。
* `join` - 接受绑定列表并返回连接后的绑定列表。重复的 `ρ`、`Δ` 和 `λ` 属性将被忽略,所有其他重复的属性将使用 `random-tau` 函数替换为唯一的属性。
## 元变量
`phino` 支持使用元变量来编写用于捕获属性、绑定等的 𝜑-表达式模式。
以下是支持的元变量列表:
* `!a` || `𝜏` - 属性
* `!e` || `𝑒` - 任意表达式
* `!B` || `𝐵` - 绑定列表
* `!d` || `δ` - 元 delta 绑定中的字节
* `!t` - 表达式之后的尾部,即应用和/或分发的序列,必须仅以分发开头
* `!F` - 元 lambda 绑定中的函数名称
每个元变量还可以与整数索引一起使用,例如 `!B1` 或 `𝜏0`。
在 𝜑-表达式模式中不正确地使用元变量会导致解析错误。
标签:Cabal, DNS解析, EO语言, Haskell, Objectionary, Phi-Calculus, Stack, φ微积分, 云安全监控, 代码分析, 凭证管理, 函数式编程, 可配置连接, 开源项目, 形式化方法, 程序分析, 编译器, 表达式规范化, 表达式重写, 静态分析, 默认DNS解析器