packages/bison-parser/bench/ParseBench.php

1<?php
2
3declare(strict_types=1);
4
5namespace Bench;
6
7use BisonParser\Parser;
8use BisonParser\Printer\Printer;
9use PhpBench\Attributes as Benchmark;
10
11/**
12 * Measures reading and writing a grammar of a few hundred rules.
13 */
14final class ParseBench
15{
16    private string $source = '';
17
18    private Parser $parser;
19
20    private Printer $printer;
21
22    /**
23     * Builds a grammar of two hundred rules with actions, tags and precedence before measurement.
24     */
25    public function setUp(): void
26    {
27        $lines = ['%token <int> NUM 258 "number"', '%left \'+\' \'-\'', '%left \'*\' \'/\'', '%%'];
28        for ($index = 0; $index < 200; $index++) {
29            $lines[] = "rule{$index}[r]: rule{$index} '+' NUM { \$\$ = \$1 + \$3; } | NUM %prec '*' | %empty ;";
30        }
31        $this->source = implode("\n", $lines) . "\n%%\nint main() {}\n";
32        $this->parser = new Parser();
33        $this->printer = new Printer();
34    }
35
36    /**
37     * Reads the grammar into a tree.
38     */
39    #[Benchmark\BeforeMethods('setUp')]
40    #[Benchmark\Revs(20)]
41    #[Benchmark\Iterations(5)]
42    public function benchParse(): void
43    {
44        $this->parser->parse($this->source);
45    }
46
47    /**
48     * Reads the grammar and writes it back out.
49     */
50    #[Benchmark\BeforeMethods('setUp')]
51    #[Benchmark\Revs(20)]
52    #[Benchmark\Iterations(5)]
53    public function benchRoundTrip(): void
54    {
55        $this->printer->print($this->parser->parse($this->source));
56    }
57}
58