http://www.mediawiki.org/wiki/Special:Code/MediaWiki/65412

Revision: 65412
Author:   than4213
Date:     2010-04-21 19:40:00 +0000 (Wed, 21 Apr 2010)

Log Message:
-----------
Rename extension to ParserWiki.  Added test case to see if my parser language 
can parse itself.

Added Paths:
-----------
    trunk/extensions/ParserWiki/
    trunk/extensions/ParserWiki/ParseEngine.php
    trunk/extensions/ParserWiki/ParserWiki.php
    trunk/extensions/ParserWiki/parserTests.txt

Removed Paths:
-------------
    trunk/extensions/ParseEngine/

Added: trunk/extensions/ParserWiki/ParseEngine.php
===================================================================
--- trunk/extensions/ParserWiki/ParseEngine.php                         (rev 0)
+++ trunk/extensions/ParserWiki/ParseEngine.php 2010-04-21 19:40:00 UTC (rev 
65412)
@@ -0,0 +1,233 @@
+<?php
+/**
+ * Acts as the primary interface between the world and the parser.
+ * mStartRule - the first rule to use while parsing
+ * mRules - The list of rules to use while parsing
+ * mDom - Used to create Dom objects and get's returned at the end of parsing
+ * mIter - Keeps track of how many times the parser recurses to stop endless 
loops
+ */
+class ParseEngine {
+       const maxIter = 4096;
+       private $mGrammar;
+
+       function __construct($grammar) {
+               $xpath = new DOMXPath($grammar);
+               $rootRules = $xpath->query("/grammar/parseObject | 
/grammar/rule/parseObject");
+               foreach ($rootRules as $child) {
+                       $this->pushTags($child, NULL);
+               }
+               $this->mGrammar = $grammar;
+       }
+
+       function parse($text) {
+               wfDebugLog("ParseEngine", "==========Start Parse 
Engine==========\n");
+               $xpath = new DOMXPath($this->mGrammar);
+               $rootAssign = $xpath->query("/grammar/parseObject")->item(0);
+               $doc = new DOMDocument();
+               if (! $this->parseRec($rootAssign, "", "", $iter, $text, $doc)) 
{
+                       $doc = NULL;
+               }
+               return $doc;
+       }
+
+       static function unparse($inNodes) {
+               $retStr = "";
+               foreach ($inNodes as $child) {
+                       if ($child instanceof DOMText) {
+                               $retStr .= $child->data;
+                       } else {
+                               $retStr .= $child->getAttribute("tag") . 
self::unparse($child->childNodes);
+                       }
+               }
+               return $retStr;
+       }
+
+       private function parseRec($rule, $replaceStr, $saveTags, &$iter, 
&$text, &$outNode) {
+               $iter ++;
+               if ($iter > ParseEngine::maxIter) {
+                       throw new MWException("Parser iterated too many times. 
Probable loop in grammar.");
+               }
+               $rule = $rule->firstChild;
+               if ($rule->nodeName == "assignment" || $rule->nodeName == 
"reference" || $rule->nodeName == "text") {
+                       $saveTags = str_replace("~r", preg_quote($replaceStr, 
"/"), $saveTags);
+                       $newTags = $rule->getAttribute("saveTags");
+                       if ($saveTags == "") {
+                               $saveTags = $newTags;
+                       } elseif ($newTags != "") {
+                               $saveTags .= "|" . $newTags;
+                       }
+               }
+               $dom = $outNode->ownerDocument == NULL ? $outNode : 
$outNode->ownerDocument;
+               $xpath = new DOMXPath($rule->ownerDocument);
+               $childRules = $xpath->query("parseObject", $rule);
+               $retCode = TRUE;
+               if ($rule->nodeName == "assignment") {
+                       $patterns = $xpath->query("pattern", $rule);
+                       $tag = "";
+                       if ($patterns->length > 0) {
+                               $pattern = str_replace("~r", $replaceStr, 
$patterns->item(0)->getAttribute("tag"));
+                               $retCode = preg_match("/^$pattern/s", $text, 
$matches);
+                               if ($retCode) {
+                                       $tag = $matches[0];
+                                       if (isset($matches[1])) {
+                                               $replaceStr = $matches[1];
+                                       }
+                               }
+                       }
+                       if ($retCode) {
+                               $newText = $text;
+                               $newElement = 
$dom->createElement($rule->getAttribute("tag"));
+                               if ($tag != "") {
+                                       $newText = substr($newText, 
strlen($tag));
+                                       $newElement->setAttribute("tag", $tag);
+                               }
+                               $retCode = $childRules->length <= 0 || 
$this->parseRec($childRules->item(0), $replaceStr, $saveTags, $iter, $newText, 
$newElement);
+                               if ($retCode) {
+                                       $outNode->appendChild($newElement);
+                                       $text = $newText;
+                               }
+                       }
+               } elseif ($rule->nodeName == "sequence") {
+                       $pushInd = $rule->getAttribute("pushInd");
+                       if ($pushInd > 0) {
+                               $saveText = $text;
+                               $saveNode = $outNode->cloneNode(TRUE);
+                       }
+                       foreach ($childRules as $i => $child) {
+                               $pushTags = $i >= $pushInd ? $saveTags : "";
+                               $retCode = $this->parseRec($child, $replaceStr, 
$pushTags, $iter, $text, $outNode);
+                               if (! $retCode) {
+                                       if ($i > 0) {
+                                               $text = $saveText;
+                                               $outNode = $saveNode;
+                                       }
+                                       break;
+                               }
+                       }
+               } elseif ($rule->nodeName == "choice") {
+                       foreach ($childRules as $child) {
+                               $retCode = $this->parseRec($child, $replaceStr, 
$saveTags, $iter, $text, $outNode);
+                               if ($retCode) {
+                                       break;
+                               }
+                       }
+                       $retCode |= $rule->hasAttribute("tag");
+               } elseif ($rule->nodeName == "reference") {
+                       $childRule = $rule->getAttribute("tag");
+                       wfDebugLog("ParseEngine", "Entering $childRule\n");
+                       $varNode = $xpath->query("pattern", $rule);
+                       if ($varNode->length > 0) {
+                               $replaceStr = str_replace("~r", $replaceStr, 
$varNode->item(0)->getAttribute("tag"));
+                       }
+                       $refRule = 
$xpath->query("/grammar/ru...@tag='$childRule']/parseObject")->item(0);
+                       $retCode = $this->parseRec($refRule, $replaceStr, 
$saveTags, $iter, $text, $outNode);
+                       wfDebugLog("ParseEngine", "Exiting $childRule, Return 
Code - $retCode\n");
+                       wfDebugLog("ParseEngine", "text - $text\n");
+               } elseif ($rule->nodeName == "text") {
+                       $tagSearch = $rule->getAttribute("childTags");
+                       if ($tagSearch == "") {
+                               $tagSearch = $saveTags;
+                       } elseif ($saveTags != "") {
+                               $tagSearch .= "|" . $saveTags;
+                       }
+                       $childNode = $childRules->length <= 0 ? NULL : 
$childRules->item(0);
+                       while ($text != "" && ($saveTags == "" || ! 
preg_match("/^($saveTags)/s", $text))) {
+                               $offset = $childNode != NULL && 
$this->parseRec($childNode, $replaceStr, "", $iter, $text, $outNode) ? 0 : 1;
+                               if (preg_match("/$tagSearch/s", $text, 
$matches, PREG_OFFSET_CAPTURE, $offset)) {
+                                       if ($matches[0][1] > 0) {
+                                               
$outNode->appendChild($dom->createTextNode(substr($text, 0, $matches[0][1])));
+                                               $text = substr($text, 
$matches[0][1]);
+                                       }
+                               } else {
+                                       
$outNode->appendChild($dom->createTextNode($text));
+                                       $text = "";
+                               }
+                       }
+               }
+               return $retCode;
+       }
+
+       private function pushTags($rule, $tagStr) {
+               $rule = $rule->firstChild;
+               $xpath = new DOMXPath($rule->ownerDocument);
+               $childRules = $xpath->query("parseObject", $rule);
+               if ($rule->nodeName == "sequence") {
+                       $pushInd = 0;
+                       for ($i = $childRules->length - 1; $i >= 0; $i --) {
+                               $this->pushTags($childRules->item($i), $tagStr);
+                               if ($i > 0) {
+                                       if 
($this->pullTags($childRules->item($i), $iter, $childTag)) {
+                                               if ($tagStr == "") {
+                                                       $tagStr = $childTag;
+                                               } elseif ($childTag != "") {
+                                                       $tagStr .= "|" . 
$childTag;
+                                               }
+                                       } else {
+                                               if ($pushInd < $i) {
+                                                       $pushInd = $i;
+                                               }
+                                               $tagStr = $childTag;
+                                       }
+                               }
+                       }
+                       $rule->setAttribute("pushInd", $pushInd);
+               } else {
+                       if ($rule->nodeName != "choice") {
+                               $rule->setAttribute("saveTags", $tagStr);
+                               $tagStr = NULL;
+                               if ($rule->nodeName == "text") {
+                                       $childTags = "";
+                                       foreach ($childRules as $child) {
+                                               if ($childTags != "") {
+                                                       $childTags .= "|";
+                                               }
+                                               $this->pullTags($child, $iter, 
$childTag);
+                                               $childTags .= $childTag;
+                                       }
+                                       $rule->setAttribute("childTags", 
$childTags);
+                               }
+                       }
+                       foreach ($childRules as $child) {
+                               $this->pushTags($child, $tagStr);
+                       }
+               }
+       }
+
+       private function pullTags($rule, &$iter, &$childTags) {
+               $iter ++;
+               if ($iter > ParseEngine::maxIter) {
+                       throw new MWException("Collecter iterated too many 
times. Probable loop in grammar.");
+               }
+               $rule = $rule->firstChild;
+               $xpath = new DOMXPath($rule->ownerDocument);
+               $childTags = "";
+               $failSafe = TRUE;
+               if ($rule->nodeName == "assignment") {
+                       $patterns = $xpath->query("pattern", $rule);
+                       if ($patterns->length > 0) {
+                               $childTags = 
$patterns->item(0)->getAttribute("tag");
+                       }
+                       $failSafe = FALSE;
+               } elseif ($rule->nodeName == "choice" || $rule->nodeName == 
"sequence") {
+                       $childRules = $xpath->query("parseObject", $rule);
+                       $failSafe = $rule->nodeName == "sequence";
+                       foreach ($childRules as $child) {
+                               $failSafe = $this->pullTags($child, $iter, 
$newTags);
+                               if ($childTags == "") {
+                                       $childTags = $newTags;
+                               } elseif ($newTags != "") {
+                                       $childTags .= "|" . $newTags;
+                               }
+                               if (($failSafe && $rule->nodeName == "choice") 
|| (! $failSafe && $rule->nodeName == "sequence")) {
+                                       break;
+                               }
+                       }
+                       $failSafe |= $rule->hasAttribute("tag");
+               } elseif ($rule->nodeName == "reference") {
+                       $refRule = 
$xpath->query("/grammar/ru...@tag='{$rule->getAttribute("tag")}']/parseObject")->item(0);
+                       $failSafe = $this->pullTags($refRule, $iter, 
$childTags);
+               }
+               return $failSafe;
+       }
+}
+


Property changes on: trunk/extensions/ParserWiki/ParseEngine.php
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/extensions/ParserWiki/ParserWiki.php
===================================================================
--- trunk/extensions/ParserWiki/ParserWiki.php                          (rev 0)
+++ trunk/extensions/ParserWiki/ParserWiki.php  2010-04-21 19:40:00 UTC (rev 
65412)
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Allows people to define a grammar in a wiki then use that grammar to input 
information to the same wiki
+ * @ingroup Extensions
+ * @author Nathanael Thompson <[email protected]>
+ * @copyright Copyright © 2010 Nathanael Thompson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+if ( !defined( "MEDIAWIKI" ) ) {
+       die( "This is not a valid entry point.\n" );
+}
+
+$wgExtensionCredits["other"][] = array(
+       "path" => __FILE__,
+       "name" => "ParserWiki",
+       "author" => "Nathanael Thompson",
+       "url" => "http://www.mediawiki.org/wiki/Extension:ParserWiki";,
+       "version" => "1.0",
+       "descriptionmsg" => "parserwiki-desc",
+);
+
+$wgAutoloadClasses["ParseEngine"] = dirname( __FILE__ ) . "/ParseEngine.php";
+
+$wgTheParserWiki = new ParserWiki();
+$wgHooks["ParserBeforeStrip"][] = array($wgTheParserWiki, "callFromParse");
+
+define ( "NS_GRAMMAR" , 91628);
+define ( "NS_GRAMMAR_TALK" , 91629);
+$wgExtraNamespaces[NS_GRAMMAR] = "Grammar";
+$wgExtraNamespaces[NS_GRAMMAR_TALK] = "Grammar_talk";
+
+class ParserWiki {
+       private $mEngines;
+
+       function __construct() {
+               $this->mEngines = array();
+       }
+
+       function callFromParse($unUsed, &$text) {
+               global $wgParserWikiGrammar;
+               $engine = $this->mEngines[$wgParserWikiGrammar];
+               if ($engine == NULL) {
+                       $revision = 
Revision::newFromTitle(Title::newFromText($wgParserWikiGrammar, NS_GRAMMAR));
+                       $grammar = new DOMDocument();
+                       if ($revision == NULL || ! 
$grammar->loadXML($revision->getText(), LIBXML_NOBLANKS)) {
+                               return TRUE;
+                       }
+                       $engine = new ParseEngine($grammar);
+                       $this->mEngines[$wgParserWikiGrammar] = $engine;
+               }
+               $parseTree = $engine->parse($text);
+               if ($parseTree == NULL) {
+                       return TRUE;
+               }
+               $text = $parseTree->saveXML();
+               return FALSE;
+       }
+}


Property changes on: trunk/extensions/ParserWiki/ParserWiki.php
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/extensions/ParserWiki/parserTests.txt
===================================================================
--- trunk/extensions/ParserWiki/parserTests.txt                         (rev 0)
+++ trunk/extensions/ParserWiki/parserTests.txt 2010-04-21 19:40:00 UTC (rev 
65412)
@@ -0,0 +1,37 @@
+# Tests for the ParseEngine using maintenance/parserTests.php
+# Please make sure that the input parser XML is an exact duplicate of the test 
result
+
+!!article 
+Grammar:WikiGrammar1_0
+!!text
+<grammar><tag tag=";; grammar for WikiGrammar v1.0&#10;;; only one parseObject 
at base level for the start rule / root 
node&#10;&lt;"/><parseObject><assignment tag="grammar"><tag tag=" 
["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="parseObject"/></parseObject><tag tag=" -&gt;"/><parseObject><reference 
tag="ruleList"/></parseObject><tag tag=" -&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern/><tag 
tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/></assignment></parseObject><tag tag="&gt;"/><tag tag="&#10;;; ignore 
whitespace, comments lines starting in # and tags&#10;"/><rule tag="tag"><tag 
tag=" ="/><tag tag=" &lt;"/><parseObject><assignment tag="tag"><tag tag=" 
/"/><pattern tag="(?:\s+|;;[^\n]*)*~r"/><tag 
tag="/"/></assignment></parseObject><tag tag="&gt;"/></rule><tag 
tag="&#10;"/><rule tag="pattern"><tag tag=" ="/><tag tag=" 
["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="\/"/><tag 
tag="/"/></reference></parseObject><tag tag=" &lt;"/><parseObject><assignment 
tag="pattern"><tag tag=" /"/><pattern tag="(?:[^\\\/]|\\.)*"/><tag 
tag="/"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
&lt;"/><parseObject><assignment tag="tag"><tag tag=" /"/><pattern 
tag="\/"/><tag tag="/"/></assignment></parseObject><tag 
tag="&gt;"/></sequence></parseObject><tag tag="]"/></rule><tag tag="&#10;;; 
This works a lot like polymorphism -&gt; new feature&#10;"/><rule 
tag="parseObject"><tag tag=" ="/><tag tag=" ("/><parseObject><choice><tag 
tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="-&gt;"/><tag tag="/"/></reference></parseObject><tag 
tag=" &lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="reference"><tag tag=" /"/><pattern 
tag="\w+"/><tag tag="/"/><tag tag=" ("/><parseObject><choice tag="?"><tag 
tag="["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="="/><tag 
tag="/"/></reference></parseObject><tag tag=" -&gt;"/><parseObject><reference 
tag="pattern"/></parseObject></sequence></parseObject><tag 
tag="]"/></choice></parseObject><tag tag=")"/></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag 
tag="&gt;"/></sequence></parseObject><tag tag="]"/><tag 
tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="\("/><tag tag="/"/></reference></parseObject><tag tag=" 
&lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="choice"><tag tag=" /"/><pattern 
tag="\??"/><tag tag="/"/><tag tag=" -&gt;"/><parseObject><reference 
tag="objectList"/></parseObject></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern 
tag="\)"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/><tag tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="\["/><tag tag="/"/></reference></parseObject><tag tag=" 
&lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="sequence"><tag tag=" 
-&gt;"/><parseObject><reference 
tag="objectList"/></parseObject></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern 
tag="\]"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/><tag tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="$"/><tag tag="/"/></reference></parseObject><tag tag=" 
&lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="text"><tag tag=" ("/><parseObject><choice 
tag="?"><tag tag="-&gt;"/><parseObject><reference 
tag="parseObject"/></parseObject></choice></parseObject><tag 
tag=")"/></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern 
tag="$"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/><tag tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="&lt;"/><tag tag="/"/></reference></parseObject><tag 
tag=" &lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="assignment"><tag tag=" /"/><pattern 
tag="\w+"/><tag tag="/"/><tag tag=" ["/><parseObject><sequence><tag 
tag="&#10;&#9;&#9;("/><parseObject><choice tag="?"><tag 
tag="-&gt;"/><parseObject><reference 
tag="pattern"/></parseObject></choice></parseObject><tag tag=")"/><tag 
tag="&#10;&#9;&#9;("/><parseObject><choice tag="?"><tag 
tag="-&gt;"/><parseObject><reference 
tag="parseObject"/></parseObject></choice></parseObject><tag 
tag=")"/></sequence></parseObject><tag 
tag="&#10;&#9;]"/></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern 
tag="&gt;"/><tag 
tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/></choice></parseObject><tag tag="&#10;)"/></rule><tag tag="&#10;;; 
Lists work a lot like regEx +'s -&gt; syntactic sugar&#10;"/><rule 
tag="objectList"><tag tag=" ="/><tag tag=" ("/><parseObject><choice 
tag="?"><tag tag="["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="parseObject"/></parseObject><tag 
tag=" -&gt;"/><parseObject><reference 
tag="objectList"/></parseObject></sequence></parseObject><tag 
tag="]"/></choice></parseObject><tag tag=")"/></rule><tag tag="&#10;"/><rule 
tag="ruleList"><tag tag=" ="/><tag tag=" ("/><parseObject><choice tag="?"><tag 
tag="["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern/><tag 
tag="/"/></reference></parseObject><tag tag=" &lt;"/><parseObject><assignment 
tag="rule"><tag tag=" /"/><pattern tag="\w+"/><tag tag="/"/><tag tag=" 
["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="="/><tag 
tag="/"/></reference></parseObject><tag tag=" -&gt;"/><parseObject><reference 
tag="parseObject"/></parseObject></sequence></parseObject><tag 
tag="]"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference 
tag="ruleList"/></parseObject></sequence></parseObject><tag 
tag="]"/></choice></parseObject><tag tag=")"/></rule><tag/></grammar>
+!!endarticle
+
+!! test
+Generic Test
+!! input
+;; grammar for WikiGrammar v1.0
+;; only one parseObject at base level for the start rule / root node
+<grammar [->parseObject ->ruleList ->tag=//]>
+;; ignore whitespace, comments lines starting in # and tags
+tag = <tag /(?:\s+|;;[^\n]*)*~r/>
+pattern = [->tag=/\// <pattern /(?:[^\\\/]|\\.)*/> <tag /\//>]
+;; This works a lot like polymorphism -> new feature
+parseObject = (
+       [->tag=/->/ <parseObject <reference /\w+/ (?[->tag=/=/ ->pattern])>>]
+       [->tag=/\(/ <parseObject <choice /\??/ ->objectList>> ->tag=/\)/]
+       [->tag=/\[/ <parseObject <sequence ->objectList>> ->tag=/\]/]
+       [->tag=/$/ <parseObject <text (?->parseObject)>> ->tag=/$/]
+       [->tag=/</ <parseObject <assignment /\w+/ [
+               (?->pattern)
+               (?->parseObject)
+       ]>> ->tag=/>/]
+)
+;; Lists work a lot like regEx +'s -> syntactic sugar
+objectList = (?[->parseObject ->objectList])
+ruleList = (?[->tag=// <rule /\w+/ [->tag=/=/ ->parseObject]> ->ruleList])
+!! result
+<grammar><tag tag=";; grammar for WikiGrammar v1.0&#10;;; only one parseObject 
at base level for the start rule / root 
node&#10;&lt;"/><parseObject><assignment tag="grammar"><tag tag=" 
["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="parseObject"/></parseObject><tag tag=" -&gt;"/><parseObject><reference 
tag="ruleList"/></parseObject><tag tag=" -&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern/><tag 
tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/></assignment></parseObject><tag tag="&gt;"/><tag tag="&#10;;; ignore 
whitespace, comments lines starting in # and tags&#10;"/><rule tag="tag"><tag 
tag=" ="/><tag tag=" &lt;"/><parseObject><assignment tag="tag"><tag tag=" 
/"/><pattern tag="(?:\s+|;;[^\n]*)*~r"/><tag 
tag="/"/></assignment></parseObject><tag tag="&gt;"/></rule><tag 
tag="&#10;"/><rule tag="pattern"><tag tag=" ="/><tag tag=" 
["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="\/"/><tag 
tag="/"/></reference></parseObject><tag tag=" &lt;"/><parseObject><assignment 
tag="pattern"><tag tag=" /"/><pattern tag="(?:[^\\\/]|\\.)*"/><tag 
tag="/"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
&lt;"/><parseObject><assignment tag="tag"><tag tag=" /"/><pattern 
tag="\/"/><tag tag="/"/></assignment></parseObject><tag 
tag="&gt;"/></sequence></parseObject><tag tag="]"/></rule><tag tag="&#10;;; 
This works a lot like polymorphism -&gt; new feature&#10;"/><rule 
tag="parseObject"><tag tag=" ="/><tag tag=" ("/><parseObject><choice><tag 
tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="-&gt;"/><tag tag="/"/></reference></parseObject><tag 
tag=" &lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="reference"><tag tag=" /"/><pattern 
tag="\w+"/><tag tag="/"/><tag tag=" ("/><parseObject><choice tag="?"><tag 
tag="["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="="/><tag 
tag="/"/></reference></parseObject><tag tag=" -&gt;"/><parseObject><reference 
tag="pattern"/></parseObject></sequence></parseObject><tag 
tag="]"/></choice></parseObject><tag tag=")"/></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag 
tag="&gt;"/></sequence></parseObject><tag tag="]"/><tag 
tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="\("/><tag tag="/"/></reference></parseObject><tag tag=" 
&lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="choice"><tag tag=" /"/><pattern 
tag="\??"/><tag tag="/"/><tag tag=" -&gt;"/><parseObject><reference 
tag="objectList"/></parseObject></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern 
tag="\)"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/><tag tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="\["/><tag tag="/"/></reference></parseObject><tag tag=" 
&lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="sequence"><tag tag=" 
-&gt;"/><parseObject><reference 
tag="objectList"/></parseObject></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern 
tag="\]"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/><tag tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="$"/><tag tag="/"/></reference></parseObject><tag tag=" 
&lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="text"><tag tag=" ("/><parseObject><choice 
tag="?"><tag tag="-&gt;"/><parseObject><reference 
tag="parseObject"/></parseObject></choice></parseObject><tag 
tag=")"/></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern 
tag="$"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/><tag tag="&#10;&#9;["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag 
tag="/"/><pattern tag="&lt;"/><tag tag="/"/></reference></parseObject><tag 
tag=" &lt;"/><parseObject><assignment tag="parseObject"><tag tag=" 
&lt;"/><parseObject><assignment tag="assignment"><tag tag=" /"/><pattern 
tag="\w+"/><tag tag="/"/><tag tag=" ["/><parseObject><sequence><tag 
tag="&#10;&#9;&#9;("/><parseObject><choice tag="?"><tag 
tag="-&gt;"/><parseObject><reference 
tag="pattern"/></parseObject></choice></parseObject><tag tag=")"/><tag 
tag="&#10;&#9;&#9;("/><parseObject><choice tag="?"><tag 
tag="-&gt;"/><parseObject><reference 
tag="parseObject"/></parseObject></choice></parseObject><tag 
tag=")"/></sequence></parseObject><tag 
tag="&#10;&#9;]"/></assignment></parseObject><tag 
tag="&gt;"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern 
tag="&gt;"/><tag 
tag="/"/></reference></parseObject></sequence></parseObject><tag 
tag="]"/></choice></parseObject><tag tag="&#10;)"/></rule><tag tag="&#10;;; 
Lists work a lot like regEx +'s -&gt; syntactic sugar&#10;"/><rule 
tag="objectList"><tag tag=" ="/><tag tag=" ("/><parseObject><choice 
tag="?"><tag tag="["/><parseObject><sequence><tag 
tag="-&gt;"/><parseObject><reference tag="parseObject"/></parseObject><tag 
tag=" -&gt;"/><parseObject><reference 
tag="objectList"/></parseObject></sequence></parseObject><tag 
tag="]"/></choice></parseObject><tag tag=")"/></rule><tag tag="&#10;"/><rule 
tag="ruleList"><tag tag=" ="/><tag tag=" ("/><parseObject><choice tag="?"><tag 
tag="["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern/><tag 
tag="/"/></reference></parseObject><tag tag=" &lt;"/><parseObject><assignment 
tag="rule"><tag tag=" /"/><pattern tag="\w+"/><tag tag="/"/><tag tag=" 
["/><parseObject><sequence><tag tag="-&gt;"/><parseObject><reference 
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="="/><tag 
tag="/"/></reference></parseObject><tag tag=" -&gt;"/><parseObject><reference 
tag="parseObject"/></parseObject></sequence></parseObject><tag 
tag="]"/></assignment></parseObject><tag tag="&gt;"/><tag tag=" 
-&gt;"/><parseObject><reference 
tag="ruleList"/></parseObject></sequence></parseObject><tag 
tag="]"/></choice></parseObject><tag tag=")"/></rule><tag/></grammar>
+
+!! end
+


Property changes on: trunk/extensions/ParserWiki/parserTests.txt
___________________________________________________________________
Added: svn:eol-style
   + native



_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to