index 7ca1f9e3b25e349eb5a6f04db852aee016c1b742..345895231f2ec801cd55107e00153f68ec004406 100644 (file)
<?php
+
+#include_once 'class.tree.php';
+#include_once 'class.scanner.php';
+#include_once 'class.semantics.php';
+
class Parser
{
var $scanner_;
var $script_;
var $tree_;
var $status_;
+ var $registeredExtensions_;
var $status_text;
function parse($script)
{
+ $this->registeredExtensions_ = array();
$this->status_text = "incomplete";
$this->script_ = $script;
return strval($token);
}
+ function getPrevTokenText_($parent_id)
+ {
+ $childs = $this->tree_->getChilds($parent_id);
+
+ for ($i=count($childs); $i>0; --$i)
+ {
+ $prev = $this->tree_->getNode($childs[$i-1]);
+
+ if (in_array($prev['text'], array('{', '(', ',')))
+ {
+ // use command owning a block or list
+ $prev = $this->tree_->getNode($parent_id);
+ }
+
+ if ($prev['class'] != 'comment')
+ {
+ return $prev['text'];
+ }
+ }
+
+ $prev = $this->tree_->getNode($parent_id);
+ return $prev['text'];
+ }
+
+ function getSemantics_($token_text)
+ {
+ $semantics = new Semantics($token_text);
+ $semantics->setExtensionFuncs(array(&$this, 'registerExtension_'), array(&$this, 'isExtensionRegistered_'));
+ return $semantics;
+ }
+
+ function registerExtension_($extension)
+ {
+ array_push($this->registeredExtensions_, str_replace('"', '', $extension));
+ }
+
+ function isExtensionRegistered_($extension)
+ {
+ return (in_array($extension, $this->registeredExtensions_) ? true : false);
+ }
+
function success_($text = null)
{
if ($text != null)
return false;
}
+ /*******************************************************************************
+ * methods for recursive descent start below
+ */
+
function comment_($token)
{
$this->tree_->addChild($token);
// Get and check a command token
$token = $this->scanner_->nextToken();
- $semantics = new Semantics($token['text']);
- if ($semantics->unknown)
+ $semantics = $this->getSemantics_($token['text']);
+ if (!$semantics->validCommand($this->getPrevTokenText_($parent_id), $token['line']))
{
- return $this->error_('unknown command: '. $token['text']);
- }
-
- $last = $this->tree_->getLastNode($parent_id);
- if (!$semantics->validAfter($last['text']))
- {
- return $this->error_('"'. $token['text'] .'" may not appear after "'. $last['text'] .'"');
+ return $this->error_($semantics->message);
}
// Process eventual arguments
}
// Get semantics for this test command
- $this_semantics = new Semantics($token['text']);
- if ($this_semantics->unknown)
+ $this_semantics = $this->getSemantics_($token['text']);
+ if (!$this_semantics->validCommand($this->getPrevTokenText_($parent_id), $token['line']))
{
- return $this->error_('unknown test: '. $token['text']);
+ return $this->error_($this_semantics->message);
}
$this_node = $this->tree_->addChildTo($parent_id, $token);