コード例 #1
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());
 }
コード例 #2
0
ファイル: Parser.php プロジェクト: bgarrels/ebnf
 /**
  * Parses an EBNF factor:
  * factor = identifier
  *        | literal
  *        | "[" expression "]"
  *        | "(" expression ")"
  *        | "{" expression "}" .
  *
  * @param Node $parent Parent node.
  *
  * @throws SyntaxtException
  * @return DOMElement
  */
 private function parseFactor(Node $parent)
 {
     if ($this->scanner->currentToken()->isType(Token::IDENTIFIER)) {
         $identifier = $this->dom->createElement(Type::IDENTIFIER);
         $identifier->setAttribute('value', $this->scanner->currentToken()->getValue());
         $identifierNode = new Identifier($parent);
         $identifierNode->value = $this->scanner->currentToken()->getValue();
         return array($identifier, $identifierNode);
     }
     if ($this->scanner->currentToken()->isType(Token::LITERAL)) {
         /*if ($this->assertToken($this->scanner->peekToken(), Token::OPERATOR, "::")) {
               echo "range";
               $range = $this->dom->createElement(Type::RANGE);
               $range->setAttribute("from", $this->scanner->currentToken()->getValue(true));
               $this->scanner->nextToken(); // Omit ".." literal.
               $this->scanner->nextToken();
               $range->setAttribute("to", $this->scanner->currentToken()->getValue(true));
               return $range;
           }*/
         $literal = $this->dom->createElement(Type::TERMINAL);
         $literal->setAttribute('value', $this->scanner->currentToken()->getValue(true));
         $literalNode = new Terminal($parent);
         $literalNode->value = $this->scanner->currentToken()->getValue(true);
         return array($literal, $literalNode);
     }
     if ($this->assertToken($this->scanner->currentToken(), Token::OPERATOR, '(')) {
         $this->scanner->nextToken();
         $expression = $this->parseExpression($parent);
         if (!$this->assertToken($this->scanner->currentToken(), Token::OPERATOR, ')')) {
             $this->raiseError("Group must end with ')'");
         }
         return $expression;
     }
     if ($this->assertToken($this->scanner->currentToken(), Token::OPERATOR, '[')) {
         $option = $this->dom->createElement(Type::OPTION);
         $this->scanner->nextToken();
         $expression = $this->parseExpression($parent);
         $option->appendChild($expression[0]);
         $optionNode = new Option($parent);
         $optionNode->addChild($expression[1]);
         if (!$this->assertToken($this->scanner->currentToken(), Token::OPERATOR, ']')) {
             $this->raiseError("Option must end with ']'");
         }
         return array($option, $optionNode);
     }
     if ($this->assertToken($this->scanner->currentToken(), Token::OPERATOR, '{')) {
         $loop = $this->dom->createElement(Type::LOOP);
         $this->scanner->nextToken();
         $expression = $this->parseExpression($parent);
         $loop->appendChild($expression[0]);
         $loopNode = new Loop($parent);
         $loopNode->addChild($expression[1]);
         if (!$this->assertToken($this->scanner->currentToken(), Token::OPERATOR, '}')) {
             $this->raiseError("Loop must end with '}'");
         }
         return array($loop, $loopNode);
     }
     $this->raiseError("Factor expected");
 }