コード例 #1
0
ファイル: SyntaxBuilder.php プロジェクト: bgarrels/ebnf
 /**
  * Declare a {@link Rule} for the syntax.
  *
  * @param string $name Name of the rule.
  *
  * @return RuleBuilder
  */
 public function rule($name)
 {
     $rule = new Rule($this->syntax);
     $rule->name = (string) $name;
     $this->syntax->addChild($rule);
     return new RuleBuilder($rule, $this);
 }
コード例 #2
0
ファイル: Validator.php プロジェクト: bgarrels/ebnf
 protected function visitSyntax(Syntax $syntax)
 {
     if ($this->isSyntaxDefined()) {
         throw new ValidaorException("You can specify a syntax only once!", ValidaorException::SYNTAXT_REDECLARATION);
     }
     $this->representative[$syntax->getNodeName()] = array("meta" => $syntax->meta, "title" => $syntax->title, "rule" => array());
 }
コード例 #3
0
ファイル: ParserTest.php プロジェクト: bgarrels/ebnf
 private function assertEquivalentSyntax(Syntax $expected, Syntax $actual)
 {
     $n = new Notification();
     $expected->probeEquivalence($actual, $n);
     $this->assertNotificationOk($n);
     $n = new Notification();
     $actual->probeEquivalence($expected, $n);
     $this->assertNotificationOk($n);
 }
