interitty / pacc
Parser generator (currently generates recursive descent parser and canonical LR(1) parser) for PHP.
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
Parser generator (currently generates recursive descent parser and canonical LR(1) parser) for PHP.
Requirements
- PHP >= 8.3
Installation
The best way to install interitty/pacc is using Composer:
composer require interitty/pacc
Usage
The executable script pacc
is available in the Composer binary folder.
When no arguments are given, the Pacc expect the grammar definition from standard input and put result to standard output.
vendor/bin/pacc
Normaly the grammar definition is given via --input=<grammar file>
argument or his short variant -i <grammar file>
.
When the output is expected to store in file, there is an --output=<output file>
argument or his short variant -o <output file>
.
vendor/bin/pacc -i vendor/interitty/pacc/examples/GrammarParser.y -o vendor/interitty/pacc/examples/GrammarParser.php
When the output file already exists, it can be usefull to use --force
argument or his short variant -f
.
When something wrong happens, it can be useful to increase the verbosity level.
Write parsers
Files consumed by pacc
are structured like this:
grammar <<parser_name>>;
option <<option_name>> = <<option_value>>;
/**
<<phpDoc>>
*/
@<<code>>
{
<<php or yacc code>>
}
<<rules>>
Rules are compiled into PHP parser code, header and footer are left as they are.
pacc
is compatible with YACC/Bison syntax for rules
with the additional support of method return types.
Each rule consists of its name, :
, body, and ;
.
Name has to match regular expression [a-z][a-z_]*
.
The body consists of expressions separated by |
.
Each expression can have some attached PHP code between {
and }
.
For example:
numerical_operation
: number '+' number { $$ = $1 + $3; /* $1 is first number, $2 is plus sign, and $3 is second number */ }
| number '-' number : int { $$ = $1 - $3; }
;
In PHP code, you can use special variables like $$
, $1
, $2
, $3
, etc. In $$
is the saved result of an expression.
Through numerical variables, you get a result of subexpressions.
These special variables can have optional return types and phpDoc types surrounded with <>
between $
and the
variable name like $<returnType#phpDocType>$
. For example $<stdClass|null>1
, $<?array|array<mixed>|null>2
Look for inspiration in the examples/
directory.