xdimedrolx/hoa-compiler

Hiqdev Hoa\Compiler 库。

1.0.1 2022-12-02 16:22 UTC

This package is auto-updated.

Last update: 2024-08-30 01:32:28 UTC


README

Hoa 项目已被归档,不会提供升级或补丁,也不会接受合并请求。

HOA 包包含一些针对 PHP 8.0 和 PHP 8.1 已弃用的代码,但我们需要这些包才能在现代 PHP 版本上运行。

从哪里开始变化?

更改主要影响了方法声明中的返回数据类型提示和未初始化属性的访问。

如何使用

我们目前已经分叉了以下包,主要是为了使 hoa/ruler 能够与 PHP 8.1 兼容

您可以直接在 composer.json 中替换 hoa 包的要求为相应的分叉包:无需更改代码库中的任何内容。

如果您使用某人需要 hoa 的包,只需将分叉添加到项目的根 composer.json 中:我们将分叉标记为替代品,因此 composer 将安装它们而不是原始包。

版本

我们从最新的 hoa 包版本进行分叉,并从 1.0 版本开始提升自己的版本。

测试

在运行测试套件之前,必须安装开发依赖项

$ composer install

然后,要运行所有测试套件

$ vendor/bin/hoa test:run

有关更多信息,请阅读 贡献指南

快速使用

作为一个快速概述,我们将查看 PP 语言和 LL(k) 编译器编译器。

PP 语言

语法由词元(单词的单位)和规则(请参阅文档了解语言理论的介绍)组成。PP 语言使用以下结构声明词元

%token [source_namespace:]name value [-> destination_namespace]

默认命名空间是 default。词元的值由一个 PCRE 表示。我们可以使用 %skip 结构跳过词元。

作为一个例子,我们将考虑 JSON 语言 的简化语法。完整的语法在 hoa://Library/Json/Grammar.pp 文件中。因此

%skip   space          \s
// Scalars.
%token  true           true
%token  false          false
%token  null           null
// Strings.
%token  quote_         "        -> string
%token  string:string  [^"]+
%token  string:_quote  "        -> default
// Objects.
%token  brace_         {
%token _brace          }
// Arrays.
%token  bracket_       \[
%token _bracket        \]
// Rest.
%token  colon          :
%token  comma          ,
%token  number         \d+

value:
    <true> | <false> | <null> | string() | object() | array() | number()

string:
    ::quote_:: <string> ::_quote::

number:
    <number>

#object:
    ::brace_:: pair() ( ::comma:: pair() )* ::_brace::

#pair:
    string() ::colon:: value()

#array:
    ::bracket_:: value() ( ::comma:: value() )* ::_bracket::

我们可以看到 PP 结构

  • rule() 用于调用规则;
  • <token>::token:: 用于声明词元;
  • | 用于析取;
  • (…) 用于分组多个声明;
  • e? 表示 e 是可选的;
  • e+ 表示 e 至少出现 1 次;
  • e* 表示 e 可以出现 0 或多次;
  • e{x,y} 表示 e 可以出现 xy 次;
  • #node 用于创建 AST(结果树)中的节点;
  • token[i] 用于在词元之间统一值。

统一非常有用。例如,如果我们有一个表示引号(单引号或双引号)的词元,我们可以有

%token  quote   "|'
%token  handle  \w+

string:
    ::quote:: <handle> ::quote::

因此,数据 "foo"'foo' 是有效的,但也可以是 "foo''foo"!为了避免这种情况,我们可以通过统一来添加新的词元值约束,因此

string:
    ::quote[0]:: <handle> ::quote[0]::

所有 quote[0] 规则实例必须具有相同的值。另一个示例是 XML 标签名统一。

LL(k) 编译器编译器

Hoa\Compiler\Llk\Llk类提供了操作(加载或保存)编译器的辅助工具。以下代码将使用之前的语法创建一个编译器,并解析一个JSON字符串。如果解析成功,它将生成一个抽象语法树(AST,即抽象语法树),我们可以对其进行访问,例如进行AST转储。

// 1. Load grammar.
$compiler = Hoa\Compiler\Llk\Llk::load(new Hoa\File\Read('Json.pp'));

// 2. Parse a data.
$ast = $compiler->parse('{"foo": true, "bar": [null, 42]}');

// 3. Dump the AST.
$dump = new Hoa\Compiler\Visitor\Dump();
echo $dump->visit($ast);

/**
 * Will output:
 *     >  #object
 *     >  >  #pair
 *     >  >  >  token(string, foo)
 *     >  >  >  token(true, true)
 *     >  >  #pair
 *     >  >  >  token(string, bar)
 *     >  >  >  #array
 *     >  >  >  >  token(null, null)
 *     >  >  >  >  token(number, 42)
 */

非常简单。

CLI中的编译器

这个库提供了一个脚本,用于解析并应用特定语法的访问者(visitor)到数据。非常有用。此外,我们可以使用管道(因为Hoa\File\Read——请参阅Hoa\File——支持使用0作为标准输入stdin),因此

$ echo '[1, [1, [2, 3], 5], 8]' | hoa compiler:pp Json.pp 0 --visitor dump
>  #array
>  >  token(number, 1)
>  >  #array
>  >  >  token(number, 1)
>  >  >  #array
>  >  >  >  token(number, 2)
>  >  >  >  token(number, 3)
>  >  >  token(number, 5)
>  >  token(number, 8)

你可以应用任何访问者类。

错误

错误展示得很好

$ echo '{"foo" true}' | hoa compiler:pp Json.pp 0 --visitor dump
Uncaught exception (Hoa\Compiler\Exception\UnexpectedToken):
Hoa\Compiler\Llk\Parser::parse(): (0) Unexpected token "true" (true) at line 1
and column 8:
{"foo" true}
       ↑
in hoa://Library/Compiler/Llk/Parser.php at line 1

采样器

一些算法可以根据语法生成数据。我们将只给出一个使用基于覆盖率的生成算法的示例,该算法将激活语法中的所有分支和标记。

$sampler = new Hoa\Compiler\Llk\Sampler\Coverage(
    // Grammar.
    Hoa\Compiler\Llk\Llk::load(new Hoa\File\Read('Json.pp')),
    // Token sampler.
    new Hoa\Regex\Visitor\Isotropic(new Hoa\Math\Sampler\Random())
);

foreach ($sampler as $i => $data) {
    echo $i, ' => ', $data, "\n";
}

/**
 * Will output:
 *     0 => true
 *     1 => {" )o?bz " : null , " %3W) " : [false, 130    , " 6"   ]  }
 *     2 => [{" ny  " : true } ]
 *     3 => {" Ne;[3 " :[ true , true ] , " th: " : true," C[8} " :   true }
 */

研究论文

文档

Hoa\Compiler的hacker手册包含了如何使用此库及其工作原理的详细信息。

要本地生成文档,请执行以下命令

$ composer require --dev hoa/devtools
$ vendor/bin/hoa devtools:documentation --open

更多文档可以在项目的网站上找到: hoa-project.net

获取帮助

获取帮助主要有两种方式

贡献

你想贡献吗?谢谢!详细的贡献指南解释了你需要知道的一切。

许可

Hoa采用新的BSD许可协议(BSD-3-Clause)。请参阅LICENSE以获取详细信息。