stratadox/parser

解析器组合库

v0.1.1 2023-11-13 12:26 UTC

This package is auto-updated.

Last update: 2024-09-13 14:33:38 UTC


README

Github Action Scrutinizer Code Quality

简单而强大的解析库。

这是什么

一个创建自定义解析器的库。基于“古老”的解析器组合概念,这个库包含大量基础解析器、装饰器、组合器和辅助工具。

为什么使用这个

使用此库创建的解析器可以用多种方式使用。解析是将文本转换为可使用结构的过程。

这可以用于各种目的,无论是将 json / csv / xml / yaml 等转换为某种数据结构,还是将自定义 DSL 或表达式语言解析为抽象语法树。

无论您是想创建自己的文件格式、自己的编程语言、解释现有的文件格式或语言……这个库都会为您提供帮助。

如何使用这个

有关实际操作说明,请参阅 指南

安装

使用 composer: composer require stratadox/parser

概述

有 3 个基础解析器:anytextpattern

  • Any 匹配任何单个字符。
  • Text 匹配预定义的字符串。
  • Pattern 匹配正则表达式。

这些可以通过大量附加组件(“装饰器”)进行升级,可以根据需要组合使用。

  • Repeatable 任何次数地应用解析器,生成一个列表。
  • Map 基于函数修改成功的结果。
  • Full Map 基于函数修改所有结果。
  • Ignore 需要该对象存在,然后忽略它。(喵喵)
  • Maybe 不需要它,但如果有,则使用它。
  • Optional 结合上述两种。
  • Except 如果另一个解析器成功,则“不匹配”。
  • End 如果存在未解析的内容,则返回错误状态。
  • All or Nothing 修改解析错误。

可以使用这些组合器组合解析器

上述所有内容都可以自由混合和组合。为了使生活更轻松,有一系列组合器快捷方式用于“日常任务”。

  • Between 匹配解析器内容在起始和结束之间。
  • Between Escaped 匹配起始和结束之间的非转义内容。
  • Split 根据分隔符生成一个或多个结果。
  • Must Split 根据分隔符生成两个或多个结果。
  • Keep Split 生成类似 {delimiter: [left, right]} 的结构。

有几个额外的辅助工具,本质上是一些映射快捷方式

  • Join 将数组结果压缩为一个字符串。
  • Non-Empty 拒绝 empty 结果。
  • At Least 拒绝少于 x 个条目的数组。
  • At Most 拒绝多于 x 个条目的数组。
  • First 将数组结果转换为它的第一个元素。
  • Item 将数组结果转换为它的第 n 个元素。

要启用懒解析器(以及/或提供结构),不同类型的容器可用

示例 1:CSV

对于基本“现实生活”示例,这里有一个简单的 CSV 解析器

<?php
use Stratadox\Parser\Helpers\Between;
use Stratadox\Parser\Parser;
use function Stratadox\Parser\any;
use function Stratadox\Parser\pattern;

function csvParser(
    Parser|string $sep = ',',
    Parser|string $esc = '"',
): Parser {
    $newline = pattern('\r\n|\r|\n');
    return Between::escaped('"', '"', $esc)
        ->or(any()->except($newline->or($sep)->or($esc))->repeatableString())
        ->mustSplit($sep)->maybe()
        ->split($newline)
        ->end();
}

(有关关联结果映射,请参阅 CSV 示例

示例 2:计算器 AST

下一个示例将基本的算术字符串(例如 1 + -3 * 3 ^ 2)解析为抽象语法树

<?php
use Stratadox\Parser\Containers\Grammar;
use Stratadox\Parser\Containers\Lazy;
use Stratadox\Parser\Parser;
use function Stratadox\Parser\pattern;
use function Stratadox\Parser\text;

function calculationsParser(): Parser
{
    $grammar = Grammar::with($lazy = Lazy::container());

    $sign = text('+')->or('-')->maybe();
    $digits = pattern('\d+');
    $map = fn($op, $l, $r) => [
        'op' => $op,
        'arg' => [$l, $r],
    ];

    $grammar['prio 0'] = $sign->andThen($digits, '.', $digits)->join()->map(fn($x) => (float) $x)
        ->or($sign->andThen($digits)->join()->map(fn($x) => (int) $x))
        ->between(text(' ')->or("\t", "\n", "\r")->repeatable()->optional());

    $lazy['prio 1'] = $grammar['prio 0']->andThen('^', $grammar['prio 0'])->map(fn($a) => [
        'op' => '^',
        'arg' => [$a[0], $a[2]],
    ])->or($grammar['prio 0']);

    $grammar['prio 2'] = $grammar['prio 1']->keepSplit(['*', '/'], $map)->or($grammar['prio 1']);

    $grammar['prio 3'] = $grammar['prio 2']->keepSplit(['+', '-'], $map)->or($grammar['prio 2']);

    return $grammar['prio 3']->end();
}

(有关工作示例,请参阅 计算器示例

文档

更多文档可通过 指南参考 和/或 测试 获得。