packages/lemon-parser/tests/Unit/Printer/RulePrinterTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Printer;
6
7use LemonParser\Ast\CodeBlock;
8use LemonParser\Ast\Location;
9use LemonParser\Ast\RhsItem;
10use LemonParser\Ast\Rule;
11use LemonParser\Ast\Symbol;
12use LemonParser\Printer\RulePrinter;
13use PHPUnit\Framework\Attributes\CoversClass;
14use PHPUnit\Framework\Attributes\Small;
15use PHPUnit\Framework\Attributes\UsesClass;
16use PHPUnit\Framework\TestCase;
17
18#[CoversClass(RulePrinter::class)]
19#[UsesClass(CodeBlock::class)]
20#[UsesClass(Location::class)]
21#[UsesClass(RhsItem::class)]
22#[UsesClass(Rule::class)]
23#[UsesClass(Symbol::class)]
24#[Small]
25final class RulePrinterTest extends TestCase
26{
27    public function testPrint(): void
28    {
29        $at = new Location(1, 1);
30        $items = [new RhsItem([new Symbol('expr', $at)], 'B'), new RhsItem([new Symbol('PLUS', $at), new Symbol('MINUS', $at)], null)];
31        $full = new Rule(new Symbol('expr', $at), 'A', $items, new Symbol('STAR', $at), new CodeBlock(' A = B; ', $at), true, $at);
32        $bare = new Rule(new Symbol('empty', $at), null, [], null, null, false, $at);
33
34        self::assertSame('expr(A) ::= expr(B) PLUS|MINUS. [STAR] {NEVER-REDUCE} { A = B; }', (new RulePrinter())->print($full));
35        self::assertSame('empty ::=.', (new RulePrinter())->print($bare));
36    }
37
38    public function testItem(): void
39    {
40        $at = new Location(1, 1);
41        $printer = new RulePrinter();
42
43        self::assertSame('expr(B)', $printer->item(new RhsItem([new Symbol('expr', $at)], 'B')));
44        self::assertSame('PLUS|MINUS', $printer->item(new RhsItem([new Symbol('PLUS', $at), new Symbol('MINUS', $at)], null)));
45    }
46}
47