phplrt/phplrt

PHP语言识别工具


README

Phplrt

PHP 7.4+ Latest Stable Version Latest Unstable Version Total Downloads License MIT

介绍

phplrt 是一组用于编程语言识别的工具。该库提供词法分析器、解析器、语法编译器、错误处理库、文本分析等功能。

安装

phplrt 可作为 composer 仓库使用,您可以使用以下命令在项目根目录下安装:

$ composer require phplrt/phplrt

更详细的安装说明请参阅此处

文档

快速开始

首先,我们将为我们的解析器创建语法。

您可以在此处了解更多关于语法语法的知识。

<?php

use Phplrt\Compiler\Compiler;

$compiler = new Compiler();
$compiler->load(<<<EBNF
   
    %token T_DIGIT          \d
    %token T_PLUS           \+
    %token T_MINUS          \-
    %token T_POW            \*
    %token T_DIV            /
    %skip  T_WHITESPACE     \s+
    
    #Expression
      : <T_DIGIT> (Operator() <T_DIGIT>)* 
      ;

    #Operator
      : <T_PLUS>
      | <T_MINUS>
      | <T_POW>
      | <T_DIV>
      ;

EBNF);

执行

为了快速检查所编写代码的性能,您可以使用简单的 parse() 方法。结果,它将输出识别的抽象语法树,以及可以转换为字符串表示的预定义 AST 类。

<?php

echo $compiler->parse('2 + 2');

//
// Output:
//
// <Expression offset="0">
//     <T_DIGIT offset="0">2</T_DIGIT>
//     <Operator offset="2">
//         <T_PLUS offset="2">+</T_PLUS>
//     </Operator>
//     <T_DIGIT offset="4">2</T_DIGIT>
// </Expression>
//

编译

当您的语法准备就绪并经过测试后,应该对其进行编译。之后,您不再需要 phplrt/compiler 依赖(参见 https://phplrt.org/docs/installation#runtime-only)。

file_put_contents(__DIR__ . '/grammar.php', (string)$compiler->build());

该文件将包含您编译后的数据,这些数据可以用于您的自定义解析器。

use Phplrt\Lexer\Lexer;
use Phplrt\Parser\Parser;
use Phplrt\Parser\BuilderInterface;
use Phplrt\Parser\Context;

$data = require __DIR__ . '/grammar.php';

// Create Lexer from compiled data
$lexer = new Lexer($data['tokens']['default'], $data['skip']);

// Create Parser from compiled data
$parser = new Parser($lexer, $data['grammar'], [

    // Recognition will start from the specified rule
    Parser::CONFIG_INITIAL_RULE => $data['initial'],

    // Rules for the abstract syntax tree builder. 
    // In this case, we use the data found in the compiled grammar.
    Parser::CONFIG_AST_BUILDER => new class($data['reducers']) implements BuilderInterface {
        public function __construct(private array $reducers) {}

        public function build(Context $context, $result)
        {
            $state = $context->getState();

            return isset($this->reducers[$state])) 
                ? $this->reducers[$state]($context, $result)
                : $result
            ;
        }
    }
]);

// Now we are ready to parse any code using the compiled grammar

$parser->parse(' ..... ');