コード例 #4
0
ファイル: XmlTest.php プロジェクト: bgarrels/ebnf
 /**
  * @todo use ast builder
  */
 public function testGenerateXml()
 {
     $visitor = new Xml();
     $this->assertEquals('<?xml version="1.0" encoding="utf-8"?>', $visitor->getXmlString());
     $syntax = new Syntax();
     $syntax->meta = "EBNF defined in itself.";
     $syntax->title = "xis/ebnf v2.0 http://wiki.karmin.ch/ebnf/ gpl3";
     $visitor = new Xml();
     $syntax->accept($visitor);
     $xml = file_get_contents(EBNF_TESTS_FIXTURS . "/visitor/syntax.xml");
     $this->assertEquals('<?xml version="1.0" encoding="utf-8"?>' . "\n" . '<syntax title="xis/ebnf v2.0 http://wiki.karmin.ch/ebnf/ gpl3" meta="EBNF defined in itself."/>', $visitor->getXmlString());
     $syntax = new Syntax();
     $syntax->title = "EBNF defined in itself.";
     $syntax->meta = "xis/ebnf v2.0 http://wiki.karmin.ch/ebnf/ gpl3";
     $syntaxRule = new Rule($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $syntaxRule->name = "syntax";
     $seq = new Sequence($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $opt = new Option($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "title";
     $opt->addChild($ident);
     $seq->addChild($opt);
     $terminal = new Terminal($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $terminal->value = "{";
     $seq->addChild($terminal);
     $loop = new Loop($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "rule";
     $loop->addChild($ident);
     $seq->addChild($loop);
     $terminal = new Terminal($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $terminal->value = "}";
     $seq->addChild($terminal);
     $opt = new Option($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "comment";
     $opt->addChild($ident);
     $seq->addChild($opt);
     $syntaxRule->addChild($seq);
     $syntax->addChild($syntaxRule);
     $ruleRule = new Rule($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ruleRule->name = "rule";
     $seq = new Sequence($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "identifier";
     $seq->addChild($ident);
     $choice = new Choice($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     foreach (array("=", ":", ":==") as $literal) {
         $terminal = new Terminal($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
         $terminal->value = $literal;
         $choice->addChild($terminal);
     }
     $seq->addChild($choice);
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "expression";
     $seq->addChild($ident);
     $choice = new Choice($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     foreach (array(".", ";") as $literal) {
         $terminal = new Terminal($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
         $terminal->value = $literal;
         $choice->addChild($terminal);
     }
     $seq->addChild($choice);
     $ruleRule->addChild($seq);
     $syntax->addChild($ruleRule);
     $literalRule = new Rule($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $literalRule->name = "literal";
     $choice = new Choice($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $seq = new Sequence($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $terminal = new Terminal($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $terminal->value = "'";
     $seq->addChild($terminal);
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "character";
     $seq->addChild($ident);
     $loop = new Loop($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "character";
     $loop->addChild($ident);
     $seq->addChild($loop);
     $seq->addChild($terminal);
     $choice->addChild($seq);
     $seq = new Sequence($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $terminal = new Terminal($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $terminal->value = '"';
     $seq->addChild($terminal);
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "character";
     $seq->addChild($ident);
     $loop = new Loop($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident = new Identifier($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ident->value = "character";
     $loop->addChild($ident);
     $seq->addChild($loop);
     $seq->addChild($terminal);
     $choice->addChild($seq);
     $literalRule->addChild($choice);
     $syntax->addChild($literalRule);
     $visitor = new Xml();
     $syntax->accept($visitor);
     $xml = file_get_contents(EBNF_TESTS_FIXTURS . "/visitor/syntax.xml");
     $this->assertEquals($xml, $visitor->getXmlString());
 }
コード例 #5
0
ファイル: IntegrationTest.php プロジェクト: bgarrels/ebnf
 public function testProbeEquivalenceSyntaxWithRules()
 {
     $syntax1 = new Syntax();
     $syntax1->title = "foo";
     $syntax1->meta = "bar";
     $syntax2 = new Syntax();
     $syntax2->title = "foo";
     $syntax2->meta = "bar";
     $syntax3 = new Syntax();
     $syntax3->title = "foo";
     $syntax3->meta = "bar";
     $rule1 = new Rule($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $rule1->name = "rule1";
     $syntax1->addChild($rule1);
     $syntax2->addChild($rule1);
     $n = new Notification();
     $syntax1->probeEquivalence($syntax2, $n);
     $this->assertTrue($n->isOk(), $n->report());
     $this->assertEquals("", $n->report());
     $n = new Notification();
     $syntax2->probeEquivalence($syntax1, $n);
     $this->assertTrue($n->isOk(), $n->report());
     $this->assertEquals("", $n->report());
     $rule2 = new Rule($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $rule2->name = "rule2";
     $syntax1->addChild($rule2);
     $error = "Node syntax has different child count than other: 2 != 1!\n";
     $error .= "Other node has not the expected subnode!";
     $n = new Notification();
     $syntax1->probeEquivalence($syntax2, $n);
     $this->assertFalse($n->isOk());
     $this->assertEquals($error, $n->report());
     $error = "Node syntax has different child count than other: 1 != 2!";
     $n = new Notification();
     $syntax2->probeEquivalence($syntax1, $n);
     $this->assertFalse($n->isOk());
     $this->assertEquals($error, $n->report());
     $syntax2->addChild($rule2);
     $n = new Notification();
     $syntax1->probeEquivalence($syntax2, $n);
     $this->assertTrue($n->isOk(), $n->report());
     $this->assertEquals("", $n->report());
     $n = new Notification();
     $syntax2->probeEquivalence($syntax1, $n);
     $this->assertTrue($n->isOk(), $n->report());
     $this->assertEquals("", $n->report());
     $rule3 = new Rule($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $rule3->name = "rule3";
     $syntax3->addChild($rule1);
     $syntax3->addChild($rule3);
     $n = new Notification();
     $syntax1->probeEquivalence($syntax3, $n);
     $this->assertFalse($n->isOk());
     $this->assertEquals("Names of rule differs: 'rule2' != 'rule3'!", $n->report());
 }
コード例 #6
0
ファイル: Parser.php プロジェクト: bgarrels/ebnf
 /**
  * Parses the EBNF tokens and returns a syntax tree as DOMDocument object on success.
  *
  * On semantic syntax errors a SyntaxtException will be thrown.
  *
  * @throws SyntaxtException
  * @return DOMDocument
  */
 public function parse()
 {
     $syntax = $this->dom->createElement(Type::SYNTAX);
     $this->scanner->nextToken();
     if ($this->scanner->currentToken()->isType(Token::LITERAL)) {
         $syntax->setAttribute('title', $this->scanner->currentToken()->getValue(true));
         $this->ast->title = $this->scanner->currentToken()->getValue(true);
         $this->scanner->nextToken();
     }
     if (!$this->assertToken($this->scanner->currentToken(), Token::OPERATOR, '{')) {
         $this->raiseError("Syntax must start with '{'");
     }
     $this->scanner->nextToken();
     while ($this->scanner->hasNextToken() && $this->scanner->currentToken()->isType(Token::IDENTIFIER)) {
         $rules = $this->parseRule();
         $syntax->appendChild($rules[0]);
         $this->ast->addChild($rules[1]);
         $this->scanner->nextToken();
     }
     if (!$this->assertToken($this->scanner->currentToken(), Token::OPERATOR, '}')) {
         $this->raiseError("Syntax must end with '}' but saw {$this->scanner->currentToken()}");
     }
     $this->scanner->nextToken();
     if ($this->scanner->hasNextToken()) {
         if ($this->scanner->currentToken()->isType(Token::LITERAL)) {
             $syntax->setAttribute('meta', $this->scanner->currentToken()->getValue(true));
             $this->ast->meta = $this->scanner->currentToken()->getValue(true);
         } else {
             $this->raiseError("Literal expected as syntax comment");
         }
     } else {
         $syntax->setAttribute('meta', self::DEFAULT_META);
         $this->ast->meta = self::DEFAULT_META;
     }
     $this->dom->appendChild($syntax);
     return $this->dom;
 }
コード例 #7
0
ファイル: ValidatorTest.php プロジェクト: bgarrels/ebnf
 public function testValidateRule()
 {
     $syntax = new Syntax();
     $syntax->meta = "foo meta";
     $syntax->title = "bar title";
     $ruleFoo = new Rule($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ruleFoo->name = "foo";
     $syntax->addChild($ruleFoo);
     $ruleBar = new Rule($this->getMock('de\\weltraumschaf\\ebnf\\ast\\Node'));
     $ruleBar->name = "bar";
     $syntax->addChild($ruleBar);
     $tester = new Validator();
     $syntax->accept($tester);
     $this->assertEquals(array("syntax" => array("meta" => "foo meta", "title" => "bar title", "rule" => array("foo" => array(), "bar" => array()))), $tester->getRepresentative());
 }