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