interitty / pacc
PHP 的解析器生成器(目前生成递归下降解析器和规范 LR(1) 解析器)。
Requires
- php: ~8.3
- dg/composer-cleaner: ~2.2
- interitty/console: ~1.0
- interitty/tokenizer: ~1.0
- interitty/utils: ~1.0
- nette/php-generator: ~4.1
Requires (Dev)
- interitty/code-checker: ~1.0
- interitty/phpunit: ~1.0
Replaces
- jakubkulhan/pacc: *
README
PHP 的解析器生成器(目前生成递归下降解析器和规范 LR(1) 解析器)。
要求
- PHP >= 8.3
安装
安装 interitty/pacc 的最佳方式是使用 Composer
composer require interitty/pacc
使用方法
可执行脚本 pacc
位于 Composer 二进制文件夹 中。
如果没有提供参数,Pacc 期望从标准输入获取语法定义,并将结果输出到标准输出。
vendor/bin/pacc
通常,语法定义通过 --input=<grammar file>
参数或其简写形式 -i <grammar file>
提供。当期望将输出存储在文件中时,可以使用 --output=<output file>
参数或其简写形式 -o <output file>
。
vendor/bin/pacc -i vendor/interitty/pacc/examples/GrammarParser.y -o vendor/interitty/pacc/examples/GrammarParser.php
当输出文件已存在时,可以使用 --force
参数或其简写形式 -f
来很有用。
当发生错误时,增加 详细程度 可能很有用。
编写解析器
pacc
消耗的文件结构如下
grammar <<parser_name>>;
option <<option_name>> = <<option_value>>;
/**
<<phpDoc>>
*/
@<<code>>
{
<<php or yacc code>>
}
<<rules>>
规则被编译成 PHP 解析器代码,头部和尾部保持不变。
pacc
与 YACC/Bison 的规则语法兼容,并增加了对方法返回类型的支持。每个规则由其名称、:
、主体和;
组成。名称必须匹配正则表达式 [a-z][a-z_]*
。主体由用 |
分隔的表达式组成。每个表达式可以有一些附加的 PHP 代码,用 {
和 }
包围。
例如
numerical_operation
: number '+' number { $$ = $1 + $3; /* $1 is first number, $2 is plus sign, and $3 is second number */ }
| number '-' number : int { $$ = $1 - $3; }
;
在 PHP 代码中,你可以使用特殊变量如 $$
、$1
、$2
、$3
等。在 $$
中是表达式的保存结果。通过数字变量,你可以获得子表达式的结果。
这些特殊变量可以有可选的返回类型和 phpDoc 类型,用 <
和 >
包围在 $
和变量名之间,例如 $<returnType#phpDocType>$
。例如 $<stdClass|null>1
、$<?array|array<mixed>|null>2
在 examples/
目录中寻找灵感。