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 ;; only one parseObject
at base level for the start rule / root
node <"/><parseObject><assignment tag="grammar"><tag tag="
["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="parseObject"/></parseObject><tag tag=" ->"/><parseObject><reference
tag="ruleList"/></parseObject><tag tag=" ->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern/><tag
tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/></assignment></parseObject><tag tag=">"/><tag tag=" ;; ignore
whitespace, comments lines starting in # and tags "/><rule tag="tag"><tag
tag=" ="/><tag tag=" <"/><parseObject><assignment tag="tag"><tag tag="
/"/><pattern tag="(?:\s+|;;[^\n]*)*~r"/><tag
tag="/"/></assignment></parseObject><tag tag=">"/></rule><tag
tag=" "/><rule tag="pattern"><tag tag=" ="/><tag tag="
["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="\/"/><tag
tag="/"/></reference></parseObject><tag tag=" <"/><parseObject><assignment
tag="pattern"><tag tag=" /"/><pattern tag="(?:[^\\\/]|\\.)*"/><tag
tag="/"/></assignment></parseObject><tag tag=">"/><tag tag="
<"/><parseObject><assignment tag="tag"><tag tag=" /"/><pattern
tag="\/"/><tag tag="/"/></assignment></parseObject><tag
tag=">"/></sequence></parseObject><tag tag="]"/></rule><tag tag=" ;;
This works a lot like polymorphism -> new feature "/><rule
tag="parseObject"><tag tag=" ="/><tag tag=" ("/><parseObject><choice><tag
tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="->"/><tag tag="/"/></reference></parseObject><tag
tag=" <"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="reference"><tag tag=" /"/><pattern
tag="\w+"/><tag tag="/"/><tag tag=" ("/><parseObject><choice tag="?"><tag
tag="["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="="/><tag
tag="/"/></reference></parseObject><tag tag=" ->"/><parseObject><reference
tag="pattern"/></parseObject></sequence></parseObject><tag
tag="]"/></choice></parseObject><tag tag=")"/></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag
tag=">"/></sequence></parseObject><tag tag="]"/><tag
tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="\("/><tag tag="/"/></reference></parseObject><tag tag="
<"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="choice"><tag tag=" /"/><pattern
tag="\??"/><tag tag="/"/><tag tag=" ->"/><parseObject><reference
tag="objectList"/></parseObject></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern
tag="\)"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/><tag tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="\["/><tag tag="/"/></reference></parseObject><tag tag="
<"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="sequence"><tag tag="
->"/><parseObject><reference
tag="objectList"/></parseObject></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern
tag="\]"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/><tag tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="$"/><tag tag="/"/></reference></parseObject><tag tag="
<"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="text"><tag tag=" ("/><parseObject><choice
tag="?"><tag tag="->"/><parseObject><reference
tag="parseObject"/></parseObject></choice></parseObject><tag
tag=")"/></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern
tag="$"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/><tag tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="<"/><tag tag="/"/></reference></parseObject><tag
tag=" <"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="assignment"><tag tag=" /"/><pattern
tag="\w+"/><tag tag="/"/><tag tag=" ["/><parseObject><sequence><tag
tag=" 		("/><parseObject><choice tag="?"><tag
tag="->"/><parseObject><reference
tag="pattern"/></parseObject></choice></parseObject><tag tag=")"/><tag
tag=" 		("/><parseObject><choice tag="?"><tag
tag="->"/><parseObject><reference
tag="parseObject"/></parseObject></choice></parseObject><tag
tag=")"/></sequence></parseObject><tag
tag=" 	]"/></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern
tag=">"/><tag
tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/></choice></parseObject><tag tag=" )"/></rule><tag tag=" ;;
Lists work a lot like regEx +'s -> syntactic sugar "/><rule
tag="objectList"><tag tag=" ="/><tag tag=" ("/><parseObject><choice
tag="?"><tag tag="["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="parseObject"/></parseObject><tag
tag=" ->"/><parseObject><reference
tag="objectList"/></parseObject></sequence></parseObject><tag
tag="]"/></choice></parseObject><tag tag=")"/></rule><tag tag=" "/><rule
tag="ruleList"><tag tag=" ="/><tag tag=" ("/><parseObject><choice tag="?"><tag
tag="["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern/><tag
tag="/"/></reference></parseObject><tag tag=" <"/><parseObject><assignment
tag="rule"><tag tag=" /"/><pattern tag="\w+"/><tag tag="/"/><tag tag="
["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="="/><tag
tag="/"/></reference></parseObject><tag tag=" ->"/><parseObject><reference
tag="parseObject"/></parseObject></sequence></parseObject><tag
tag="]"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><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 ;; only one parseObject
at base level for the start rule / root
node <"/><parseObject><assignment tag="grammar"><tag tag="
["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="parseObject"/></parseObject><tag tag=" ->"/><parseObject><reference
tag="ruleList"/></parseObject><tag tag=" ->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern/><tag
tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/></assignment></parseObject><tag tag=">"/><tag tag=" ;; ignore
whitespace, comments lines starting in # and tags "/><rule tag="tag"><tag
tag=" ="/><tag tag=" <"/><parseObject><assignment tag="tag"><tag tag="
/"/><pattern tag="(?:\s+|;;[^\n]*)*~r"/><tag
tag="/"/></assignment></parseObject><tag tag=">"/></rule><tag
tag=" "/><rule tag="pattern"><tag tag=" ="/><tag tag="
["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="\/"/><tag
tag="/"/></reference></parseObject><tag tag=" <"/><parseObject><assignment
tag="pattern"><tag tag=" /"/><pattern tag="(?:[^\\\/]|\\.)*"/><tag
tag="/"/></assignment></parseObject><tag tag=">"/><tag tag="
<"/><parseObject><assignment tag="tag"><tag tag=" /"/><pattern
tag="\/"/><tag tag="/"/></assignment></parseObject><tag
tag=">"/></sequence></parseObject><tag tag="]"/></rule><tag tag=" ;;
This works a lot like polymorphism -> new feature "/><rule
tag="parseObject"><tag tag=" ="/><tag tag=" ("/><parseObject><choice><tag
tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="->"/><tag tag="/"/></reference></parseObject><tag
tag=" <"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="reference"><tag tag=" /"/><pattern
tag="\w+"/><tag tag="/"/><tag tag=" ("/><parseObject><choice tag="?"><tag
tag="["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="="/><tag
tag="/"/></reference></parseObject><tag tag=" ->"/><parseObject><reference
tag="pattern"/></parseObject></sequence></parseObject><tag
tag="]"/></choice></parseObject><tag tag=")"/></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag
tag=">"/></sequence></parseObject><tag tag="]"/><tag
tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="\("/><tag tag="/"/></reference></parseObject><tag tag="
<"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="choice"><tag tag=" /"/><pattern
tag="\??"/><tag tag="/"/><tag tag=" ->"/><parseObject><reference
tag="objectList"/></parseObject></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern
tag="\)"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/><tag tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="\["/><tag tag="/"/></reference></parseObject><tag tag="
<"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="sequence"><tag tag="
->"/><parseObject><reference
tag="objectList"/></parseObject></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern
tag="\]"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/><tag tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="$"/><tag tag="/"/></reference></parseObject><tag tag="
<"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="text"><tag tag=" ("/><parseObject><choice
tag="?"><tag tag="->"/><parseObject><reference
tag="parseObject"/></parseObject></choice></parseObject><tag
tag=")"/></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern
tag="$"/><tag tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/><tag tag=" 	["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="tag"><tag tag="="/><tag
tag="/"/><pattern tag="<"/><tag tag="/"/></reference></parseObject><tag
tag=" <"/><parseObject><assignment tag="parseObject"><tag tag="
<"/><parseObject><assignment tag="assignment"><tag tag=" /"/><pattern
tag="\w+"/><tag tag="/"/><tag tag=" ["/><parseObject><sequence><tag
tag=" 		("/><parseObject><choice tag="?"><tag
tag="->"/><parseObject><reference
tag="pattern"/></parseObject></choice></parseObject><tag tag=")"/><tag
tag=" 		("/><parseObject><choice tag="?"><tag
tag="->"/><parseObject><reference
tag="parseObject"/></parseObject></choice></parseObject><tag
tag=")"/></sequence></parseObject><tag
tag=" 	]"/></assignment></parseObject><tag
tag=">"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><parseObject><reference tag="tag"><tag tag="="/><tag tag="/"/><pattern
tag=">"/><tag
tag="/"/></reference></parseObject></sequence></parseObject><tag
tag="]"/></choice></parseObject><tag tag=" )"/></rule><tag tag=" ;;
Lists work a lot like regEx +'s -> syntactic sugar "/><rule
tag="objectList"><tag tag=" ="/><tag tag=" ("/><parseObject><choice
tag="?"><tag tag="["/><parseObject><sequence><tag
tag="->"/><parseObject><reference tag="parseObject"/></parseObject><tag
tag=" ->"/><parseObject><reference
tag="objectList"/></parseObject></sequence></parseObject><tag
tag="]"/></choice></parseObject><tag tag=")"/></rule><tag tag=" "/><rule
tag="ruleList"><tag tag=" ="/><tag tag=" ("/><parseObject><choice tag="?"><tag
tag="["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern/><tag
tag="/"/></reference></parseObject><tag tag=" <"/><parseObject><assignment
tag="rule"><tag tag=" /"/><pattern tag="\w+"/><tag tag="/"/><tag tag="
["/><parseObject><sequence><tag tag="->"/><parseObject><reference
tag="tag"><tag tag="="/><tag tag="/"/><pattern tag="="/><tag
tag="/"/></reference></parseObject><tag tag=" ->"/><parseObject><reference
tag="parseObject"/></parseObject></sequence></parseObject><tag
tag="]"/></assignment></parseObject><tag tag=">"/><tag tag="
->"/><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