public function testGenerateDotSyntax() { // $file = EBNF_TESTS_FIXTURS . "/Renderer/test_grammar.ebnf"; $file = EBNF_TESTS_FIXTURS . "/rules_with_literals.ebnf"; $scanner = new Scanner(file_get_contents($file)); $parser = new Parser($scanner); $parser->parse(); $ast = $parser->getAst(); $visitor = new GraphvizSyntaxTree($file); $ast->accept($visitor); $this->assertEquals('digraph "' . $file . '" { size = "8,8"; ordering = out; node [shape=record]; n4; n5; n7; n8; n10; n11; n13; n14; node [shape=ellipse]; n0; n1; n2; n3; n6; n9; n12; n0 [label="syntax"]; n1 [label="{rule|literal}"]; n2 [label="choice"]; n3 [label="sequence"]; n4 [label="{terminal|\'}"]; n5 [label="{identifier|character}"]; n6 [label="loop"]; n7 [label="{identifier|character}"]; n8 [label="{terminal|\'}"]; n9 [label="sequence"]; n10 [label="{terminal|\\"}"]; n11 [label="{identifier|character}"]; n12 [label="loop"]; n13 [label="{identifier|character}"]; n14 [label="{terminal|\\"}"]; n0 -> n1; n1 -> n2; n2 -> { n3 n9 }; n3 -> { n4 n5 n6 n8 }; n6 -> n7; n9 -> { n10 n11 n12 n14 }; n12 -> n13; }', $visitor->getDotString()); $this->markTestIncomplete("TODO: Ordering of nodes maybe wrong."); }
/** * Generates either CLI or file output depending on -f option. * * @param string $input The input grammar. * * @return void */ private function generateOutput($input) { $scanner = new Scanner($input); $parser = new Parser($scanner); $ast = $parser->parse(); if ("texttree" === $this->format) { $visitor = new TextSyntaxTree(); $parser->getAst()->accept($visitor); echo $visitor->getText(); } else { if ("xml" === $this->format) { $visitor = new Xml(); $parser->getAst()->accept($visitor); file_put_contents($this->outfile, $visitor->getXmlString()); } else { $renderer = new Renderer($this->format, $this->outfile, $ast); $renderer->save(); } } }
public function testGenerateText() { $builder = new SyntaxBuilder(); $builder->syntax("foo"); $ast = $builder->getAst(); $visitor = new TextSyntaxTree(); $ast->accept($visitor); $this->assertEquals("[syntax]" . PHP_EOL, $visitor->getText()); $visitor = new TextSyntaxTree(); $builder->rule("rule-1"); $ast = $builder->getAst(); $ast->accept($visitor); $this->assertEquals("[syntax]" . PHP_EOL . " +--[rule='rule-1']" . PHP_EOL, $visitor->getText()); $visitor = new TextSyntaxTree(); $builder->rule("rule-2"); $ast = $builder->getAst(); $ast->accept($visitor); $this->assertEquals("[syntax]" . PHP_EOL . " +--[rule='rule-1']" . PHP_EOL . " +--[rule='rule-2']" . PHP_EOL, $visitor->getText()); $choice = $builder->clear()->rule("name")->choice(); $ast = $builder->getAst(); $visitor = new TextSyntaxTree(); $ast->accept($visitor); $this->assertEquals("[syntax]" . PHP_EOL . " +--[rule='name']" . PHP_EOL . " +--[choice]" . PHP_EOL, $visitor->getText()); $choice->identifier("ident")->terminal("term")->end(); $ast = $builder->getAst(); $ast->accept($visitor); $this->assertEquals("[syntax]" . PHP_EOL . " +--[rule='name']" . PHP_EOL . " +--[choice]" . PHP_EOL . " +--[identifier='ident']" . PHP_EOL . " +--[terminal='term']" . PHP_EOL, $visitor->getText()); $visitor = new TextSyntaxTree(); $builder->clear()->syntax("foobar")->rule("one")->choice()->end()->rule("two"); $ast = $builder->getAst(); $ast->accept($visitor); $this->assertEquals("[syntax]" . PHP_EOL . " +--[rule='one']" . PHP_EOL . " | +--[choice]" . PHP_EOL . " +--[rule='two']" . PHP_EOL, $visitor->getText()); $fixtureDir = EBNF_TESTS_FIXTURS . DIRECTORY_SEPARATOR . "visitor" . DIRECTORY_SEPARATOR . "TextSyntaxTree"; $file = EBNF_TESTS_FIXTURS . "/rules_with_literals.ebnf"; $scanner = new Scanner(file_get_contents($file)); $parser = new Parser($scanner); $parser->parse(); $ast = $parser->getAst(); $visitor = new TextSyntaxTree(); $ast->accept($visitor); $this->assertEquals(file_get_contents($fixtureDir . DIRECTORY_SEPARATOR . "rules_with_literals"), $visitor->getText()); }
public function testParseAst() { $p = new Parser(new Scanner($this->loadFixture("rules_with_different_assignment_ops.ebnf"))); $p->parse(); $builder = new SyntaxBuilder(); $builder->syntax("Rules with different assignment operators.")->rule("comment1")->identifier("literal1")->end()->rule("comment2")->identifier("literal2")->end()->rule("comment3")->identifier("literal3")->end(); $this->assertEquivalentSyntax($builder->getAst(), $p->getAst()); $p = new Parser(new Scanner($this->loadFixture("rules_with_literals.ebnf"))); $p->parse(); $builder->clear()->syntax("Rules with literal.")->rule("literal")->choice()->sequence()->terminal("'")->identifier("character")->loop()->identifier("character")->end()->terminal("'")->end()->sequence()->terminal('"')->identifier("character")->loop()->identifier("character")->end()->terminal('"')->end()->end()->end(); $this->assertEquivalentSyntax($builder->getAst(), $p->getAst()); $p = new Parser(new Scanner($this->loadFixture("testgrammar_1.old.ebnf"))); $p->parse(); $builder->clear()->syntax("EBNF defined in itself.")->rule("syntax")->sequence()->option()->identifier("title")->end()->terminal("{")->loop()->identifier("rule")->end()->terminal("}")->option()->identifier("comment")->end()->end()->end()->rule("rule")->sequence()->identifier("identifier")->choice()->terminal("=")->terminal(":")->terminal(":==")->end()->identifier("expression")->choice()->terminal(".")->terminal(";")->end()->end()->end()->rule("expression")->sequence()->identifier("term")->loop()->sequence()->terminal("|")->identifier("term")->end()->end()->end()->end()->rule("term")->sequence()->identifier("factor")->loop()->identifier("factor")->end()->end()->end()->rule("factor")->choice()->identifier("identifier")->identifier("literal")->identifier("range")->sequence()->terminal("[")->identifier("expression")->terminal("]")->end()->sequence()->terminal("(")->identifier("expression")->terminal(")")->end()->sequence()->terminal("{")->identifier("expression")->terminal("}")->end()->end()->end()->rule("identifier")->sequence()->identifier("character")->loop()->identifier("character")->end()->end()->end()->rule("range")->sequence()->identifier("character")->terminal("..")->identifier("character")->end()->end()->rule("title")->identifier("literal")->end()->rule("comment")->identifier("literal")->end()->rule("literal")->choice()->sequence()->terminal("'")->identifier("character")->loop()->identifier("character")->end()->terminal("'")->end()->sequence()->terminal('"')->identifier("character")->loop()->identifier("character")->end()->terminal('"')->end()->end()->end()->rule("character")->choice()->terminal("a")->terminal("b")->terminal("c")->terminal("d")->terminal("e")->terminal("f")->terminal("g")->terminal("h")->terminal("i")->terminal("j")->terminal("k")->terminal("l")->terminal("m")->terminal("n")->terminal("o")->terminal("p")->terminal("q")->terminal("r")->terminal("s")->terminal("t")->terminal("u")->terminal("v")->terminal("w")->terminal("x")->terminal("y")->terminal("z")->terminal("A")->terminal("B")->terminal("C")->terminal("D")->terminal("E")->terminal("F")->terminal("G")->terminal("H")->terminal("I")->terminal("J")->terminal("K")->terminal("L")->terminal("M")->terminal("N")->terminal("O")->terminal("P")->terminal("Q")->terminal("R")->terminal("S")->terminal("T")->terminal("U")->terminal("V")->terminal("W")->terminal("X")->terminal("Y")->terminal("Z")->end()->end(); $this->assertEquivalentSyntax($builder->getAst(), $p->getAst()); }