diff --git a/core/oql/build.bash b/core/oql/build.bash
deleted file mode 100755
index cff08c526..000000000
--- a/core/oql/build.bash
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-php /usr/share/php/PHP/LexerGenerator/cli.php oql-lexer.plex
-php /usr/share/php/PHP/ParserGenerator/cli.php oql-parser.y
-
diff --git a/core/oql/build.cmd b/core/oql/build.cmd
deleted file mode 100644
index 2187cec66..000000000
--- a/core/oql/build.cmd
+++ /dev/null
@@ -1,3 +0,0 @@
-c:\itop\php-5.2.3\php.exe -q "C:\itop\PHP-5.2.3\PEAR\PHP\LexerGenerator\cli.php" oql-lexer.plex
-c:\itop\php-5.2.3\php.exe -q "C:\itop\PHP-5.2.3\PEAR\PHP\ParserGenerator\cli.php" oql-parser.y
-pause
\ No newline at end of file
diff --git a/core/oql/build/PHP/Lempar.php b/core/oql/build/PHP/Lempar.php
new file mode 100644
index 000000000..23ba300fd
--- /dev/null
+++ b/core/oql/build/PHP/Lempar.php
@@ -0,0 +1,937 @@
+string = $s->string;
+ $this->metadata = $s->metadata;
+ } else {
+ $this->string = (string) $s;
+ if ($m instanceof ParseyyToken) {
+ $this->metadata = $m->metadata;
+ } elseif (is_array($m)) {
+ $this->metadata = $m;
+ }
+ }
+ }
+
+ function __toString()
+ {
+ return $this->string;
+ }
+
+ function offsetExists($offset)
+ {
+ return isset($this->metadata[$offset]);
+ }
+
+ function offsetGet($offset)
+ {
+ return $this->metadata[$offset];
+ }
+
+ function offsetSet($offset, $value)
+ {
+ if ($offset === null) {
+ if (isset($value[0])) {
+ $x = ($value instanceof ParseyyToken) ?
+ $value->metadata : $value;
+ $this->metadata = array_merge($this->metadata, $x);
+ return;
+ }
+ $offset = count($this->metadata);
+ }
+ if ($value === null) {
+ return;
+ }
+ if ($value instanceof ParseyyToken) {
+ if ($value->metadata) {
+ $this->metadata[$offset] = $value->metadata;
+ }
+ } elseif ($value) {
+ $this->metadata[$offset] = $value;
+ }
+ }
+
+ function offsetUnset($offset)
+ {
+ unset($this->metadata[$offset]);
+ }
+}
+
+/** The following structure represents a single element of the
+ * parser's stack. Information stored includes:
+ *
+ * + The state number for the parser at this level of the stack.
+ *
+ * + The value of the token stored at this level of the stack.
+ * (In other words, the "major" token.)
+ *
+ * + The semantic value stored at this level of the stack. This is
+ * the information used by the action routines in the grammar.
+ * It is sometimes called the "minor" token.
+ */
+class ParseyyStackEntry
+{
+ public $stateno; /* The state-number */
+ public $major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ public $minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+
+// code external to the class is included here
+%%
+
+// declare_class is output here
+%%
+{
+/* First off, code is included which follows the "include_class" declaration
+** in the input file. */
+%%
+
+/* Next is all token values, as class constants
+*/
+/*
+** These constants (all generated automatically by the parser generator)
+** specify the various kinds of tokens (terminals) that the parser
+** understands.
+**
+** Each symbol here is a terminal symbol in the grammar.
+*/
+%%
+
+/* Next are that tables used to determine what action to take based on the
+** current state and lookahead token. These tables are used to implement
+** functions that take a state number and lookahead value and return an
+** action integer.
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N < self::YYNSTATE Shift N. That is,
+** push the lookahead
+** token onto the stack
+** and goto state N.
+**
+** self::YYNSTATE <= N < self::YYNSTATE+self::YYNRULE Reduce by rule N-YYNSTATE.
+**
+** N == self::YYNSTATE+self::YYNRULE A syntax error has occurred.
+**
+** N == self::YYNSTATE+self::YYNRULE+1 The parser accepts its
+** input. (and concludes parsing)
+**
+** N == self::YYNSTATE+self::YYNRULE+2 No such action. Denotes unused
+** slots in the yy_action[] table.
+**
+** The action table is constructed as a single large static array $yy_action.
+** Given state S and lookahead X, the action is computed as
+**
+** self::$yy_action[self::$yy_shift_ofst[S] + X ]
+**
+** If the index value self::$yy_shift_ofst[S]+X is out of range or if the value
+** self::$yy_lookahead[self::$yy_shift_ofst[S]+X] is not equal to X or if
+** self::$yy_shift_ofst[S] is equal to self::YY_SHIFT_USE_DFLT, it means that
+** the action is not in the table and that self::$yy_default[S] should be used instead.
+**
+** The formula above is for computing the action when the lookahead is
+** a terminal symbol. If the lookahead is a non-terminal (as occurs after
+** a reduce action) then the static $yy_reduce_ofst array is used in place of
+** the static $yy_shift_ofst array and self::YY_REDUCE_USE_DFLT is used in place of
+** self::YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** self::$yy_action A single table containing all actions.
+** self::$yy_lookahead A table containing the lookahead for each entry in
+** yy_action. Used to detect hash collisions.
+** self::$yy_shift_ofst For each state, the offset into self::$yy_action for
+** shifting terminals.
+** self::$yy_reduce_ofst For each state, the offset into self::$yy_action for
+** shifting non-terminals after a reduce.
+** self::$yy_default Default action for each state.
+*/
+%%
+/* The next thing included is series of defines which control
+** various aspects of the generated parser.
+** self::YYNOCODE is a number which corresponds
+** to no legal terminal or nonterminal number. This
+** number is used to fill in empty slots of the hash
+** table.
+** self::YYFALLBACK If defined, this indicates that one or more tokens
+** have fall-back values which should be used if the
+** original value of the token will not parse.
+** self::YYSTACKDEPTH is the maximum depth of the parser's stack.
+** self::YYNSTATE the combined number of states.
+** self::YYNRULE the number of rules in the grammar
+** self::YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+*/
+%%
+ /** The next table maps tokens into fallback tokens. If a construct
+ * like the following:
+ *
+ * %fallback ID X Y Z.
+ *
+ * appears in the grammer, then ID becomes a fallback token for X, Y,
+ * and Z. Whenever one of the tokens X, Y, or Z is input to the parser
+ * but it does not parse, the type of the token is changed to ID and
+ * the parse is retried before an error is thrown.
+ */
+ static public $yyFallback = array(
+%%
+ );
+ /**
+ * Turn parser tracing on by giving a stream to which to write the trace
+ * and a prompt to preface each trace message. Tracing is turned off
+ * by making either argument NULL
+ *
+ * Inputs:
+ *
+ * - A stream resource to which trace output should be written.
+ * If NULL, then tracing is turned off.
+ * - A prefix string written at the beginning of every
+ * line of trace output. If NULL, then tracing is
+ * turned off.
+ *
+ * Outputs:
+ *
+ * - None.
+ * @param resource
+ * @param string
+ */
+ static function Trace($TraceFILE, $zTracePrompt)
+ {
+ if (!$TraceFILE) {
+ $zTracePrompt = 0;
+ } elseif (!$zTracePrompt) {
+ $TraceFILE = 0;
+ }
+ self::$yyTraceFILE = $TraceFILE;
+ self::$yyTracePrompt = $zTracePrompt;
+ }
+
+ /**
+ * Output debug information to output (php://output stream)
+ */
+ static function PrintTrace()
+ {
+ self::$yyTraceFILE = fopen('php://output', 'w');
+ self::$yyTracePrompt = '';
+ }
+
+ /**
+ * @var resource|0
+ */
+ static public $yyTraceFILE;
+ /**
+ * String to prepend to debug output
+ * @var string|0
+ */
+ static public $yyTracePrompt;
+ /**
+ * @var int
+ */
+ public $yyidx = -1; /* Index of top element in stack */
+ /**
+ * @var int
+ */
+ public $yyerrcnt; /* Shifts left before out of the error */
+ /**
+ * @var array
+ */
+ public $yystack = array(); /* The parser's stack */
+
+ /**
+ * For tracing shifts, the names of all terminals and nonterminals
+ * are required. The following table supplies these names
+ * @var array
+ */
+ static public $yyTokenName = array(
+%%
+ );
+
+ /**
+ * For tracing reduce actions, the names of all rules are required.
+ * @var array
+ */
+ static public $yyRuleName = array(
+%%
+ );
+
+ /**
+ * This function returns the symbolic name associated with a token
+ * value.
+ * @param int
+ * @return string
+ */
+ function tokenName($tokenType)
+ {
+ if ($tokenType === 0) {
+ return 'End of Input';
+ }
+ if ($tokenType > 0 && $tokenType < count(self::$yyTokenName)) {
+ return self::$yyTokenName[$tokenType];
+ } else {
+ return "Unknown";
+ }
+ }
+
+ /**
+ * The following function deletes the value associated with a
+ * symbol. The symbol can be either a terminal or nonterminal.
+ * @param int the symbol code
+ * @param mixed the symbol's value
+ */
+ static function yy_destructor($yymajor, $yypminor)
+ {
+ switch ($yymajor) {
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
+ ** reduce or during error processing or when a parser is
+ ** being destroyed before it is finished parsing.
+ **
+ ** Note: during a reduce, the only symbols destroyed are those
+ ** which appear on the RHS of the rule, but which are not used
+ ** inside the C code.
+ */
+%%
+ default: break; /* If no destructor action specified: do nothing */
+ }
+ }
+
+ /**
+ * Pop the parser's stack once.
+ *
+ * If there is a destructor routine associated with the token which
+ * is popped from the stack, then call it.
+ *
+ * Return the major token number for the symbol popped.
+ * @param ParseyyParser
+ * @return int
+ */
+ function yy_pop_parser_stack()
+ {
+ if (!count($this->yystack)) {
+ return;
+ }
+ $yytos = array_pop($this->yystack);
+ if (self::$yyTraceFILE && $this->yyidx >= 0) {
+ fwrite(self::$yyTraceFILE,
+ self::$yyTracePrompt . 'Popping ' . self::$yyTokenName[$yytos->major] .
+ "\n");
+ }
+ $yymajor = $yytos->major;
+ self::yy_destructor($yymajor, $yytos->minor);
+ $this->yyidx--;
+ return $yymajor;
+ }
+
+ /**
+ * Deallocate and destroy a parser. Destructors are all called for
+ * all stack elements before shutting the parser down.
+ */
+ function __destruct()
+ {
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ if (is_resource(self::$yyTraceFILE)) {
+ fclose(self::$yyTraceFILE);
+ }
+ }
+
+ /**
+ * Based on the current state and parser stack, get a list of all
+ * possible lookahead tokens
+ * @param int
+ * @return array
+ */
+ function yy_get_expected_tokens($token)
+ {
+ $state = $this->yystack[$this->yyidx]->stateno;
+ $expected = self::$yyExpectedTokens[$state];
+ if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return $expected;
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return array_unique($expected);
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+ $nextstate = $this->yy_find_reduce_action(
+ $this->yystack[$this->yyidx]->stateno,
+ self::$yyRuleInfo[$yyruleno]['lhs']);
+ if (isset(self::$yyExpectedTokens[$nextstate])) {
+ $expected += self::$yyExpectedTokens[$nextstate];
+ if (in_array($token,
+ self::$yyExpectedTokens[$nextstate], true)) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return array_unique($expected);
+ }
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new ParseyyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return array_unique($expected);
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return $expected;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ return array_unique($expected);
+ }
+
+ /**
+ * Based on the parser state and current parser stack, determine whether
+ * the lookahead token is possible.
+ *
+ * The parser will convert the token value to an error token if not. This
+ * catches some unusual edge cases where the parser would fail.
+ * @param int
+ * @return bool
+ */
+ function yy_is_expected_token($token)
+ {
+ if ($token === 0) {
+ return true; // 0 is not part of this
+ }
+ $state = $this->yystack[$this->yyidx]->stateno;
+ if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return true;
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return true;
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+ $nextstate = $this->yy_find_reduce_action(
+ $this->yystack[$this->yyidx]->stateno,
+ self::$yyRuleInfo[$yyruleno]['lhs']);
+ if (isset(self::$yyExpectedTokens[$nextstate]) &&
+ in_array($token, self::$yyExpectedTokens[$nextstate], true)) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new ParseyyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ if (!$token) {
+ // end of input: this is valid
+ return true;
+ }
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return false;
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return true;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+
+ /**
+ * Find the appropriate action for a parser given the terminal
+ * look-ahead token iLookAhead.
+ *
+ * If the look-ahead token is YYNOCODE, then check to see if the action is
+ * independent of the look-ahead. If it is, return the action, otherwise
+ * return YY_NO_ACTION.
+ * @param int The look-ahead token
+ */
+ function yy_find_shift_action($iLookAhead)
+ {
+ $stateno = $this->yystack[$this->yyidx]->stateno;
+
+ /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */
+ if (!isset(self::$yy_shift_ofst[$stateno])) {
+ // no shift actions
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_shift_ofst[$stateno];
+ if ($i === self::YY_SHIFT_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+ self::$yy_lookahead[$i] != $iLookAhead) {
+ if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback)
+ && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) {
+ if (self::$yyTraceFILE) {
+ fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " .
+ self::$yyTokenName[$iLookAhead] . " => " .
+ self::$yyTokenName[$iFallback] . "\n");
+ }
+ return $this->yy_find_shift_action($iFallback);
+ }
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ /**
+ * Find the appropriate action for a parser given the non-terminal
+ * look-ahead token $iLookAhead.
+ *
+ * If the look-ahead token is self::YYNOCODE, then check to see if the action is
+ * independent of the look-ahead. If it is, return the action, otherwise
+ * return self::YY_NO_ACTION.
+ * @param int Current state number
+ * @param int The look-ahead token
+ */
+ function yy_find_reduce_action($stateno, $iLookAhead)
+ {
+ /* $stateno = $this->yystack[$this->yyidx]->stateno; */
+
+ if (!isset(self::$yy_reduce_ofst[$stateno])) {
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_reduce_ofst[$stateno];
+ if ($i == self::YY_REDUCE_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+ self::$yy_lookahead[$i] != $iLookAhead) {
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ /**
+ * Perform a shift action.
+ * @param int The new state to shift in
+ * @param int The major token to shift in
+ * @param mixed the minor token to shift in
+ */
+ function yy_shift($yyNewState, $yyMajor, $yypMinor)
+ {
+ $this->yyidx++;
+ if ($this->yyidx >= self::YYSTACKDEPTH) {
+ $this->yyidx--;
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will execute if the parser
+ ** stack ever overflows */
+%%
+ return;
+ }
+ $yytos = new ParseyyStackEntry;
+ $yytos->stateno = $yyNewState;
+ $yytos->major = $yyMajor;
+ $yytos->minor = $yypMinor;
+ array_push($this->yystack, $yytos);
+ if (self::$yyTraceFILE && $this->yyidx > 0) {
+ fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt,
+ $yyNewState);
+ fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt);
+ for ($i = 1; $i <= $this->yyidx; $i++) {
+ fprintf(self::$yyTraceFILE, " %s",
+ self::$yyTokenName[$this->yystack[$i]->major]);
+ }
+ fwrite(self::$yyTraceFILE,"\n");
+ }
+ }
+
+ /**
+ * The following table contains information about every rule that
+ * is used during the reduce.
+ *
+ *
+ * array(
+ * array(
+ * int $lhs; Symbol on the left-hand side of the rule
+ * int $nrhs; Number of right-hand side symbols in the rule
+ * ),...
+ * );
+ *
+ */
+ static public $yyRuleInfo = array(
+%%
+ );
+
+ /**
+ * The following table contains a mapping of reduce action to method name
+ * that handles the reduction.
+ *
+ * If a rule is not set, it has no handler.
+ */
+ static public $yyReduceMap = array(
+%%
+ );
+ /* Beginning here are the reduction cases. A typical example
+ ** follows:
+ ** #line
+ ** function yy_r0($yymsp){ ... } // User supplied code
+ ** #line
+ */
+%%
+
+ /**
+ * placeholder for the left hand side in a reduce operation.
+ *
+ * For a parser with a rule like this:
+ *
+ * rule(A) ::= B. { A = 1; }
+ *
+ *
+ * The parser will translate to something like:
+ *
+ *
+ * function yy_r0(){$this->_retvalue = 1;}
+ *
+ */
+ private $_retvalue;
+
+ /**
+ * Perform a reduce action and the shift that must immediately
+ * follow the reduce.
+ *
+ * For a rule such as:
+ *
+ *
+ * A ::= B blah C. { dosomething(); }
+ *
+ *
+ * This function will first call the action, if any, ("dosomething();" in our
+ * example), and then it will pop three states from the stack,
+ * one for each entry on the right-hand side of the expression
+ * (B, blah, and C in our example rule), and then push the result of the action
+ * back on to the stack with the resulting state reduced to (as described in the .out
+ * file)
+ * @param int Number of the rule by which to reduce
+ */
+ function yy_reduce($yyruleno)
+ {
+ //int $yygoto; /* The next state */
+ //int $yyact; /* The next action */
+ //mixed $yygotominor; /* The LHS of the rule reduced */
+ //ParseyyStackEntry $yymsp; /* The top of the parser's stack */
+ //int $yysize; /* Amount to pop the stack */
+ $yymsp = $this->yystack[$this->yyidx];
+ if (self::$yyTraceFILE && $yyruleno >= 0
+ && $yyruleno < count(self::$yyRuleName)) {
+ fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n",
+ self::$yyTracePrompt, $yyruleno,
+ self::$yyRuleName[$yyruleno]);
+ }
+
+ $this->_retvalue = $yy_lefthand_side = null;
+ if (array_key_exists($yyruleno, self::$yyReduceMap)) {
+ // call the action
+ $this->_retvalue = null;
+ $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}();
+ $yy_lefthand_side = $this->_retvalue;
+ }
+ $yygoto = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $yysize = self::$yyRuleInfo[$yyruleno]['rhs'];
+ $this->yyidx -= $yysize;
+ for ($i = $yysize; $i; $i--) {
+ // pop all of the right-hand side parameters
+ array_pop($this->yystack);
+ }
+ $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto);
+ if ($yyact < self::YYNSTATE) {
+ /* If we are not debugging and the reduce action popped at least
+ ** one element off the stack, then we can push the new element back
+ ** onto the stack here, and skip the stack overflow test in yy_shift().
+ ** That gives a significant speed improvement. */
+ if (!self::$yyTraceFILE && $yysize) {
+ $this->yyidx++;
+ $x = new ParseyyStackEntry;
+ $x->stateno = $yyact;
+ $x->major = $yygoto;
+ $x->minor = $yy_lefthand_side;
+ $this->yystack[$this->yyidx] = $x;
+ } else {
+ $this->yy_shift($yyact, $yygoto, $yy_lefthand_side);
+ }
+ } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yy_accept();
+ }
+ }
+
+ /**
+ * The following code executes when the parse fails
+ *
+ * Code from %parse_fail is inserted here
+ */
+ function yy_parse_failed()
+ {
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+%%
+ }
+
+ /**
+ * The following code executes when a syntax error first occurs.
+ *
+ * %syntax_error code is inserted here
+ * @param int The major type of the error token
+ * @param mixed The minor type of the error token
+ */
+ function yy_syntax_error($yymajor, $TOKEN)
+ {
+%%
+ }
+
+ /**
+ * The following is executed when the parser accepts
+ *
+ * %parse_accept code is inserted here
+ */
+ function yy_accept()
+ {
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $stack = $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+%%
+ }
+
+ /**
+ * The main parser program.
+ *
+ * The first argument is the major token number. The second is
+ * the token value string as scanned from the input.
+ *
+ * @param int $yymajor the token number
+ * @param mixed $yytokenvalue the token value
+ * @param mixed ... any extra arguments that should be passed to handlers
+ *
+ * @return void
+ */
+ function doParse($yymajor, $yytokenvalue)
+ {
+// $yyact; /* The parser action. */
+// $yyendofinput; /* True if we are at the end of input */
+ $yyerrorhit = 0; /* True if yymajor has invoked an error */
+
+ /* (re)initialize the parser, if necessary */
+ if ($this->yyidx === null || $this->yyidx < 0) {
+ /* if ($yymajor == 0) return; // not sure why this was here... */
+ $this->yyidx = 0;
+ $this->yyerrcnt = -1;
+ $x = new ParseyyStackEntry;
+ $x->stateno = 0;
+ $x->major = 0;
+ $this->yystack = array();
+ array_push($this->yystack, $x);
+ }
+ $yyendofinput = ($yymajor==0);
+
+ if (self::$yyTraceFILE) {
+ fprintf(
+ self::$yyTraceFILE,
+ "%sInput %s\n",
+ self::$yyTracePrompt,
+ self::$yyTokenName[$yymajor]
+ );
+ }
+
+ do {
+ $yyact = $this->yy_find_shift_action($yymajor);
+ if ($yymajor < self::YYERRORSYMBOL
+ && !$this->yy_is_expected_token($yymajor)
+ ) {
+ // force a syntax error
+ $yyact = self::YY_ERROR_ACTION;
+ }
+ if ($yyact < self::YYNSTATE) {
+ $this->yy_shift($yyact, $yymajor, $yytokenvalue);
+ $this->yyerrcnt--;
+ if ($yyendofinput && $this->yyidx >= 0) {
+ $yymajor = 0;
+ } else {
+ $yymajor = self::YYNOCODE;
+ }
+ } elseif ($yyact < self::YYNSTATE + self::YYNRULE) {
+ $this->yy_reduce($yyact - self::YYNSTATE);
+ } elseif ($yyact == self::YY_ERROR_ACTION) {
+ if (self::$yyTraceFILE) {
+ fprintf(
+ self::$yyTraceFILE,
+ "%sSyntax Error!\n",
+ self::$yyTracePrompt
+ );
+ }
+ if (self::YYERRORSYMBOL) {
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
+ ** grammar defines an error token "ERROR".
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if ($this->yyerrcnt < 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $yymx = $this->yystack[$this->yyidx]->major;
+ if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ) {
+ if (self::$yyTraceFILE) {
+ fprintf(
+ self::$yyTraceFILE,
+ "%sDiscard input token %s\n",
+ self::$yyTracePrompt,
+ self::$yyTokenName[$yymajor]
+ );
+ }
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $yymajor = self::YYNOCODE;
+ } else {
+ while ($this->yyidx >= 0
+ && $yymx != self::YYERRORSYMBOL
+ && ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE
+ ) {
+ $this->yy_pop_parser_stack();
+ }
+ if ($this->yyidx < 0 || $yymajor==0) {
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $this->yy_parse_failed();
+ $yymajor = self::YYNOCODE;
+ } elseif ($yymx != self::YYERRORSYMBOL) {
+ $u2 = 0;
+ $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2);
+ }
+ }
+ $this->yyerrcnt = 3;
+ $yyerrorhit = 1;
+ } else {
+ /* YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if ($this->yyerrcnt <= 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $this->yyerrcnt = 3;
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ if ($yyendofinput) {
+ $this->yy_parse_failed();
+ }
+ $yymajor = self::YYNOCODE;
+ }
+ } else {
+ $this->yy_accept();
+ $yymajor = self::YYNOCODE;
+ }
+ } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
+ }
+}
diff --git a/core/oql/build/PHP/LexerGenerator.php b/core/oql/build/PHP/LexerGenerator.php
new file mode 100644
index 000000000..f9dd13a6e
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator.php
@@ -0,0 +1,332 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_LexerGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category php
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: LexerGenerator.php 294970 2010-02-12 03:46:38Z clockwerx $
+ * @since File available since Release 0.1.0
+ */
+/**
+ * The Lexer generation parser
+ */
+require_once 'PHP/LexerGenerator/Parser.php';
+/**
+ * Hand-written lexer for lex2php format files
+ */
+require_once 'PHP/LexerGenerator/Lexer.php';
+
+/**
+ * The basic home class for the lexer generator. A lexer scans text and
+ * organizes it into tokens for usage by a parser.
+ *
+ * Sample Usage:
+ *
+ * require_once 'PHP/LexerGenerator.php';
+ * $lex = new PHP_LexerGenerator('/path/to/lexerfile.plex');
+ *
+ *
+ * A file named "/path/to/lexerfile.php" will be created.
+ *
+ * File format consists of a PHP file containing specially
+ * formatted comments like so:
+ *
+ *
+ * /*!lex2php
+ * {@*}
+ *
+ *
+ * All lexer definition files must contain at least two lex2php comment blocks:
+ * - 1 regex declaration block
+ * - 1 or more rule declaration blocks
+ *
+ * The first lex2php comment is the regex declaration block and must contain
+ * several processor instruction as well as defining a name for all
+ * regular expressions. Processor instructions start with
+ * a "%" symbol and must be:
+ *
+ * - %counter
+ * - %input
+ * - %token
+ * - %value
+ * - %line
+ *
+ * token and counter should define the class variables used to define lexer input
+ * and the index into the input. token and value should be used to define the class
+ * variables used to store the token number and its textual value. Finally, line
+ * should be used to define the class variable used to define the current line number
+ * of scanning.
+ *
+ * For example:
+ *
+ * /*!lex2php
+ * %counter {$this->N}
+ * %input {$this->data}
+ * %token {$this->token}
+ * %value {$this->value}
+ * %line {%this->linenumber}
+ * {@*}
+ *
+ *
+ * Patterns consist of an identifier containing an letters or an underscore, and
+ * a descriptive match pattern.
+ *
+ * Descriptive match patterns may either be regular expressions (regexes) or
+ * quoted literal strings. Here are some examples:
+ *
+ *
+ * pattern = "quoted literal"
+ * ANOTHER = /[a-zA-Z_]+/
+ * COMPLEX = @<([a-zA-Z_]+)( +(([a-zA-Z_]+)=((["\'])([^\6]*)\6))+){0,1}>[^<]*\1>@
+ *
+ *
+ * Quoted strings must escape the \ and " characters with \" and \\.
+ *
+ * Regex patterns must be in Perl-compatible regular expression format (preg).
+ * special characters (like \t \n or \x3H) can only be used in regexes, all
+ * \ will be escaped in literal strings.
+ *
+ * Sub-patterns may be defined and back-references (like \1) may be used. Any sub-
+ * patterns detected will be passed to the token handler in the variable
+ * $yysubmatches.
+ *
+ * In addition, lookahead expressions, and once-only expressions are allowed.
+ * Lookbehind expressions are impossible (scanning always occurs from the
+ * current position forward), and recursion (?R) can't work and is not allowed.
+ *
+ *
+ * /*!lex2php
+ * %counter {$this->N}
+ * %input {$this->data}
+ * %token {$this->token}
+ * %value {$this->value}
+ * %line {%this->linenumber}
+ * alpha = /[a-zA-Z]/
+ * alphaplus = /[a-zA-Z]+/
+ * number = /[0-9]/
+ * numerals = /[0-9]+/
+ * whitespace = /[ \t\n]+/
+ * blah = "$\""
+ * blahblah = /a\$/
+ * GAMEEND = @(?:1\-0|0\-1|1/2\-1/2)@
+ * PAWNMOVE = /P?[a-h]([2-7]|[18]\=(Q|R|B|N))|P?[a-h]x[a-h]([2-7]|[18]\=(Q|R|B|N))/
+ * {@*}
+ *
+ *
+ * All regexes must be delimited. Any legal preg delimiter can be used (as in @ or / in
+ * the example above)
+ *
+ * Rule lex2php blocks each define a lexer state. You can optionally name the state
+ * with the %statename processor instruction. State names can be used to transfer to
+ * a new lexer state with the yybegin() method
+ *
+ *
+ * /*!lexphp
+ * %statename INITIAL
+ * blah {
+ * $this->yybegin(self::INBLAH);
+ * // note - $this->yybegin(2) would also work
+ * }
+ * {@*}
+ * /*!lex2php
+ * %statename INBLAH
+ * ANYTHING {
+ * $this->yybegin(self::INITIAL);
+ * // note - $this->yybegin(1) would also work
+ * }
+ * {@*}
+ *
+ *
+ * You can maintain a parser state stack simply by using yypushstate() and
+ * yypopstate() instead of yybegin():
+ *
+ *
+ * /*!lexphp
+ * %statename INITIAL
+ * blah {
+ * $this->yypushstate(self::INBLAH);
+ * }
+ * {@*}
+ * /*!lex2php
+ * %statename INBLAH
+ * ANYTHING {
+ * $this->yypopstate();
+ * // now INBLAH doesn't care where it was called from
+ * }
+ * {@*}
+ *
+ *
+ * Code blocks can choose to skip the current token and cycle to the next token by
+ * returning "false"
+ *
+ *
+ * /*!lex2php
+ * WHITESPACE {
+ * return false;
+ * }
+ * {@*}
+ *
+ *
+ * If you wish to re-process the current token in a new state, simply return true.
+ * If you forget to change lexer state, this will cause an unterminated loop,
+ * so be careful!
+ *
+ *
+ * /*!lex2php
+ * "(" {
+ * $this->yypushstate(self::INPARAMS);
+ * return true;
+ * }
+ * {@*}
+ *
+ *
+ * Lastly, if you wish to cycle to the next matching rule, return any value other than
+ * true, false or null:
+ *
+ *
+ * /*!lex2php
+ * "{@" ALPHA {
+ * if ($this->value == '{@internal') {
+ * return 'more';
+ * }
+ * ...
+ * }
+ * "{@internal" {
+ * ...
+ * }
+ * {@*}
+ *
+ *
+ * Note that this procedure is exceptionally inefficient, and it would be far better
+ * to take advantage of PHP_LexerGenerator's top-down precedence and instead code:
+ *
+ *
+ * /*!lex2php
+ * "{@internal" {
+ * ...
+ * }
+ * "{@" ALPHA {
+ * ...
+ * }
+ * {@*}
+ *
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version @package_version@
+ * @since Class available since Release 0.1.0
+ * @example TestLexer.plex Example lexer source
+ * @example TestLexer.php Example lexer generated php code
+ * @example usage.php Example usage of PHP_LexerGenerator
+ * @example Lexer.plex File_ChessPGN lexer source (complex)
+ * @example Lexer.php File_ChessPGN lexer generated php code
+ */
+
+class PHP_LexerGenerator
+{
+ /**
+ * Plex file lexer.
+ * @var PHP_LexerGenerator_Lexer
+ */
+ private $_lex;
+
+ /**
+ * Plex file parser.
+ * @var PHP_LexerGenerator_Parser
+ */
+ private $_parser;
+
+ /**
+ * Path to the output PHP file.
+ * @var string
+ */
+ private $_outfile;
+
+ /**
+ * Debug flag. When set, Parser trace information is generated.
+ * @var boolean
+ */
+ public $debug = false;
+
+ /**
+ * Create a lexer generator and optionally generate a lexer file.
+ *
+ * @param string Optional plex file {@see PHP_LexerGenerator::create}.
+ * @param string Optional output file {@see PHP_LexerGenerator::create}.
+ */
+ function __construct($lexerfile = '', $outfile = '')
+ {
+ if ($lexerfile) {
+ $this -> create($lexerfile, $outfile);
+ }
+ }
+
+ /**
+ * Create a lexer file from its skeleton plex file.
+ *
+ * @param string Path to the plex file.
+ * @param string Optional path to output file. Default is lexerfile with
+ * extension of ".php".
+ */
+ function create($lexerfile, $outfile = '')
+ {
+ $this->_lex = new PHP_LexerGenerator_Lexer(file_get_contents($lexerfile));
+ $info = pathinfo($lexerfile);
+ if ($outfile) {
+ $this->outfile = $outfile;
+ } else {
+ $this->outfile = $info['dirname'] . DIRECTORY_SEPARATOR .
+ substr($info['basename'], 0,
+ strlen($info['basename']) - strlen($info['extension'])) . 'php';
+ }
+ $this->_parser = new PHP_LexerGenerator_Parser($this->outfile, $this->_lex);
+ if ($this -> debug) {
+ $this->_parser->PrintTrace();
+ }
+ while ($this->_lex->advance($this->_parser)) {
+ $this->_parser->doParse($this->_lex->token, $this->_lex->value);
+ }
+ $this->_parser->doParse(0, 0);
+ }
+}
+//$a = new PHP_LexerGenerator('/development/File_ChessPGN/ChessPGN/Lexer.plex');
+?>
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/Exception.php b/core/oql/build/PHP/LexerGenerator/Exception.php
new file mode 100644
index 000000000..69b3066d2
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Exception.php
@@ -0,0 +1,55 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_LexerGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category php
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ */
+require_once 'PEAR/Exception.php';
+/**
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version @package_version@
+ * @since File available since Release 0.1.0
+ */
+class PHP_LexerGenerator_Exception extends PEAR_Exception {}
+?>
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/Lexer.php b/core/oql/build/PHP/LexerGenerator/Lexer.php
new file mode 100644
index 000000000..8b1731d06
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Lexer.php
@@ -0,0 +1,533 @@
+
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: Lexer.php 246683 2007-11-22 04:43:52Z instance $
+ * @since File available since Release 0.1.0
+ */
+require_once 'PHP/LexerGenerator/Parser.php';
+/**
+ * Token scanner for plex files.
+ *
+ * This scanner detects comments beginning with "/*!lex2php" and
+ * then returns their components (processing instructions, patterns, strings
+ * action code, and regexes)
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version @package_version@
+ * @since Class available since Release 0.1.0
+ */
+class PHP_LexerGenerator_Lexer
+{
+ private $data;
+ private $N;
+ private $state;
+ /**
+ * Current line number in input
+ * @var int
+ */
+ public $line;
+ /**
+ * Number of scanning errors detected
+ * @var int
+ */
+ public $errors = 0;
+ /**
+ * integer identifier of the current token
+ * @var int
+ */
+ public $token;
+ /**
+ * string content of current token
+ * @var string
+ */
+ public $value;
+
+ const CODE = PHP_LexerGenerator_Parser::CODE;
+ const COMMENTEND = PHP_LexerGenerator_Parser::COMMENTEND;
+ const COMMENTSTART = PHP_LexerGenerator_Parser::COMMENTSTART;
+ const PATTERN = PHP_LexerGenerator_Parser::PATTERN;
+ const PHPCODE = PHP_LexerGenerator_Parser::PHPCODE;
+ const PI = PHP_LexerGenerator_Parser::PI;
+ const QUOTE = PHP_LexerGenerator_Parser::QUOTE;
+ const SINGLEQUOTE = PHP_LexerGenerator_Parser::SINGLEQUOTE;
+ const SUBPATTERN = PHP_LexerGenerator_Parser::SUBPATTERN;
+
+ /**
+ * prepare scanning
+ * @param string the input
+ */
+ function __construct($data)
+ {
+ $this->data = str_replace("\r\n", "\n", $data);
+ $this->N = 0;
+ $this->line = 1;
+ $this->state = 'Start';
+ $this->errors = 0;
+ }
+
+ /**
+ * Output an error message
+ * @param string
+ */
+ private function error($msg)
+ {
+ echo 'Error on line ' . $this->line . ': ' . $msg;
+ $this->errors++;
+ }
+
+ /**
+ * Initial scanning state lexer
+ * @return boolean
+ */
+ private function lexStart()
+ {
+ if ($this->N >= strlen($this->data)) {
+ return false;
+ }
+ $a = strpos($this->data, '/*!lex2php' . "\n", $this->N);
+ if ($a === false) {
+ $this->value = substr($this->data, $this->N);
+ $this->N = strlen($this->data);
+ $this->token = self::PHPCODE;
+ return true;
+ }
+ if ($a > $this->N) {
+ $this->value = substr($this->data, $this->N, $a - $this->N);
+ $this->N = $a;
+ $this->token = self::PHPCODE;
+ return true;
+ }
+ $this->value = '/*!lex2php' . "\n";
+ $this->N += 11; // strlen("/*lex2php\n")
+ $this->token = self::COMMENTSTART;
+ $this->state = 'Declare';
+ return true;
+ }
+
+ /**
+ * lexer for top-level canning state after the initial declaration comment
+ * @return boolean
+ */
+ private function lexStartNonDeclare()
+ {
+ if ($this->N >= strlen($this->data)) {
+ return false;
+ }
+ $a = strpos($this->data, '/*!lex2php' . "\n", $this->N);
+ if ($a === false) {
+ $this->value = substr($this->data, $this->N);
+ $this->N = strlen($this->data);
+ $this->token = self::PHPCODE;
+ return true;
+ }
+ if ($a > $this->N) {
+ $this->value = substr($this->data, $this->N, $a - $this->N);
+ $this->N = $a;
+ $this->token = self::PHPCODE;
+ return true;
+ }
+ $this->value = '/*!lex2php' . "\n";
+ $this->N += 11; // strlen("/*lex2php\n")
+ $this->token = self::COMMENTSTART;
+ $this->state = 'Rule';
+ return true;
+ }
+
+ /**
+ * lexer for declaration comment state
+ * @return boolean
+ */
+ private function lexDeclare()
+ {
+ while (true) {
+ $this -> skipWhitespaceEol();
+ if (
+ $this->N + 1 >= strlen($this->data)
+ || $this->data[$this->N] != '/'
+ || $this->data[$this->N + 1] != '/'
+ ) {
+ break;
+ }
+ // Skip single-line comment
+ while (
+ $this->N < strlen($this->data)
+ && $this->data[$this->N] != "\n"
+ ) {
+ ++$this->N;
+ }
+ }
+ if ($this->data[$this->N] == '*' && $this->data[$this->N + 1] == '/') {
+ $this->state = 'StartNonDeclare';
+ $this->value = '*/';
+ $this->N += 2;
+ $this->token = self::COMMENTEND;
+ return true;
+ }
+ if (preg_match('/\G%([a-z]+)/', $this->data, $token, null, $this->N)) {
+ $this->value = $token[1];
+ $this->N += strlen($token[1]) + 1;
+ $this->state = 'DeclarePI';
+ $this->token = self::PI;
+ return true;
+ }
+ if (preg_match('/\G[a-zA-Z_][a-zA-Z0-9_]*/', $this->data, $token, null, $this->N)) {
+ $this->value = $token[0];
+ $this->token = self::PATTERN;
+ $this->N += strlen($token[0]);
+ $this->state = 'DeclareEquals';
+ return true;
+ }
+ $this->error('expecting declaration of sub-patterns');
+ return false;
+ }
+
+ /**
+ * lexer for processor instructions within declaration comment
+ * @return boolean
+ */
+ private function lexDeclarePI()
+ {
+ $this -> skipWhitespace();
+ if ($this->data[$this->N] == "\n") {
+ $this->N++;
+ $this->state = 'Declare';
+ $this->line++;
+ return $this->lexDeclare();
+ }
+ if ($this->data[$this->N] == '{') {
+ return $this->lexCode();
+ }
+ if (!preg_match("/\G[^\n]+/", $this->data, $token, null, $this->N)) {
+ $this->error('Unexpected end of file');
+ return false;
+ }
+ $this->value = $token[0];
+ $this->N += strlen($this->value);
+ $this->token = self::SUBPATTERN;
+ return true;
+ }
+
+ /**
+ * lexer for processor instructions inside rule comments
+ * @return boolean
+ */
+ private function lexDeclarePIRule()
+ {
+ $this -> skipWhitespace();
+ if ($this->data[$this->N] == "\n") {
+ $this->N++;
+ $this->state = 'Rule';
+ $this->line++;
+ return $this->lexRule();
+ }
+ if ($this->data[$this->N] == '{') {
+ return $this->lexCode();
+ }
+ if (!preg_match("/\G[^\n]+/", $this->data, $token, null, $this->N)) {
+ $this->error('Unexpected end of file');
+ return false;
+ }
+ $this->value = $token[0];
+ $this->N += strlen($this->value);
+ $this->token = self::SUBPATTERN;
+ return true;
+ }
+
+ /**
+ * lexer for the state representing scanning between a pattern and the "=" sign
+ * @return boolean
+ */
+ private function lexDeclareEquals()
+ {
+ $this -> skipWhitespace();
+ if ($this->N >= strlen($this->data)) {
+ $this->error('unexpected end of input, expecting "=" for sub-pattern declaration');
+ }
+ if ($this->data[$this->N] != '=') {
+ $this->error('expecting "=" for sub-pattern declaration');
+ return false;
+ }
+ $this->N++;
+ $this->state = 'DeclareRightside';
+ $this -> skipWhitespace();
+ if ($this->N >= strlen($this->data)) {
+ $this->error('unexpected end of file, expecting right side of sub-pattern declaration');
+ return false;
+ }
+ return $this->lexDeclareRightside();
+ }
+
+ /**
+ * lexer for the right side of a pattern, detects quotes or regexes
+ * @return boolean
+ */
+ private function lexDeclareRightside()
+ {
+ if ($this->data[$this->N] == "\n") {
+ $this->state = 'lexDeclare';
+ $this->N++;
+ $this->line++;
+ return $this->lexDeclare();
+ }
+ if ($this->data[$this->N] == '"') {
+ return $this->lexQuote();
+ }
+ if ($this->data[$this->N] == '\'') {
+ return $this->lexQuote('\'');
+ }
+ $this -> skipWhitespace();
+ // match a pattern
+ $test = $this->data[$this->N];
+ $token = $this->N + 1;
+ $a = 0;
+ do {
+ if ($a++) {
+ $token++;
+ }
+ $token = strpos($this->data, $test, $token);
+ } while ($token !== false && ($this->data[$token - 1] == '\\'
+ && $this->data[$token - 2] != '\\'));
+ if ($token === false) {
+ $this->error('Unterminated regex pattern (started with "' . $test . '"');
+ return false;
+ }
+ if (substr_count($this->data, "\n", $this->N, $token - $this->N)) {
+ $this->error('Regex pattern extends over multiple lines');
+ return false;
+ }
+ $this->value = substr($this->data, $this->N + 1, $token - $this->N - 1);
+ // unescape the regex marker
+ // we will re-escape when creating the final regex
+ $this->value = str_replace('\\' . $test, $test, $this->value);
+ $this->N = $token + 1;
+ $this->token = self::SUBPATTERN;
+ return true;
+ }
+
+ /**
+ * lexer for quoted literals
+ * @return boolean
+ */
+ private function lexQuote($quote = '"')
+ {
+ $token = $this->N + 1;
+ $a = 0;
+ do {
+ if ($a++) {
+ $token++;
+ }
+ $token = strpos($this->data, $quote, $token);
+ } while ($token !== false && $token < strlen($this->data) &&
+ ($this->data[$token - 1] == '\\' && $this->data[$token - 2] != '\\'));
+ if ($token === false) {
+ $this->error('unterminated quote');
+ return false;
+ }
+ if (substr_count($this->data, "\n", $this->N, $token - $this->N)) {
+ $this->error('quote extends over multiple lines');
+ return false;
+ }
+ $this->value = substr($this->data, $this->N + 1, $token - $this->N - 1);
+ $this->value = str_replace('\\'.$quote, $quote, $this->value);
+ $this->value = str_replace('\\\\', '\\', $this->value);
+ $this->N = $token + 1;
+ if ($quote == '\'' ) {
+ $this->token = self::SINGLEQUOTE;
+ } else {
+ $this->token = self::QUOTE;
+ }
+ return true;
+ }
+
+ /**
+ * lexer for rules
+ * @return boolean
+ */
+ private function lexRule()
+ {
+ while (
+ $this->N < strlen($this->data)
+ && (
+ $this->data[$this->N] == ' '
+ || $this->data[$this->N] == "\t"
+ || $this->data[$this->N] == "\n"
+ ) || (
+ $this->N < strlen($this->data) - 1
+ && $this->data[$this->N] == '/'
+ && $this->data[$this->N + 1] == '/'
+ )
+ ) {
+ if ( $this->data[$this->N] == '/' && $this->data[$this->N + 1] == '/' ) {
+ // Skip single line comments
+ $next_newline = strpos($this->data, "\n", $this->N) + 1;
+ if ($next_newline) {
+ $this->N = $next_newline;
+ } else {
+ $this->N = sizeof($this->data);
+ }
+ $this->line++;
+ } else {
+ if ($this->data[$this->N] == "\n") {
+ $this->line++;
+ }
+ $this->N++; // skip all whitespace
+ }
+ }
+
+ if ($this->N >= strlen($this->data)) {
+ $this->error('unexpected end of input, expecting rule declaration');
+ }
+ if ($this->data[$this->N] == '*' && $this->data[$this->N + 1] == '/') {
+ $this->state = 'StartNonDeclare';
+ $this->value = '*/';
+ $this->N += 2;
+ $this->token = self::COMMENTEND;
+ return true;
+ }
+ if ($this->data[$this->N] == '\'') {
+ return $this->lexQuote('\'');
+ }
+ if (preg_match('/\G%([a-zA-Z_]+)/', $this->data, $token, null, $this->N)) {
+ $this->value = $token[1];
+ $this->N += strlen($token[1]) + 1;
+ $this->state = 'DeclarePIRule';
+ $this->token = self::PI;
+ return true;
+ }
+ if ($this->data[$this->N] == "{") {
+ return $this->lexCode();
+ }
+ if ($this->data[$this->N] == '"') {
+ return $this->lexQuote();
+ }
+ if (preg_match('/\G[a-zA-Z_][a-zA-Z0-9_]*/', $this->data, $token, null, $this->N)) {
+ $this->value = $token[0];
+ $this->N += strlen($token[0]);
+ $this->token = self::SUBPATTERN;
+ return true;
+ } else {
+ $this->error('expecting token rule (quotes or sub-patterns)');
+ return false;
+ }
+ }
+
+ /**
+ * lexer for php code blocks
+ * @return boolean
+ */
+ private function lexCode()
+ {
+ $cp = $this->N + 1;
+ for ($level = 1; $cp < strlen($this->data) && ($level > 1 || $this->data[$cp] != '}'); $cp++) {
+ if ($this->data[$cp] == '{') {
+ $level++;
+ } elseif ($this->data[$cp] == '}') {
+ $level--;
+ } elseif ($this->data[$cp] == '/' && $this->data[$cp + 1] == '/') {
+ /* Skip C++ style comments */
+ $cp += 2;
+ $z = strpos($this->data, "\n", $cp);
+ if ($z === false) {
+ $cp = strlen($this->data);
+ break;
+ }
+ $cp = $z;
+ } elseif ($this->data[$cp] == "'" || $this->data[$cp] == '"') {
+ /* String a character literals */
+ $startchar = $this->data[$cp];
+ $prevc = 0;
+ for ($cp++; $cp < strlen($this->data) && ($this->data[$cp] != $startchar || $prevc === '\\'); $cp++) {
+ if ($prevc === '\\') {
+ $prevc = 0;
+ } else {
+ $prevc = $this->data[$cp];
+ }
+ }
+ }
+ }
+ if ($cp >= strlen($this->data)) {
+ $this->error("PHP code starting on this line is not terminated before the end of the file.");
+ $this->error++;
+ return false;
+ } else {
+ $this->value = substr($this->data, $this->N + 1, $cp - $this->N - 1);
+ $this->token = self::CODE;
+ $this->N = $cp + 1;
+ return true;
+ }
+ }
+
+ /**
+ * Skip whitespace characters
+ */
+ private function skipWhitespace() {
+ while (
+ $this->N < strlen($this->data)
+ && (
+ $this->data[$this->N] == ' '
+ || $this->data[$this->N] == "\t"
+ )
+ ) {
+ $this->N++; // skip whitespace
+ }
+ }
+
+ /**
+ * Skip whitespace and EOL characters
+ */
+ private function skipWhitespaceEol() {
+ while (
+ $this->N < strlen($this->data)
+ && (
+ $this->data[$this->N] == ' '
+ || $this->data[$this->N] == "\t"
+ || $this->data[$this->N] == "\n"
+ )
+ ) {
+ if ($this->data[$this->N] == "\n") {
+ ++$this -> line;
+ }
+ $this->N++; // skip whitespace
+ }
+ }
+
+ /**
+ * Primary scanner
+ *
+ * In addition to lexing, this properly increments the line number of lexing.
+ * This calls the proper sub-lexer based on the parser state
+ * @param unknown_type $parser
+ * @return unknown
+ */
+ public function advance($parser)
+ {
+ if ($this->N >= strlen($this->data)) {
+ return false;
+ }
+ if ($this->{'lex' . $this->state}()) {
+ $this->line += substr_count($this->value, "\n");
+ return true;
+ }
+ return false;
+ }
+}
+?>
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/Parser.out b/core/oql/build/PHP/LexerGenerator/Parser.out
new file mode 100644
index 000000000..2db63a6e3
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Parser.out
@@ -0,0 +1,492 @@
+State 0:
+ start ::= * lexfile
+ lexfile ::= * declare rules
+ lexfile ::= * declare PHPCODE rules
+ lexfile ::= * PHPCODE declare rules
+ lexfile ::= * PHPCODE declare PHPCODE rules
+ declare ::= * COMMENTSTART declarations COMMENTEND
+
+ PHPCODE shift 17
+ COMMENTSTART shift 8
+ start accept
+ lexfile shift 52
+ declare shift 6
+
+State 1:
+ rules ::= reset_rules * rule COMMENTEND
+ rules ::= reset_rules * PI SUBPATTERN rule COMMENTEND
+ rules ::= reset_rules * rule COMMENTEND PHPCODE
+ rules ::= reset_rules * PI SUBPATTERN rule COMMENTEND PHPCODE
+ rule ::= * rule_subpattern CODE
+ rule ::= * rule rule_subpattern CODE
+ rule_subpattern ::= * QUOTE
+ rule_subpattern ::= * SUBPATTERN
+ rule_subpattern ::= * rule_subpattern QUOTE
+ rule_subpattern ::= * rule_subpattern SUBPATTERN
+
+ PI shift 29
+ SUBPATTERN shift 50
+ QUOTE shift 51
+ rule shift 12
+ rule_subpattern shift 18
+
+State 2:
+ rules ::= COMMENTSTART * rule COMMENTEND
+ rules ::= COMMENTSTART * PI SUBPATTERN rule COMMENTEND
+ rules ::= COMMENTSTART * rule COMMENTEND PHPCODE
+ rules ::= COMMENTSTART * PI SUBPATTERN rule COMMENTEND PHPCODE
+ rule ::= * rule_subpattern CODE
+ rule ::= * rule rule_subpattern CODE
+ rule_subpattern ::= * QUOTE
+ rule_subpattern ::= * SUBPATTERN
+ rule_subpattern ::= * rule_subpattern QUOTE
+ rule_subpattern ::= * rule_subpattern SUBPATTERN
+
+ PI shift 34
+ SUBPATTERN shift 50
+ QUOTE shift 51
+ rule shift 11
+ rule_subpattern shift 18
+
+State 3:
+ rules ::= COMMENTSTART PI SUBPATTERN * rule COMMENTEND
+ rules ::= COMMENTSTART PI SUBPATTERN * rule COMMENTEND PHPCODE
+ rule ::= * rule_subpattern CODE
+ rule ::= * rule rule_subpattern CODE
+ rule_subpattern ::= * QUOTE
+ rule_subpattern ::= * SUBPATTERN
+ rule_subpattern ::= * rule_subpattern QUOTE
+ rule_subpattern ::= * rule_subpattern SUBPATTERN
+
+ SUBPATTERN shift 50
+ QUOTE shift 51
+ rule shift 10
+ rule_subpattern shift 18
+
+State 4:
+ lexfile ::= PHPCODE declare * rules
+ lexfile ::= PHPCODE declare * PHPCODE rules
+ rules ::= * COMMENTSTART rule COMMENTEND
+ rules ::= * COMMENTSTART PI SUBPATTERN rule COMMENTEND
+ rules ::= * COMMENTSTART rule COMMENTEND PHPCODE
+ rules ::= * COMMENTSTART PI SUBPATTERN rule COMMENTEND PHPCODE
+ rules ::= * reset_rules rule COMMENTEND
+ rules ::= * reset_rules PI SUBPATTERN rule COMMENTEND
+ rules ::= * reset_rules rule COMMENTEND PHPCODE
+ rules ::= * reset_rules PI SUBPATTERN rule COMMENTEND PHPCODE
+ reset_rules ::= * rules COMMENTSTART
+
+ PHPCODE shift 7
+ COMMENTSTART shift 2
+ rules shift 25
+ reset_rules shift 1
+
+State 5:
+ rules ::= reset_rules PI SUBPATTERN * rule COMMENTEND
+ rules ::= reset_rules PI SUBPATTERN * rule COMMENTEND PHPCODE
+ rule ::= * rule_subpattern CODE
+ rule ::= * rule rule_subpattern CODE
+ rule_subpattern ::= * QUOTE
+ rule_subpattern ::= * SUBPATTERN
+ rule_subpattern ::= * rule_subpattern QUOTE
+ rule_subpattern ::= * rule_subpattern SUBPATTERN
+
+ SUBPATTERN shift 50
+ QUOTE shift 51
+ rule shift 13
+ rule_subpattern shift 18
+
+State 6:
+ lexfile ::= declare * rules
+ lexfile ::= declare * PHPCODE rules
+ rules ::= * COMMENTSTART rule COMMENTEND
+ rules ::= * COMMENTSTART PI SUBPATTERN rule COMMENTEND
+ rules ::= * COMMENTSTART rule COMMENTEND PHPCODE
+ rules ::= * COMMENTSTART PI SUBPATTERN rule COMMENTEND PHPCODE
+ rules ::= * reset_rules rule COMMENTEND
+ rules ::= * reset_rules PI SUBPATTERN rule COMMENTEND
+ rules ::= * reset_rules rule COMMENTEND PHPCODE
+ rules ::= * reset_rules PI SUBPATTERN rule COMMENTEND PHPCODE
+ reset_rules ::= * rules COMMENTSTART
+
+ PHPCODE shift 9
+ COMMENTSTART shift 2
+ rules shift 33
+ reset_rules shift 1
+
+State 7:
+ lexfile ::= PHPCODE declare PHPCODE * rules
+ rules ::= * COMMENTSTART rule COMMENTEND
+ rules ::= * COMMENTSTART PI SUBPATTERN rule COMMENTEND
+ rules ::= * COMMENTSTART rule COMMENTEND PHPCODE
+ rules ::= * COMMENTSTART PI SUBPATTERN rule COMMENTEND PHPCODE
+ rules ::= * reset_rules rule COMMENTEND
+ rules ::= * reset_rules PI SUBPATTERN rule COMMENTEND
+ rules ::= * reset_rules rule COMMENTEND PHPCODE
+ rules ::= * reset_rules PI SUBPATTERN rule COMMENTEND PHPCODE
+ reset_rules ::= * rules COMMENTSTART
+
+ COMMENTSTART shift 2
+ rules shift 27
+ reset_rules shift 1
+
+State 8:
+ declare ::= COMMENTSTART * declarations COMMENTEND
+ declarations ::= * processing_instructions pattern_declarations
+ processing_instructions ::= * PI SUBPATTERN
+ processing_instructions ::= * PI CODE
+ processing_instructions ::= * processing_instructions PI SUBPATTERN
+ processing_instructions ::= * processing_instructions PI CODE
+
+ PI shift 23
+ declarations shift 28
+ processing_instructions shift 14
+
+State 9:
+ lexfile ::= declare PHPCODE * rules
+ rules ::= * COMMENTSTART rule COMMENTEND
+ rules ::= * COMMENTSTART PI SUBPATTERN rule COMMENTEND
+ rules ::= * COMMENTSTART rule COMMENTEND PHPCODE
+ rules ::= * COMMENTSTART PI SUBPATTERN rule COMMENTEND PHPCODE
+ rules ::= * reset_rules rule COMMENTEND
+ rules ::= * reset_rules PI SUBPATTERN rule COMMENTEND
+ rules ::= * reset_rules rule COMMENTEND PHPCODE
+ rules ::= * reset_rules PI SUBPATTERN rule COMMENTEND PHPCODE
+ reset_rules ::= * rules COMMENTSTART
+
+ COMMENTSTART shift 2
+ rules shift 31
+ reset_rules shift 1
+
+State 10:
+ rules ::= COMMENTSTART PI SUBPATTERN rule * COMMENTEND
+ rules ::= COMMENTSTART PI SUBPATTERN rule * COMMENTEND PHPCODE
+ rule ::= rule * rule_subpattern CODE
+ rule_subpattern ::= * QUOTE
+ rule_subpattern ::= * SUBPATTERN
+ rule_subpattern ::= * rule_subpattern QUOTE
+ rule_subpattern ::= * rule_subpattern SUBPATTERN
+
+ COMMENTEND shift 30
+ SUBPATTERN shift 50
+ QUOTE shift 51
+ rule_subpattern shift 19
+
+State 11:
+ rules ::= COMMENTSTART rule * COMMENTEND
+ rules ::= COMMENTSTART rule * COMMENTEND PHPCODE
+ rule ::= rule * rule_subpattern CODE
+ rule_subpattern ::= * QUOTE
+ rule_subpattern ::= * SUBPATTERN
+ rule_subpattern ::= * rule_subpattern QUOTE
+ rule_subpattern ::= * rule_subpattern SUBPATTERN
+
+ COMMENTEND shift 32
+ SUBPATTERN shift 50
+ QUOTE shift 51
+ rule_subpattern shift 19
+
+State 12:
+ rules ::= reset_rules rule * COMMENTEND
+ rules ::= reset_rules rule * COMMENTEND PHPCODE
+ rule ::= rule * rule_subpattern CODE
+ rule_subpattern ::= * QUOTE
+ rule_subpattern ::= * SUBPATTERN
+ rule_subpattern ::= * rule_subpattern QUOTE
+ rule_subpattern ::= * rule_subpattern SUBPATTERN
+
+ COMMENTEND shift 35
+ SUBPATTERN shift 50
+ QUOTE shift 51
+ rule_subpattern shift 19
+
+State 13:
+ rules ::= reset_rules PI SUBPATTERN rule * COMMENTEND
+ rules ::= reset_rules PI SUBPATTERN rule * COMMENTEND PHPCODE
+ rule ::= rule * rule_subpattern CODE
+ rule_subpattern ::= * QUOTE
+ rule_subpattern ::= * SUBPATTERN
+ rule_subpattern ::= * rule_subpattern QUOTE
+ rule_subpattern ::= * rule_subpattern SUBPATTERN
+
+ COMMENTEND shift 24
+ SUBPATTERN shift 50
+ QUOTE shift 51
+ rule_subpattern shift 19
+
+State 14:
+ declarations ::= processing_instructions * pattern_declarations
+ processing_instructions ::= processing_instructions * PI SUBPATTERN
+ processing_instructions ::= processing_instructions * PI CODE
+ pattern_declarations ::= * PATTERN subpattern
+ pattern_declarations ::= * pattern_declarations PATTERN subpattern
+
+ PI shift 20
+ PATTERN shift 16
+ pattern_declarations shift 26
+
+State 15:
+ pattern_declarations ::= pattern_declarations PATTERN * subpattern
+ subpattern ::= * QUOTE
+ subpattern ::= * SUBPATTERN
+ subpattern ::= * subpattern QUOTE
+ subpattern ::= * subpattern SUBPATTERN
+
+ SUBPATTERN shift 36
+ QUOTE shift 37
+ subpattern shift 21
+
+State 16:
+ pattern_declarations ::= PATTERN * subpattern
+ subpattern ::= * QUOTE
+ subpattern ::= * SUBPATTERN
+ subpattern ::= * subpattern QUOTE
+ subpattern ::= * subpattern SUBPATTERN
+
+ SUBPATTERN shift 36
+ QUOTE shift 37
+ subpattern shift 22
+
+State 17:
+ lexfile ::= PHPCODE * declare rules
+ lexfile ::= PHPCODE * declare PHPCODE rules
+ declare ::= * COMMENTSTART declarations COMMENTEND
+
+ COMMENTSTART shift 8
+ declare shift 4
+
+State 18:
+ rule ::= rule_subpattern * CODE
+ rule_subpattern ::= rule_subpattern * QUOTE
+ rule_subpattern ::= rule_subpattern * SUBPATTERN
+
+ SUBPATTERN shift 54
+ CODE shift 47
+ QUOTE shift 53
+
+State 19:
+ rule ::= rule rule_subpattern * CODE
+ rule_subpattern ::= rule_subpattern * QUOTE
+ rule_subpattern ::= rule_subpattern * SUBPATTERN
+
+ SUBPATTERN shift 54
+ CODE shift 45
+ QUOTE shift 53
+
+State 20:
+ processing_instructions ::= processing_instructions PI * SUBPATTERN
+ processing_instructions ::= processing_instructions PI * CODE
+
+ SUBPATTERN shift 44
+ CODE shift 40
+
+State 21:
+ (12) pattern_declarations ::= pattern_declarations PATTERN subpattern *
+ subpattern ::= subpattern * QUOTE
+ subpattern ::= subpattern * SUBPATTERN
+
+ SUBPATTERN shift 38
+ QUOTE shift 41
+ {default} reduce 12
+
+State 22:
+ (11) pattern_declarations ::= PATTERN subpattern *
+ subpattern ::= subpattern * QUOTE
+ subpattern ::= subpattern * SUBPATTERN
+
+ SUBPATTERN shift 38
+ QUOTE shift 41
+ {default} reduce 11
+
+State 23:
+ processing_instructions ::= PI * SUBPATTERN
+ processing_instructions ::= PI * CODE
+
+ SUBPATTERN shift 42
+ CODE shift 39
+
+State 24:
+ (18) rules ::= reset_rules PI SUBPATTERN rule COMMENTEND *
+ rules ::= reset_rules PI SUBPATTERN rule COMMENTEND * PHPCODE
+
+ PHPCODE shift 48
+ {default} reduce 18
+
+State 25:
+ (3) lexfile ::= PHPCODE declare rules *
+ reset_rules ::= rules * COMMENTSTART
+
+ COMMENTSTART shift 43
+ {default} reduce 3
+
+State 26:
+ (6) declarations ::= processing_instructions pattern_declarations *
+ pattern_declarations ::= pattern_declarations * PATTERN subpattern
+
+ PATTERN shift 15
+ {default} reduce 6
+
+State 27:
+ (4) lexfile ::= PHPCODE declare PHPCODE rules *
+ reset_rules ::= rules * COMMENTSTART
+
+ COMMENTSTART shift 43
+ {default} reduce 4
+
+State 28:
+ declare ::= COMMENTSTART declarations * COMMENTEND
+
+ COMMENTEND shift 55
+
+State 29:
+ rules ::= reset_rules PI * SUBPATTERN rule COMMENTEND
+ rules ::= reset_rules PI * SUBPATTERN rule COMMENTEND PHPCODE
+
+ SUBPATTERN shift 5
+
+State 30:
+ (14) rules ::= COMMENTSTART PI SUBPATTERN rule COMMENTEND *
+ rules ::= COMMENTSTART PI SUBPATTERN rule COMMENTEND * PHPCODE
+
+ PHPCODE shift 46
+ {default} reduce 14
+
+State 31:
+ (2) lexfile ::= declare PHPCODE rules *
+ reset_rules ::= rules * COMMENTSTART
+
+ COMMENTSTART shift 43
+ {default} reduce 2
+
+State 32:
+ (13) rules ::= COMMENTSTART rule COMMENTEND *
+ rules ::= COMMENTSTART rule COMMENTEND * PHPCODE
+
+ PHPCODE shift 56
+ {default} reduce 13
+
+State 33:
+ (1) lexfile ::= declare rules *
+ reset_rules ::= rules * COMMENTSTART
+
+ COMMENTSTART shift 43
+ {default} reduce 1
+
+State 34:
+ rules ::= COMMENTSTART PI * SUBPATTERN rule COMMENTEND
+ rules ::= COMMENTSTART PI * SUBPATTERN rule COMMENTEND PHPCODE
+
+ SUBPATTERN shift 3
+
+State 35:
+ (17) rules ::= reset_rules rule COMMENTEND *
+ rules ::= reset_rules rule COMMENTEND * PHPCODE
+
+ PHPCODE shift 49
+ {default} reduce 17
+
+State 36:
+ (29) subpattern ::= SUBPATTERN *
+
+ {default} reduce 29
+
+State 37:
+ (28) subpattern ::= QUOTE *
+
+ {default} reduce 28
+
+State 38:
+ (31) subpattern ::= subpattern SUBPATTERN *
+
+ {default} reduce 31
+
+State 39:
+ (8) processing_instructions ::= PI CODE *
+
+ {default} reduce 8
+
+State 40:
+ (10) processing_instructions ::= processing_instructions PI CODE *
+
+ {default} reduce 10
+
+State 41:
+ (30) subpattern ::= subpattern QUOTE *
+
+ {default} reduce 30
+
+State 42:
+ (7) processing_instructions ::= PI SUBPATTERN *
+
+ {default} reduce 7
+
+State 43:
+ (21) reset_rules ::= rules COMMENTSTART *
+
+ {default} reduce 21
+
+State 44:
+ (9) processing_instructions ::= processing_instructions PI SUBPATTERN *
+
+ {default} reduce 9
+
+State 45:
+ (23) rule ::= rule rule_subpattern CODE *
+
+ {default} reduce 23
+
+State 46:
+ (16) rules ::= COMMENTSTART PI SUBPATTERN rule COMMENTEND PHPCODE *
+
+ {default} reduce 16
+
+State 47:
+ (22) rule ::= rule_subpattern CODE *
+
+ {default} reduce 22
+
+State 48:
+ (20) rules ::= reset_rules PI SUBPATTERN rule COMMENTEND PHPCODE *
+
+ {default} reduce 20
+
+State 49:
+ (19) rules ::= reset_rules rule COMMENTEND PHPCODE *
+
+ {default} reduce 19
+
+State 50:
+ (25) rule_subpattern ::= SUBPATTERN *
+
+ {default} reduce 25
+
+State 51:
+ (24) rule_subpattern ::= QUOTE *
+
+ {default} reduce 24
+
+State 52:
+ (0) start ::= lexfile *
+
+ {default} reduce 0
+
+State 53:
+ (26) rule_subpattern ::= rule_subpattern QUOTE *
+
+ {default} reduce 26
+
+State 54:
+ (27) rule_subpattern ::= rule_subpattern SUBPATTERN *
+
+ {default} reduce 27
+
+State 55:
+ (5) declare ::= COMMENTSTART declarations COMMENTEND *
+
+ {default} reduce 5
+
+State 56:
+ (15) rules ::= COMMENTSTART rule COMMENTEND PHPCODE *
+
+ {default} reduce 15
+
diff --git a/core/oql/build/PHP/LexerGenerator/Parser.php b/core/oql/build/PHP/LexerGenerator/Parser.php
new file mode 100644
index 000000000..0362ebba2
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Parser.php
@@ -0,0 +1,1994 @@
+string = $s->string;
+ $this->metadata = $s->metadata;
+ } else {
+ $this->string = (string) $s;
+ if ($m instanceof PHP_LexerGenerator_ParseryyToken) {
+ $this->metadata = $m->metadata;
+ } elseif (is_array($m)) {
+ $this->metadata = $m;
+ }
+ }
+ }
+
+ function __toString()
+ {
+ return $this->_string;
+ }
+
+ function offsetExists($offset)
+ {
+ return isset($this->metadata[$offset]);
+ }
+
+ function offsetGet($offset)
+ {
+ return $this->metadata[$offset];
+ }
+
+ function offsetSet($offset, $value)
+ {
+ if ($offset === null) {
+ if (isset($value[0])) {
+ $x = ($value instanceof PHP_LexerGenerator_ParseryyToken) ?
+ $value->metadata : $value;
+ $this->metadata = array_merge($this->metadata, $x);
+ return;
+ }
+ $offset = count($this->metadata);
+ }
+ if ($value === null) {
+ return;
+ }
+ if ($value instanceof PHP_LexerGenerator_ParseryyToken) {
+ if ($value->metadata) {
+ $this->metadata[$offset] = $value->metadata;
+ }
+ } elseif ($value) {
+ $this->metadata[$offset] = $value;
+ }
+ }
+
+ function offsetUnset($offset)
+ {
+ unset($this->metadata[$offset]);
+ }
+}
+
+/** The following structure represents a single element of the
+ * parser's stack. Information stored includes:
+ *
+ * + The state number for the parser at this level of the stack.
+ *
+ * + The value of the token stored at this level of the stack.
+ * (In other words, the "major" token.)
+ *
+ * + The semantic value stored at this level of the stack. This is
+ * the information used by the action routines in the grammar.
+ * It is sometimes called the "minor" token.
+ */
+class PHP_LexerGenerator_ParseryyStackEntry
+{
+ public $stateno; /* The state-number */
+ public $major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ public $minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+
+// code external to the class is included here
+#line 3 "Parser.y"
+
+/* ?>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_LexerGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category php
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Parser.php 246683 2007-11-22 04:43:52Z instance $
+ * @since File available since Release 0.1.0
+ */
+/**
+ * For regular expression validation
+ */
+require_once 'PHP/LexerGenerator/Regex/Lexer.php';
+require_once 'PHP/LexerGenerator/Regex/Parser.php';
+require_once 'PHP/LexerGenerator/Exception.php';
+/**
+ * Token parser for plex files.
+ *
+ * This parser converts tokens pulled from {@link PHP_LexerGenerator_Lexer}
+ * into abstract patterns and rules, then creates the output file
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version @package_version@
+ * @since Class available since Release 0.1.0
+ */
+#line 166 "Parser.php"
+
+// declare_class is output here
+#line 2 "Parser.y"
+class PHP_LexerGenerator_Parser#line 171 "Parser.php"
+{
+/* First off, code is included which follows the "include_class" declaration
+** in the input file. */
+#line 82 "Parser.y"
+
+ private $patterns;
+ private $out;
+ private $lex;
+ private $input;
+ private $counter;
+ private $token;
+ private $value;
+ private $line;
+ private $matchlongest;
+ private $_regexLexer;
+ private $_regexParser;
+ private $_patternIndex = 0;
+ private $_outRuleIndex = 1;
+ private $caseinsensitive;
+ private $patternFlags;
+ private $unicode;
+
+ public $transTable = array(
+ 1 => self::PHPCODE,
+ 2 => self::COMMENTSTART,
+ 3 => self::COMMENTEND,
+ 4 => self::QUOTE,
+ 5 => self::SINGLEQUOTE,
+ 6 => self::PATTERN,
+ 7 => self::CODE,
+ 8 => self::SUBPATTERN,
+ 9 => self::PI,
+ );
+
+ function __construct($outfile, $lex)
+ {
+ $this->out = fopen($outfile, 'wb');
+ if (!$this->out) {
+ throw new Exception('unable to open lexer output file "' . $outfile . '"');
+ }
+ $this->lex = $lex;
+ $this->_regexLexer = new PHP_LexerGenerator_Regex_Lexer('');
+ $this->_regexParser = new PHP_LexerGenerator_Regex_Parser($this->_regexLexer);
+ }
+
+ function doLongestMatch($rules, $statename, $ruleindex)
+ {
+ fwrite($this->out, '
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ do {
+ $rules = array(');
+ foreach ($rules as $rule) {
+ fwrite($this->out, '
+ \'/\G' . $rule['pattern'] . '/' . $this->patternFlags . ' \',');
+ }
+ fwrite($this->out, '
+ );
+ $match = false;
+ foreach ($rules as $index => $rule) {
+ if (preg_match($rule, substr(' . $this->input . ', ' .
+ $this->counter . '), $yymatches)) {
+ if ($match) {
+ if (strlen($yymatches[0]) > strlen($match[0][0])) {
+ $match = array($yymatches, $index); // matches, token
+ }
+ } else {
+ $match = array($yymatches, $index);
+ }
+ }
+ }
+ if (!$match) {
+ throw new Exception(\'Unexpected input at line \' . ' . $this->line . ' .
+ \': \' . ' . $this->input . '[' . $this->counter . ']);
+ }
+ ' . $this->token . ' = $match[1];
+ ' . $this->value . ' = $match[0][0];
+ $yysubmatches = $match[0];
+ array_shift($yysubmatches);
+ if (!$yysubmatches) {
+ $yysubmatches = array();
+ }
+ $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}($yysubmatches);
+ if ($r === null) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {');
+ fwrite($this->out, '
+ $yy_yymore_patterns = array_slice($rules, $this->token, true);
+ // yymore is needed
+ do {
+ if (!isset($yy_yymore_patterns[' . $this->token . '])) {
+ throw new Exception(\'cannot do yymore for the last token\');
+ }
+ $match = false;
+ foreach ($yy_yymore_patterns[' . $this->token . '] as $index => $rule) {
+ if (preg_match(\'/\' . $rule . \'/' . $this->patternFlags . '\',
+ ' . $this->input . ', $yymatches, null, ' . $this->counter . ')) {
+ $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
+ if ($match) {
+ if (strlen($yymatches[0]) > strlen($match[0][0])) {
+ $match = array($yymatches, $index); // matches, token
+ }
+ } else {
+ $match = array($yymatches, $index);
+ }
+ }
+ }
+ if (!$match) {
+ throw new Exception(\'Unexpected input at line \' . ' . $this->line . ' .
+ \': \' . ' . $this->input . '[' . $this->counter . ']);
+ }
+ ' . $this->token . ' = $match[1];
+ ' . $this->value . ' = $match[0][0];
+ $yysubmatches = $match[0];
+ array_shift($yysubmatches);
+ if (!$yysubmatches) {
+ $yysubmatches = array();
+ }
+ ' . $this->line . ' = substr_count(' . $this->value . ', "\n");
+ $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}();
+ } while ($r !== null || !$r);
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } else {
+ // accept
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ return true;
+ }
+ }
+ } while (true);
+');
+ }
+
+ function doFirstMatch($rules, $statename, $ruleindex)
+ {
+ $patterns = array();
+ $pattern = '/';
+ $ruleMap = array();
+ $tokenindex = array();
+ $actualindex = 1;
+ $i = 0;
+ foreach ($rules as $rule) {
+ $ruleMap[$i++] = $actualindex;
+ $tokenindex[$actualindex] = $rule['subpatterns'];
+ $actualindex += $rule['subpatterns'] + 1;
+ $patterns[] = '\G(' . $rule['pattern'] . ')';
+ }
+ // Re-index tokencount from zero.
+ $tokencount = array_values($tokenindex);
+ $tokenindex = var_export($tokenindex, true);
+ $tokenindex = explode("\n", $tokenindex);
+ // indent for prettiness
+ $tokenindex = implode("\n ", $tokenindex);
+ $pattern .= implode('|', $patterns);
+ $pattern .= '/' . $this->patternFlags;
+ fwrite($this->out, '
+ $tokenMap = ' . $tokenindex . ';
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ ');
+ fwrite($this->out, '$yy_global_pattern = \'' .
+ $pattern . '\';' . "\n");
+ fwrite($this->out, '
+ do {
+ if (preg_match($yy_global_pattern,' . $this->input . ', $yymatches, null, ' .
+ $this->counter .
+ ')) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
+ if (!count($yymatches)) {
+ throw new Exception(\'Error: lexing failed because a rule matched\' .
+ \' an empty string. Input "\' . substr(' . $this->input . ',
+ ' . $this->counter . ', 5) . \'... state ' . $statename . '\');
+ }
+ next($yymatches); // skip global match
+ ' . $this->token . ' = key($yymatches); // token number
+ if ($tokenMap[' . $this->token . ']) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, ' . $this->token . ' + 1,
+ $tokenMap[' . $this->token . ']);
+ } else {
+ $yysubmatches = array();
+ }
+ ' . $this->value . ' = current($yymatches); // token value
+ $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}($yysubmatches);
+ if ($r === null) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {');
+ fwrite($this->out, '
+ $yy_yymore_patterns = array(' . "\n");
+ $extra = 0;
+ for($i = 0; count($patterns); $i++) {
+ unset($patterns[$i]);
+ $extra += $tokencount[0];
+ array_shift($tokencount);
+ fwrite($this->out, ' ' . $ruleMap[$i] . ' => array(' . $extra . ', "' .
+ implode('|', $patterns) . "\"),\n");
+ }
+ fwrite($this->out, ' );' . "\n");
+ fwrite($this->out, '
+ // yymore is needed
+ do {
+ if (!strlen($yy_yymore_patterns[' . $this->token . '][1])) {
+ throw new Exception(\'cannot do yymore for the last token\');
+ }
+ $yysubmatches = array();
+ if (preg_match(\'/\' . $yy_yymore_patterns[' . $this->token . '][1] . \'/' . $this->patternFlags . '\',
+ ' . $this->input . ', $yymatches, null, ' . $this->counter .')) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
+ next($yymatches); // skip global match
+ ' . $this->token . ' += key($yymatches) + $yy_yymore_patterns[' . $this->token . '][0]; // token number
+ ' . $this->value . ' = current($yymatches); // token value
+ ' . $this->line . ' = substr_count(' . $this->value . ', "\n");
+ if ($tokenMap[' . $this->token . ']) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, ' . $this->token . ' + 1,
+ $tokenMap[' . $this->token . ']);
+ } else {
+ $yysubmatches = array();
+ }
+ }
+ $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}($yysubmatches);
+ } while ($r !== null && !is_bool($r));
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ // accept
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ return true;
+ }
+ }
+ } else {
+ throw new Exception(\'Unexpected input at line\' . ' . $this->line . ' .
+ \': \' . ' . $this->input . '[' . $this->counter . ']);
+ }
+ break;
+ } while (true);
+');
+ }
+
+ function makeCaseInsensitve($string)
+ {
+ return preg_replace('/[a-z]/ie', "'[\\0'.strtoupper('\\0').']'", strtolower($string));
+ }
+
+ function outputRules($rules, $statename)
+ {
+ if (!$statename) {
+ $statename = $this -> _outRuleIndex;
+ }
+ fwrite($this->out, '
+ function yylex' . $this -> _outRuleIndex . '()
+ {');
+ if ($this->matchlongest) {
+ $ruleMap = array();
+ foreach ($rules as $i => $rule) {
+ $ruleMap[$i] = $i;
+ }
+ $this->doLongestMatch($rules, $statename, $this -> _outRuleIndex);
+ } else {
+ $ruleMap = array();
+ $actualindex = 1;
+ $i = 0;
+ foreach ($rules as $rule) {
+ $ruleMap[$i++] = $actualindex;
+ $actualindex += $rule['subpatterns'] + 1;
+ }
+ $this->doFirstMatch($rules, $statename, $this -> _outRuleIndex);
+ }
+ fwrite($this->out, '
+ } // end function
+
+');
+ if (is_string($statename)) {
+ fwrite($this->out, '
+ const ' . $statename . ' = ' . $this -> _outRuleIndex . ';
+');
+ }
+ foreach ($rules as $i => $rule) {
+ fwrite($this->out, ' function yy_r' . $this -> _outRuleIndex . '_' . $ruleMap[$i] . '($yy_subpatterns)
+ {
+' . $rule['code'] .
+' }
+');
+ }
+ $this -> _outRuleIndex++; // for next set of rules
+ }
+
+ function error($msg)
+ {
+ echo 'Error on line ' . $this->lex->line . ': ' , $msg;
+ }
+
+ function _validatePattern($pattern, $update = false)
+ {
+ $this->_regexLexer->reset($pattern, $this->lex->line);
+ $this->_regexParser->reset($this->_patternIndex, $update);
+ try {
+ while ($this->_regexLexer->yylex()) {
+ $this->_regexParser->doParse(
+ $this->_regexLexer->token, $this->_regexLexer->value);
+ }
+ $this->_regexParser->doParse(0, 0);
+ } catch (PHP_LexerGenerator_Exception $e) {
+ $this->error($e->getMessage());
+ throw new PHP_LexerGenerator_Exception('Invalid pattern "' . $pattern . '"');
+ }
+ return $this->_regexParser->result;
+ }
+#line 529 "Parser.php"
+
+/* Next is all token values, as class constants
+*/
+/*
+** These constants (all generated automatically by the parser generator)
+** specify the various kinds of tokens (terminals) that the parser
+** understands.
+**
+** Each symbol here is a terminal symbol in the grammar.
+*/
+ const PHPCODE = 1;
+ const COMMENTSTART = 2;
+ const COMMENTEND = 3;
+ const PI = 4;
+ const SUBPATTERN = 5;
+ const CODE = 6;
+ const PATTERN = 7;
+ const QUOTE = 8;
+ const SINGLEQUOTE = 9;
+ const YY_NO_ACTION = 99;
+ const YY_ACCEPT_ACTION = 98;
+ const YY_ERROR_ACTION = 97;
+
+/* Next are that tables used to determine what action to take based on the
+** current state and lookahead token. These tables are used to implement
+** functions that take a state number and lookahead value and return an
+** action integer.
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N < self::YYNSTATE Shift N. That is,
+** push the lookahead
+** token onto the stack
+** and goto state N.
+**
+** self::YYNSTATE <= N < self::YYNSTATE+self::YYNRULE Reduce by rule N-YYNSTATE.
+**
+** N == self::YYNSTATE+self::YYNRULE A syntax error has occurred.
+**
+** N == self::YYNSTATE+self::YYNRULE+1 The parser accepts its
+** input. (and concludes parsing)
+**
+** N == self::YYNSTATE+self::YYNRULE+2 No such action. Denotes unused
+** slots in the yy_action[] table.
+**
+** The action table is constructed as a single large static array $yy_action.
+** Given state S and lookahead X, the action is computed as
+**
+** self::$yy_action[self::$yy_shift_ofst[S] + X ]
+**
+** If the index value self::$yy_shift_ofst[S]+X is out of range or if the value
+** self::$yy_lookahead[self::$yy_shift_ofst[S]+X] is not equal to X or if
+** self::$yy_shift_ofst[S] is equal to self::YY_SHIFT_USE_DFLT, it means that
+** the action is not in the table and that self::$yy_default[S] should be used instead.
+**
+** The formula above is for computing the action when the lookahead is
+** a terminal symbol. If the lookahead is a non-terminal (as occurs after
+** a reduce action) then the static $yy_reduce_ofst array is used in place of
+** the static $yy_shift_ofst array and self::YY_REDUCE_USE_DFLT is used in place of
+** self::YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** self::$yy_action A single table containing all actions.
+** self::$yy_lookahead A table containing the lookahead for each entry in
+** yy_action. Used to detect hash collisions.
+** self::$yy_shift_ofst For each state, the offset into self::$yy_action for
+** shifting terminals.
+** self::$yy_reduce_ofst For each state, the offset into self::$yy_action for
+** shifting non-terminals after a reduce.
+** self::$yy_default Default action for each state.
+*/
+ const YY_SZ_ACTTAB = 91;
+static public $yy_action = array(
+ /* 0 */ 25, 50, 49, 31, 49, 54, 53, 54, 53, 35,
+ /* 10 */ 11, 49, 18, 22, 54, 53, 14, 59, 51, 28,
+ /* 20 */ 55, 57, 58, 59, 47, 1, 55, 57, 32, 15,
+ /* 30 */ 49, 29, 49, 54, 53, 54, 53, 30, 52, 49,
+ /* 40 */ 42, 46, 54, 53, 98, 56, 5, 13, 38, 18,
+ /* 50 */ 49, 43, 40, 54, 53, 12, 39, 18, 3, 37,
+ /* 60 */ 36, 17, 7, 8, 2, 10, 33, 18, 9, 2,
+ /* 70 */ 41, 44, 1, 24, 16, 34, 45, 27, 60, 48,
+ /* 80 */ 4, 1, 2, 1, 20, 19, 21, 26, 23, 6,
+ /* 90 */ 7,
+ );
+ static public $yy_lookahead = array(
+ /* 0 */ 3, 1, 5, 4, 5, 8, 9, 8, 9, 3,
+ /* 10 */ 19, 5, 21, 4, 8, 9, 7, 5, 6, 14,
+ /* 20 */ 8, 9, 3, 5, 6, 20, 8, 9, 3, 7,
+ /* 30 */ 5, 4, 5, 8, 9, 8, 9, 3, 1, 5,
+ /* 40 */ 5, 6, 8, 9, 11, 12, 13, 19, 5, 21,
+ /* 50 */ 5, 8, 9, 8, 9, 19, 5, 21, 5, 8,
+ /* 60 */ 9, 1, 2, 1, 2, 19, 14, 21, 1, 2,
+ /* 70 */ 5, 6, 20, 15, 16, 14, 2, 14, 1, 1,
+ /* 80 */ 5, 20, 2, 20, 18, 21, 18, 17, 4, 13,
+ /* 90 */ 2,
+);
+ const YY_SHIFT_USE_DFLT = -4;
+ const YY_SHIFT_MAX = 35;
+ static public $yy_shift_ofst = array(
+ /* 0 */ 60, 27, -1, 45, 45, 62, 67, 84, 80, 80,
+ /* 10 */ 34, 25, -3, 6, 51, 51, 9, 88, 12, 18,
+ /* 20 */ 43, 43, 65, 35, 19, 0, 22, 74, 74, 75,
+ /* 30 */ 78, 53, 77, 74, 74, 37,
+);
+ const YY_REDUCE_USE_DFLT = -10;
+ const YY_REDUCE_MAX = 17;
+ static public $yy_reduce_ofst = array(
+ /* 0 */ 33, 28, -9, 46, 36, 52, 63, 58, 61, 5,
+ /* 10 */ 64, 64, 64, 64, 66, 68, 70, 76,
+);
+ static public $yyExpectedTokens = array(
+ /* 0 */ array(1, 2, ),
+ /* 1 */ array(4, 5, 8, 9, ),
+ /* 2 */ array(4, 5, 8, 9, ),
+ /* 3 */ array(5, 8, 9, ),
+ /* 4 */ array(5, 8, 9, ),
+ /* 5 */ array(1, 2, ),
+ /* 6 */ array(1, 2, ),
+ /* 7 */ array(4, ),
+ /* 8 */ array(2, ),
+ /* 9 */ array(2, ),
+ /* 10 */ array(3, 5, 8, 9, ),
+ /* 11 */ array(3, 5, 8, 9, ),
+ /* 12 */ array(3, 5, 8, 9, ),
+ /* 13 */ array(3, 5, 8, 9, ),
+ /* 14 */ array(5, 8, 9, ),
+ /* 15 */ array(5, 8, 9, ),
+ /* 16 */ array(4, 7, ),
+ /* 17 */ array(2, ),
+ /* 18 */ array(5, 6, 8, 9, ),
+ /* 19 */ array(5, 6, 8, 9, ),
+ /* 20 */ array(5, 8, 9, ),
+ /* 21 */ array(5, 8, 9, ),
+ /* 22 */ array(5, 6, ),
+ /* 23 */ array(5, 6, ),
+ /* 24 */ array(3, ),
+ /* 25 */ array(1, ),
+ /* 26 */ array(7, ),
+ /* 27 */ array(2, ),
+ /* 28 */ array(2, ),
+ /* 29 */ array(5, ),
+ /* 30 */ array(1, ),
+ /* 31 */ array(5, ),
+ /* 32 */ array(1, ),
+ /* 33 */ array(2, ),
+ /* 34 */ array(2, ),
+ /* 35 */ array(1, ),
+ /* 36 */ array(),
+ /* 37 */ array(),
+ /* 38 */ array(),
+ /* 39 */ array(),
+ /* 40 */ array(),
+ /* 41 */ array(),
+ /* 42 */ array(),
+ /* 43 */ array(),
+ /* 44 */ array(),
+ /* 45 */ array(),
+ /* 46 */ array(),
+ /* 47 */ array(),
+ /* 48 */ array(),
+ /* 49 */ array(),
+ /* 50 */ array(),
+ /* 51 */ array(),
+ /* 52 */ array(),
+ /* 53 */ array(),
+ /* 54 */ array(),
+ /* 55 */ array(),
+ /* 56 */ array(),
+ /* 57 */ array(),
+ /* 58 */ array(),
+ /* 59 */ array(),
+ /* 60 */ array(),
+);
+ static public $yy_default = array(
+ /* 0 */ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ /* 10 */ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ /* 20 */ 72, 73, 97, 97, 97, 79, 67, 64, 65, 97,
+ /* 30 */ 75, 97, 74, 62, 63, 78, 92, 91, 96, 93,
+ /* 40 */ 95, 70, 68, 94, 71, 82, 69, 84, 77, 87,
+ /* 50 */ 81, 83, 80, 86, 85, 88, 61, 89, 66, 90,
+ /* 60 */ 76,
+);
+/* The next thing included is series of defines which control
+** various aspects of the generated parser.
+** self::YYNOCODE is a number which corresponds
+** to no legal terminal or nonterminal number. This
+** number is used to fill in empty slots of the hash
+** table.
+** self::YYFALLBACK If defined, this indicates that one or more tokens
+** have fall-back values which should be used if the
+** original value of the token will not parse.
+** self::YYSTACKDEPTH is the maximum depth of the parser's stack.
+** self::YYNSTATE the combined number of states.
+** self::YYNRULE the number of rules in the grammar
+** self::YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+*/
+ const YYNOCODE = 23;
+ const YYSTACKDEPTH = 100;
+ const YYNSTATE = 61;
+ const YYNRULE = 36;
+ const YYERRORSYMBOL = 10;
+ const YYERRSYMDT = 'yy0';
+ const YYFALLBACK = 0;
+ /** The next table maps tokens into fallback tokens. If a construct
+ * like the following:
+ *
+ * %fallback ID X Y Z.
+ *
+ * appears in the grammer, then ID becomes a fallback token for X, Y,
+ * and Z. Whenever one of the tokens X, Y, or Z is input to the parser
+ * but it does not parse, the type of the token is changed to ID and
+ * the parse is retried before an error is thrown.
+ */
+ static public $yyFallback = array(
+ );
+ /**
+ * Turn parser tracing on by giving a stream to which to write the trace
+ * and a prompt to preface each trace message. Tracing is turned off
+ * by making either argument NULL
+ *
+ * Inputs:
+ *
+ * - A stream resource to which trace output should be written.
+ * If NULL, then tracing is turned off.
+ * - A prefix string written at the beginning of every
+ * line of trace output. If NULL, then tracing is
+ * turned off.
+ *
+ * Outputs:
+ *
+ * - None.
+ * @param resource
+ * @param string
+ */
+ static function Trace($TraceFILE, $zTracePrompt)
+ {
+ if (!$TraceFILE) {
+ $zTracePrompt = 0;
+ } elseif (!$zTracePrompt) {
+ $TraceFILE = 0;
+ }
+ self::$yyTraceFILE = $TraceFILE;
+ self::$yyTracePrompt = $zTracePrompt;
+ }
+
+ /**
+ * Output debug information to output (php://output stream)
+ */
+ static function PrintTrace()
+ {
+ self::$yyTraceFILE = fopen('php://output', 'w');
+ self::$yyTracePrompt = '';
+ }
+
+ /**
+ * @var resource|0
+ */
+ static public $yyTraceFILE;
+ /**
+ * String to prepend to debug output
+ * @var string|0
+ */
+ static public $yyTracePrompt;
+ /**
+ * @var int
+ */
+ public $yyidx; /* Index of top element in stack */
+ /**
+ * @var int
+ */
+ public $yyerrcnt; /* Shifts left before out of the error */
+ /**
+ * @var array
+ */
+ public $yystack = array(); /* The parser's stack */
+
+ /**
+ * For tracing shifts, the names of all terminals and nonterminals
+ * are required. The following table supplies these names
+ * @var array
+ */
+ static public $yyTokenName = array(
+ '$', 'PHPCODE', 'COMMENTSTART', 'COMMENTEND',
+ 'PI', 'SUBPATTERN', 'CODE', 'PATTERN',
+ 'QUOTE', 'SINGLEQUOTE', 'error', 'start',
+ 'lexfile', 'declare', 'rules', 'declarations',
+ 'processing_instructions', 'pattern_declarations', 'subpattern', 'rule',
+ 'reset_rules', 'rule_subpattern',
+ );
+
+ /**
+ * For tracing reduce actions, the names of all rules are required.
+ * @var array
+ */
+ static public $yyRuleName = array(
+ /* 0 */ "start ::= lexfile",
+ /* 1 */ "lexfile ::= declare rules",
+ /* 2 */ "lexfile ::= declare PHPCODE rules",
+ /* 3 */ "lexfile ::= PHPCODE declare rules",
+ /* 4 */ "lexfile ::= PHPCODE declare PHPCODE rules",
+ /* 5 */ "declare ::= COMMENTSTART declarations COMMENTEND",
+ /* 6 */ "declarations ::= processing_instructions pattern_declarations",
+ /* 7 */ "processing_instructions ::= PI SUBPATTERN",
+ /* 8 */ "processing_instructions ::= PI CODE",
+ /* 9 */ "processing_instructions ::= processing_instructions PI SUBPATTERN",
+ /* 10 */ "processing_instructions ::= processing_instructions PI CODE",
+ /* 11 */ "pattern_declarations ::= PATTERN subpattern",
+ /* 12 */ "pattern_declarations ::= pattern_declarations PATTERN subpattern",
+ /* 13 */ "rules ::= COMMENTSTART rule COMMENTEND",
+ /* 14 */ "rules ::= COMMENTSTART PI SUBPATTERN rule COMMENTEND",
+ /* 15 */ "rules ::= COMMENTSTART rule COMMENTEND PHPCODE",
+ /* 16 */ "rules ::= COMMENTSTART PI SUBPATTERN rule COMMENTEND PHPCODE",
+ /* 17 */ "rules ::= reset_rules rule COMMENTEND",
+ /* 18 */ "rules ::= reset_rules PI SUBPATTERN rule COMMENTEND",
+ /* 19 */ "rules ::= reset_rules rule COMMENTEND PHPCODE",
+ /* 20 */ "rules ::= reset_rules PI SUBPATTERN rule COMMENTEND PHPCODE",
+ /* 21 */ "reset_rules ::= rules COMMENTSTART",
+ /* 22 */ "rule ::= rule_subpattern CODE",
+ /* 23 */ "rule ::= rule rule_subpattern CODE",
+ /* 24 */ "rule_subpattern ::= QUOTE",
+ /* 25 */ "rule_subpattern ::= SINGLEQUOTE",
+ /* 26 */ "rule_subpattern ::= SUBPATTERN",
+ /* 27 */ "rule_subpattern ::= rule_subpattern QUOTE",
+ /* 28 */ "rule_subpattern ::= rule_subpattern SINGLEQUOTE",
+ /* 29 */ "rule_subpattern ::= rule_subpattern SUBPATTERN",
+ /* 30 */ "subpattern ::= QUOTE",
+ /* 31 */ "subpattern ::= SINGLEQUOTE",
+ /* 32 */ "subpattern ::= SUBPATTERN",
+ /* 33 */ "subpattern ::= subpattern QUOTE",
+ /* 34 */ "subpattern ::= subpattern SINGLEQUOTE",
+ /* 35 */ "subpattern ::= subpattern SUBPATTERN",
+ );
+
+ /**
+ * This function returns the symbolic name associated with a token
+ * value.
+ * @param int
+ * @return string
+ */
+ function tokenName($tokenType)
+ {
+ if ($tokenType === 0) {
+ return 'End of Input';
+ }
+ if ($tokenType > 0 && $tokenType < count(self::$yyTokenName)) {
+ return self::$yyTokenName[$tokenType];
+ } else {
+ return "Unknown";
+ }
+ }
+
+ /**
+ * The following function deletes the value associated with a
+ * symbol. The symbol can be either a terminal or nonterminal.
+ * @param int the symbol code
+ * @param mixed the symbol's value
+ */
+ static function yy_destructor($yymajor, $yypminor)
+ {
+ switch ($yymajor) {
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
+ ** reduce or during error processing or when a parser is
+ ** being destroyed before it is finished parsing.
+ **
+ ** Note: during a reduce, the only symbols destroyed are those
+ ** which appear on the RHS of the rule, but which are not used
+ ** inside the C code.
+ */
+ default: break; /* If no destructor action specified: do nothing */
+ }
+ }
+
+ /**
+ * Pop the parser's stack once.
+ *
+ * If there is a destructor routine associated with the token which
+ * is popped from the stack, then call it.
+ *
+ * Return the major token number for the symbol popped.
+ * @param PHP_LexerGenerator_ParseryyParser
+ * @return int
+ */
+ function yy_pop_parser_stack()
+ {
+ if (!count($this->yystack)) {
+ return;
+ }
+ $yytos = array_pop($this->yystack);
+ if (self::$yyTraceFILE && $this->yyidx >= 0) {
+ fwrite(self::$yyTraceFILE,
+ self::$yyTracePrompt . 'Popping ' . self::$yyTokenName[$yytos->major] .
+ "\n");
+ }
+ $yymajor = $yytos->major;
+ self::yy_destructor($yymajor, $yytos->minor);
+ $this->yyidx--;
+ return $yymajor;
+ }
+
+ /**
+ * Deallocate and destroy a parser. Destructors are all called for
+ * all stack elements before shutting the parser down.
+ */
+ function __destruct()
+ {
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ if (is_resource(self::$yyTraceFILE)) {
+ fclose(self::$yyTraceFILE);
+ }
+ }
+
+ /**
+ * Based on the current state and parser stack, get a list of all
+ * possible lookahead tokens
+ * @param int
+ * @return array
+ */
+ function yy_get_expected_tokens($token)
+ {
+ $state = $this->yystack[$this->yyidx]->stateno;
+ $expected = self::$yyExpectedTokens[$state];
+ if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return $expected;
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return array_unique($expected);
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+ $nextstate = $this->yy_find_reduce_action(
+ $this->yystack[$this->yyidx]->stateno,
+ self::$yyRuleInfo[$yyruleno]['lhs']);
+ if (isset(self::$yyExpectedTokens[$nextstate])) {
+ $expected += self::$yyExpectedTokens[$nextstate];
+ if (in_array($token,
+ self::$yyExpectedTokens[$nextstate], true)) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return array_unique($expected);
+ }
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new PHP_LexerGenerator_ParseryyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return array_unique($expected);
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return $expected;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ return array_unique($expected);
+ }
+
+ /**
+ * Based on the parser state and current parser stack, determine whether
+ * the lookahead token is possible.
+ *
+ * The parser will convert the token value to an error token if not. This
+ * catches some unusual edge cases where the parser would fail.
+ * @param int
+ * @return bool
+ */
+ function yy_is_expected_token($token)
+ {
+ if ($token === 0) {
+ return true; // 0 is not part of this
+ }
+ $state = $this->yystack[$this->yyidx]->stateno;
+ if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return true;
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return true;
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+ $nextstate = $this->yy_find_reduce_action(
+ $this->yystack[$this->yyidx]->stateno,
+ self::$yyRuleInfo[$yyruleno]['lhs']);
+ if (isset(self::$yyExpectedTokens[$nextstate]) &&
+ in_array($token, self::$yyExpectedTokens[$nextstate], true)) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new PHP_LexerGenerator_ParseryyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ if (!$token) {
+ // end of input: this is valid
+ return true;
+ }
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return false;
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return true;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+
+ /**
+ * Find the appropriate action for a parser given the terminal
+ * look-ahead token iLookAhead.
+ *
+ * If the look-ahead token is YYNOCODE, then check to see if the action is
+ * independent of the look-ahead. If it is, return the action, otherwise
+ * return YY_NO_ACTION.
+ * @param int The look-ahead token
+ */
+ function yy_find_shift_action($iLookAhead)
+ {
+ $stateno = $this->yystack[$this->yyidx]->stateno;
+
+ /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */
+ if (!isset(self::$yy_shift_ofst[$stateno])) {
+ // no shift actions
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_shift_ofst[$stateno];
+ if ($i === self::YY_SHIFT_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+ self::$yy_lookahead[$i] != $iLookAhead) {
+ if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback)
+ && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) {
+ if (self::$yyTraceFILE) {
+ fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " .
+ self::$yyTokenName[$iLookAhead] . " => " .
+ self::$yyTokenName[$iFallback] . "\n");
+ }
+ return $this->yy_find_shift_action($iFallback);
+ }
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ /**
+ * Find the appropriate action for a parser given the non-terminal
+ * look-ahead token $iLookAhead.
+ *
+ * If the look-ahead token is self::YYNOCODE, then check to see if the action is
+ * independent of the look-ahead. If it is, return the action, otherwise
+ * return self::YY_NO_ACTION.
+ * @param int Current state number
+ * @param int The look-ahead token
+ */
+ function yy_find_reduce_action($stateno, $iLookAhead)
+ {
+ /* $stateno = $this->yystack[$this->yyidx]->stateno; */
+
+ if (!isset(self::$yy_reduce_ofst[$stateno])) {
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_reduce_ofst[$stateno];
+ if ($i == self::YY_REDUCE_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+ self::$yy_lookahead[$i] != $iLookAhead) {
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ /**
+ * Perform a shift action.
+ * @param int The new state to shift in
+ * @param int The major token to shift in
+ * @param mixed the minor token to shift in
+ */
+ function yy_shift($yyNewState, $yyMajor, $yypMinor)
+ {
+ $this->yyidx++;
+ if ($this->yyidx >= self::YYSTACKDEPTH) {
+ $this->yyidx--;
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will execute if the parser
+ ** stack ever overflows */
+ return;
+ }
+ $yytos = new PHP_LexerGenerator_ParseryyStackEntry;
+ $yytos->stateno = $yyNewState;
+ $yytos->major = $yyMajor;
+ $yytos->minor = $yypMinor;
+ array_push($this->yystack, $yytos);
+ if (self::$yyTraceFILE && $this->yyidx > 0) {
+ fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt,
+ $yyNewState);
+ fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt);
+ for($i = 1; $i <= $this->yyidx; $i++) {
+ fprintf(self::$yyTraceFILE, " %s",
+ self::$yyTokenName[$this->yystack[$i]->major]);
+ }
+ fwrite(self::$yyTraceFILE,"\n");
+ }
+ }
+
+ /**
+ * The following table contains information about every rule that
+ * is used during the reduce.
+ *
+ *
+ * array(
+ * array(
+ * int $lhs; Symbol on the left-hand side of the rule
+ * int $nrhs; Number of right-hand side symbols in the rule
+ * ),...
+ * );
+ *
+ */
+ static public $yyRuleInfo = array(
+ array( 'lhs' => 11, 'rhs' => 1 ),
+ array( 'lhs' => 12, 'rhs' => 2 ),
+ array( 'lhs' => 12, 'rhs' => 3 ),
+ array( 'lhs' => 12, 'rhs' => 3 ),
+ array( 'lhs' => 12, 'rhs' => 4 ),
+ array( 'lhs' => 13, 'rhs' => 3 ),
+ array( 'lhs' => 15, 'rhs' => 2 ),
+ array( 'lhs' => 16, 'rhs' => 2 ),
+ array( 'lhs' => 16, 'rhs' => 2 ),
+ array( 'lhs' => 16, 'rhs' => 3 ),
+ array( 'lhs' => 16, 'rhs' => 3 ),
+ array( 'lhs' => 17, 'rhs' => 2 ),
+ array( 'lhs' => 17, 'rhs' => 3 ),
+ array( 'lhs' => 14, 'rhs' => 3 ),
+ array( 'lhs' => 14, 'rhs' => 5 ),
+ array( 'lhs' => 14, 'rhs' => 4 ),
+ array( 'lhs' => 14, 'rhs' => 6 ),
+ array( 'lhs' => 14, 'rhs' => 3 ),
+ array( 'lhs' => 14, 'rhs' => 5 ),
+ array( 'lhs' => 14, 'rhs' => 4 ),
+ array( 'lhs' => 14, 'rhs' => 6 ),
+ array( 'lhs' => 20, 'rhs' => 2 ),
+ array( 'lhs' => 19, 'rhs' => 2 ),
+ array( 'lhs' => 19, 'rhs' => 3 ),
+ array( 'lhs' => 21, 'rhs' => 1 ),
+ array( 'lhs' => 21, 'rhs' => 1 ),
+ array( 'lhs' => 21, 'rhs' => 1 ),
+ array( 'lhs' => 21, 'rhs' => 2 ),
+ array( 'lhs' => 21, 'rhs' => 2 ),
+ array( 'lhs' => 21, 'rhs' => 2 ),
+ array( 'lhs' => 18, 'rhs' => 1 ),
+ array( 'lhs' => 18, 'rhs' => 1 ),
+ array( 'lhs' => 18, 'rhs' => 1 ),
+ array( 'lhs' => 18, 'rhs' => 2 ),
+ array( 'lhs' => 18, 'rhs' => 2 ),
+ array( 'lhs' => 18, 'rhs' => 2 ),
+ );
+
+ /**
+ * The following table contains a mapping of reduce action to method name
+ * that handles the reduction.
+ *
+ * If a rule is not set, it has no handler.
+ */
+ static public $yyReduceMap = array(
+ 1 => 1,
+ 2 => 2,
+ 3 => 3,
+ 4 => 4,
+ 5 => 5,
+ 6 => 6,
+ 7 => 7,
+ 8 => 7,
+ 9 => 9,
+ 10 => 9,
+ 11 => 11,
+ 12 => 12,
+ 13 => 13,
+ 14 => 14,
+ 15 => 15,
+ 16 => 16,
+ 17 => 17,
+ 18 => 18,
+ 19 => 19,
+ 20 => 20,
+ 21 => 21,
+ 22 => 22,
+ 23 => 23,
+ 24 => 24,
+ 25 => 25,
+ 26 => 26,
+ 27 => 27,
+ 28 => 28,
+ 29 => 29,
+ 30 => 30,
+ 31 => 31,
+ 32 => 32,
+ 33 => 33,
+ 34 => 34,
+ 35 => 35,
+ );
+ /* Beginning here are the reduction cases. A typical example
+ ** follows:
+ ** #line
+ ** function yy_r0($yymsp){ ... } // User supplied code
+ ** #line
+ */
+#line 438 "Parser.y"
+ function yy_r1(){
+ fwrite($this->out, '
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{\'yylex\' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+');
+ foreach ($this->yystack[$this->yyidx + 0]->minor as $rule) {
+ $this->outputRules($rule['rules'], $rule['statename']);
+ if ($rule['code']) {
+ fwrite($this->out, $rule['code']);
+ }
+ }
+ }
+#line 1352 "Parser.php"
+#line 472 "Parser.y"
+ function yy_r2(){
+ fwrite($this->out, '
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{\'yylex\' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+');
+ if (strlen($this->yystack[$this->yyidx + -1]->minor)) {
+ fwrite($this->out, $this->yystack[$this->yyidx + -1]->minor);
+ }
+ foreach ($this->yystack[$this->yyidx + 0]->minor as $rule) {
+ $this->outputRules($rule['rules'], $rule['statename']);
+ if ($rule['code']) {
+ fwrite($this->out, $rule['code']);
+ }
+ }
+ }
+#line 1391 "Parser.php"
+#line 509 "Parser.y"
+ function yy_r3(){
+ if (strlen($this->yystack[$this->yyidx + -2]->minor)) {
+ fwrite($this->out, $this->yystack[$this->yyidx + -2]->minor);
+ }
+ fwrite($this->out, '
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{\'yylex\' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+');
+ foreach ($this->yystack[$this->yyidx + 0]->minor as $rule) {
+ $this->outputRules($rule['rules'], $rule['statename']);
+ if ($rule['code']) {
+ fwrite($this->out, $rule['code']);
+ }
+ }
+ }
+#line 1430 "Parser.php"
+#line 546 "Parser.y"
+ function yy_r4(){
+ if (strlen($this->yystack[$this->yyidx + -3]->minor)) {
+ fwrite($this->out, $this->yystack[$this->yyidx + -3]->minor);
+ }
+ fwrite($this->out, '
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{\'yylex\' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+');
+ if (strlen($this->yystack[$this->yyidx + -1]->minor)) {
+ fwrite($this->out, $this->yystack[$this->yyidx + -1]->minor);
+ }
+ foreach ($this->yystack[$this->yyidx + 0]->minor as $rule) {
+ $this->outputRules($rule['rules'], $rule['statename']);
+ if ($rule['code']) {
+ fwrite($this->out, $rule['code']);
+ }
+ }
+ }
+#line 1472 "Parser.php"
+#line 587 "Parser.y"
+ function yy_r5(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+ $this->patterns = $this->yystack[$this->yyidx + -1]->minor['patterns'];
+ $this->_patternIndex = 1;
+ }
+#line 1479 "Parser.php"
+#line 593 "Parser.y"
+ function yy_r6(){
+ $expected = array(
+ 'counter' => true,
+ 'input' => true,
+ 'token' => true,
+ 'value' => true,
+ 'line' => true,
+ );
+ foreach ($this->yystack[$this->yyidx + -1]->minor as $pi) {
+ if (isset($expected[$pi['pi']])) {
+ unset($expected[$pi['pi']]);
+ continue;
+ }
+ if (count($expected)) {
+ throw new Exception('Processing Instructions "' .
+ implode(', ', array_keys($expected)) . '" must be defined');
+ }
+ }
+ $expected = array(
+ 'caseinsensitive' => true,
+ 'counter' => true,
+ 'input' => true,
+ 'token' => true,
+ 'value' => true,
+ 'line' => true,
+ 'matchlongest' => true,
+ 'unicode' => true,
+ );
+ foreach ($this->yystack[$this->yyidx + -1]->minor as $pi) {
+ if (isset($expected[$pi['pi']])) {
+ $this->{$pi['pi']} = $pi['definition'];
+ if ($pi['pi'] == 'matchlongest') {
+ $this->matchlongest = true;
+ }
+ continue;
+ }
+ $this->error('Unknown processing instruction %' . $pi['pi'] .
+ ', should be one of "' . implode(', ', array_keys($expected)) . '"');
+ }
+ $this->patternFlags = ($this->caseinsensitive ? 'i' : '')
+ . ($this->unicode ? 'u' : '');
+ $this->_retvalue = array('patterns' => $this->yystack[$this->yyidx + 0]->minor, 'pis' => $this->yystack[$this->yyidx + -1]->minor);
+ $this->_patternIndex = 1;
+ }
+#line 1525 "Parser.php"
+#line 638 "Parser.y"
+ function yy_r7(){
+ $this->_retvalue = array(array('pi' => $this->yystack[$this->yyidx + -1]->minor, 'definition' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1530 "Parser.php"
+#line 644 "Parser.y"
+ function yy_r9(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
+ $this->_retvalue[] = array('pi' => $this->yystack[$this->yyidx + -1]->minor, 'definition' => $this->yystack[$this->yyidx + 0]->minor);
+ }
+#line 1536 "Parser.php"
+#line 653 "Parser.y"
+ function yy_r11(){
+ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor => $this->yystack[$this->yyidx + 0]->minor);
+ // reset internal indicator of where we are in a pattern
+ $this->_patternIndex = 0;
+ }
+#line 1543 "Parser.php"
+#line 658 "Parser.y"
+ function yy_r12(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
+ if (isset($this->_retvalue[$this->yystack[$this->yyidx + -1]->minor])) {
+ throw new Exception('Pattern "' . $this->yystack[$this->yyidx + -1]->minor . '" is already defined as "' .
+ $this->_retvalue[$this->yystack[$this->yyidx + -1]->minor] . '", cannot redefine as "' . $this->yystack[$this->yyidx + 0]->minor->string . '"');
+ }
+ $this->_retvalue[$this->yystack[$this->yyidx + -1]->minor] = $this->yystack[$this->yyidx + 0]->minor;
+ // reset internal indicator of where we are in a pattern declaration
+ $this->_patternIndex = 0;
+ }
+#line 1555 "Parser.php"
+#line 669 "Parser.y"
+ function yy_r13(){
+ $this->_retvalue = array(array('rules' => $this->yystack[$this->yyidx + -1]->minor, 'code' => '', 'statename' => ''));
+ }
+#line 1560 "Parser.php"
+#line 672 "Parser.y"
+ function yy_r14(){
+ if ($this->yystack[$this->yyidx + -3]->minor != 'statename') {
+ throw new Exception('Error: only %statename processing instruction ' .
+ 'is allowed in rule sections (found ' . $this->yystack[$this->yyidx + -3]->minor . ').');
+ }
+ $this->_retvalue = array(array('rules' => $this->yystack[$this->yyidx + -1]->minor, 'code' => '', 'statename' => $this->yystack[$this->yyidx + -2]->minor));
+ }
+#line 1569 "Parser.php"
+#line 679 "Parser.y"
+ function yy_r15(){
+ $this->_retvalue = array(array('rules' => $this->yystack[$this->yyidx + -2]->minor, 'code' => $this->yystack[$this->yyidx + 0]->minor, 'statename' => ''));
+ }
+#line 1574 "Parser.php"
+#line 682 "Parser.y"
+ function yy_r16(){
+ if ($this->yystack[$this->yyidx + -4]->minor != 'statename') {
+ throw new Exception('Error: only %statename processing instruction ' .
+ 'is allowed in rule sections (found ' . $this->yystack[$this->yyidx + -4]->minor . ').');
+ }
+ $this->_retvalue = array(array('rules' => $this->yystack[$this->yyidx + -2]->minor, 'code' => $this->yystack[$this->yyidx + 0]->minor, 'statename' => $this->yystack[$this->yyidx + -3]->minor));
+ $this->_patternIndex = 1;
+ }
+#line 1584 "Parser.php"
+#line 690 "Parser.y"
+ function yy_r17(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
+ $this->_retvalue[] = array('rules' => $this->yystack[$this->yyidx + -1]->minor, 'code' => '', 'statename' => '');
+ $this->_patternIndex = 1;
+ }
+#line 1591 "Parser.php"
+#line 695 "Parser.y"
+ function yy_r18(){
+ if ($this->yystack[$this->yyidx + -3]->minor != 'statename') {
+ throw new Exception('Error: only %statename processing instruction ' .
+ 'is allowed in rule sections (found ' . $this->yystack[$this->yyidx + -3]->minor . ').');
+ }
+ $this->_retvalue = $this->yystack[$this->yyidx + -4]->minor;
+ $this->_retvalue[] = array('rules' => $this->yystack[$this->yyidx + -1]->minor, 'code' => '', 'statename' => $this->yystack[$this->yyidx + -2]->minor);
+ }
+#line 1601 "Parser.php"
+#line 703 "Parser.y"
+ function yy_r19(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor;
+ $this->_retvalue[] = array('rules' => $this->yystack[$this->yyidx + -2]->minor, 'code' => $this->yystack[$this->yyidx + 0]->minor, 'statename' => '');
+ }
+#line 1607 "Parser.php"
+#line 707 "Parser.y"
+ function yy_r20(){
+ if ($this->yystack[$this->yyidx + -4]->minor != 'statename') {
+ throw new Exception('Error: only %statename processing instruction ' .
+ 'is allowed in rule sections (found ' . $this->yystack[$this->yyidx + -4]->minor . ').');
+ }
+ $this->_retvalue = $this->yystack[$this->yyidx + -5]->minor;
+ $this->_retvalue[] = array('rules' => $this->yystack[$this->yyidx + -2]->minor, 'code' => $this->yystack[$this->yyidx + 0]->minor, 'statename' => $this->yystack[$this->yyidx + -3]->minor);
+ }
+#line 1617 "Parser.php"
+#line 716 "Parser.y"
+ function yy_r21(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+ $this->_patternIndex = 1;
+ }
+#line 1623 "Parser.php"
+#line 721 "Parser.y"
+ function yy_r22(){
+ $name = $this->yystack[$this->yyidx + -1]->minor[1];
+ $this->yystack[$this->yyidx + -1]->minor = $this->yystack[$this->yyidx + -1]->minor[0];
+ $this->yystack[$this->yyidx + -1]->minor = $this->_validatePattern($this->yystack[$this->yyidx + -1]->minor);
+ $this->_patternIndex += $this->yystack[$this->yyidx + -1]->minor['subpatterns'] + 1;
+ if (@preg_match('/' . str_replace('/', '\\/', $this->yystack[$this->yyidx + -1]->minor['pattern']) . '/', '')) {
+ $this->error('Rule "' . $name . '" can match the empty string, this will break lexing');
+ }
+ $this->_retvalue = array(array('pattern' => str_replace('/', '\\/', $this->yystack[$this->yyidx + -1]->minor->string), 'code' => $this->yystack[$this->yyidx + 0]->minor, 'subpatterns' => $this->yystack[$this->yyidx + -1]->minor['subpatterns']));
+ }
+#line 1635 "Parser.php"
+#line 731 "Parser.y"
+ function yy_r23(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
+ $name = $this->yystack[$this->yyidx + -1]->minor[1];
+ $this->yystack[$this->yyidx + -1]->minor = $this->yystack[$this->yyidx + -1]->minor[0];
+ $this->yystack[$this->yyidx + -1]->minor = $this->_validatePattern($this->yystack[$this->yyidx + -1]->minor);
+ $this->_patternIndex += $this->yystack[$this->yyidx + -1]->minor['subpatterns'] + 1;
+ if (@preg_match('/' . str_replace('/', '\\/', $this->yystack[$this->yyidx + -1]->minor['pattern']) . '/', '')) {
+ $this->error('Rule "' . $name . '" can match the empty string, this will break lexing');
+ }
+ $this->_retvalue[] = array('pattern' => str_replace('/', '\\/', $this->yystack[$this->yyidx + -1]->minor->string), 'code' => $this->yystack[$this->yyidx + 0]->minor, 'subpatterns' => $this->yystack[$this->yyidx + -1]->minor['subpatterns']);
+ }
+#line 1648 "Parser.php"
+#line 743 "Parser.y"
+ function yy_r24(){
+ $this->_retvalue = array(preg_quote($this->yystack[$this->yyidx + 0]->minor, '/'), $this->yystack[$this->yyidx + 0]->minor);
+ }
+#line 1653 "Parser.php"
+#line 746 "Parser.y"
+ function yy_r25(){
+ $this->_retvalue = array($this->makeCaseInsensitve(preg_quote($this->yystack[$this->yyidx + 0]->minor, '/')), $this->yystack[$this->yyidx + 0]->minor);
+ }
+#line 1658 "Parser.php"
+#line 749 "Parser.y"
+ function yy_r26(){
+ if (!isset($this->patterns[$this->yystack[$this->yyidx + 0]->minor])) {
+ $this->error('Undefined pattern "' . $this->yystack[$this->yyidx + 0]->minor . '" used in rules');
+ throw new Exception('Undefined pattern "' . $this->yystack[$this->yyidx + 0]->minor . '" used in rules');
+ }
+ $this->_retvalue = array($this->patterns[$this->yystack[$this->yyidx + 0]->minor], $this->yystack[$this->yyidx + 0]->minor);
+ }
+#line 1667 "Parser.php"
+#line 756 "Parser.y"
+ function yy_r27(){
+ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor[0] . preg_quote($this->yystack[$this->yyidx + 0]->minor, '/'), $this->yystack[$this->yyidx + -1]->minor[1] . ' ' . $this->yystack[$this->yyidx + 0]->minor);
+ }
+#line 1672 "Parser.php"
+#line 759 "Parser.y"
+ function yy_r28(){
+ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor[0] . $this->makeCaseInsensitve(preg_quote($this->yystack[$this->yyidx + 0]->minor, '/')), $this->yystack[$this->yyidx + -1]->minor[1] . ' ' . $this->yystack[$this->yyidx + 0]->minor);
+ }
+#line 1677 "Parser.php"
+#line 762 "Parser.y"
+ function yy_r29(){
+ if (!isset($this->patterns[$this->yystack[$this->yyidx + 0]->minor])) {
+ $this->error('Undefined pattern "' . $this->yystack[$this->yyidx + 0]->minor . '" used in rules');
+ throw new Exception('Undefined pattern "' . $this->yystack[$this->yyidx + 0]->minor . '" used in rules');
+ }
+ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor[0] . $this->patterns[$this->yystack[$this->yyidx + 0]->minor], $this->yystack[$this->yyidx + -1]->minor[1] . ' ' . $this->yystack[$this->yyidx + 0]->minor);
+ }
+#line 1686 "Parser.php"
+#line 770 "Parser.y"
+ function yy_r30(){
+ $this->_retvalue = preg_quote($this->yystack[$this->yyidx + 0]->minor, '/');
+ }
+#line 1691 "Parser.php"
+#line 773 "Parser.y"
+ function yy_r31(){
+ $this->_retvalue = $this->makeCaseInsensitve(preg_quote($this->yystack[$this->yyidx + 0]->minor, '/'));
+ }
+#line 1696 "Parser.php"
+#line 776 "Parser.y"
+ function yy_r32(){
+ // increment internal sub-pattern counter
+ // adjust back-references in pattern based on previous pattern
+ $test = $this->_validatePattern($this->yystack[$this->yyidx + 0]->minor, true);
+ $this->_patternIndex += $test['subpatterns'];
+ $this->_retvalue = $test['pattern'];
+ }
+#line 1705 "Parser.php"
+#line 783 "Parser.y"
+ function yy_r33(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . preg_quote($this->yystack[$this->yyidx + 0]->minor, '/');
+ }
+#line 1710 "Parser.php"
+#line 786 "Parser.y"
+ function yy_r34(){
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . $this->makeCaseInsensitve(preg_quote($this->yystack[$this->yyidx + 0]->minor, '/'));
+ }
+#line 1715 "Parser.php"
+#line 789 "Parser.y"
+ function yy_r35(){
+ // increment internal sub-pattern counter
+ // adjust back-references in pattern based on previous pattern
+ $test = $this->_validatePattern($this->yystack[$this->yyidx + 0]->minor, true);
+ $this->_patternIndex += $test['subpatterns'];
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . $test['pattern'];
+ }
+#line 1724 "Parser.php"
+
+ /**
+ * placeholder for the left hand side in a reduce operation.
+ *
+ * For a parser with a rule like this:
+ *
+ * rule(A) ::= B. { A = 1; }
+ *
+ *
+ * The parser will translate to something like:
+ *
+ *
+ * function yy_r0(){$this->_retvalue = 1;}
+ *
+ */
+ private $_retvalue;
+
+ /**
+ * Perform a reduce action and the shift that must immediately
+ * follow the reduce.
+ *
+ * For a rule such as:
+ *
+ *
+ * A ::= B blah C. { dosomething(); }
+ *
+ *
+ * This function will first call the action, if any, ("dosomething();" in our
+ * example), and then it will pop three states from the stack,
+ * one for each entry on the right-hand side of the expression
+ * (B, blah, and C in our example rule), and then push the result of the action
+ * back on to the stack with the resulting state reduced to (as described in the .out
+ * file)
+ * @param int Number of the rule by which to reduce
+ */
+ function yy_reduce($yyruleno)
+ {
+ //int $yygoto; /* The next state */
+ //int $yyact; /* The next action */
+ //mixed $yygotominor; /* The LHS of the rule reduced */
+ //PHP_LexerGenerator_ParseryyStackEntry $yymsp; /* The top of the parser's stack */
+ //int $yysize; /* Amount to pop the stack */
+ $yymsp = $this->yystack[$this->yyidx];
+ if (self::$yyTraceFILE && $yyruleno >= 0
+ && $yyruleno < count(self::$yyRuleName)) {
+ fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n",
+ self::$yyTracePrompt, $yyruleno,
+ self::$yyRuleName[$yyruleno]);
+ }
+
+ $this->_retvalue = $yy_lefthand_side = null;
+ if (array_key_exists($yyruleno, self::$yyReduceMap)) {
+ // call the action
+ $this->_retvalue = null;
+ $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}();
+ $yy_lefthand_side = $this->_retvalue;
+ }
+ $yygoto = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $yysize = self::$yyRuleInfo[$yyruleno]['rhs'];
+ $this->yyidx -= $yysize;
+ for($i = $yysize; $i; $i--) {
+ // pop all of the right-hand side parameters
+ array_pop($this->yystack);
+ }
+ $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto);
+ if ($yyact < self::YYNSTATE) {
+ /* If we are not debugging and the reduce action popped at least
+ ** one element off the stack, then we can push the new element back
+ ** onto the stack here, and skip the stack overflow test in yy_shift().
+ ** That gives a significant speed improvement. */
+ if (!self::$yyTraceFILE && $yysize) {
+ $this->yyidx++;
+ $x = new PHP_LexerGenerator_ParseryyStackEntry;
+ $x->stateno = $yyact;
+ $x->major = $yygoto;
+ $x->minor = $yy_lefthand_side;
+ $this->yystack[$this->yyidx] = $x;
+ } else {
+ $this->yy_shift($yyact, $yygoto, $yy_lefthand_side);
+ }
+ } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yy_accept();
+ }
+ }
+
+ /**
+ * The following code executes when the parse fails
+ *
+ * Code from %parse_fail is inserted here
+ */
+ function yy_parse_failed()
+ {
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+ }
+
+ /**
+ * The following code executes when a syntax error first occurs.
+ *
+ * %syntax_error code is inserted here
+ * @param int The major type of the error token
+ * @param mixed The minor type of the error token
+ */
+ function yy_syntax_error($yymajor, $TOKEN)
+ {
+#line 70 "Parser.y"
+
+ echo "Syntax Error on line " . $this->lex->line . ": token '" .
+ $this->lex->value . "' while parsing rule:";
+ foreach ($this->yystack as $entry) {
+ echo $this->tokenName($entry->major) . ' ';
+ }
+ foreach ($this->yy_get_expected_tokens($yymajor) as $token) {
+ $expect[] = self::$yyTokenName[$token];
+ }
+ throw new Exception('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN
+ . '), expected one of: ' . implode(',', $expect));
+#line 1849 "Parser.php"
+ }
+
+ /**
+ * The following is executed when the parser accepts
+ *
+ * %parse_accept code is inserted here
+ */
+ function yy_accept()
+ {
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $stack = $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+ }
+
+ /**
+ * The main parser program.
+ *
+ * The first argument is the major token number. The second is
+ * the token value string as scanned from the input.
+ *
+ * @param int the token number
+ * @param mixed the token value
+ * @param mixed any extra arguments that should be passed to handlers
+ */
+ function doParse($yymajor, $yytokenvalue)
+ {
+// $yyact; /* The parser action. */
+// $yyendofinput; /* True if we are at the end of input */
+ $yyerrorhit = 0; /* True if yymajor has invoked an error */
+
+ /* (re)initialize the parser, if necessary */
+ if ($this->yyidx === null || $this->yyidx < 0) {
+ /* if ($yymajor == 0) return; // not sure why this was here... */
+ $this->yyidx = 0;
+ $this->yyerrcnt = -1;
+ $x = new PHP_LexerGenerator_ParseryyStackEntry;
+ $x->stateno = 0;
+ $x->major = 0;
+ $this->yystack = array();
+ array_push($this->yystack, $x);
+ }
+ $yyendofinput = ($yymajor==0);
+
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sInput %s\n",
+ self::$yyTracePrompt, self::$yyTokenName[$yymajor]);
+ }
+
+ do {
+ $yyact = $this->yy_find_shift_action($yymajor);
+ if ($yymajor < self::YYERRORSYMBOL &&
+ !$this->yy_is_expected_token($yymajor)) {
+ // force a syntax error
+ $yyact = self::YY_ERROR_ACTION;
+ }
+ if ($yyact < self::YYNSTATE) {
+ $this->yy_shift($yyact, $yymajor, $yytokenvalue);
+ $this->yyerrcnt--;
+ if ($yyendofinput && $this->yyidx >= 0) {
+ $yymajor = 0;
+ } else {
+ $yymajor = self::YYNOCODE;
+ }
+ } elseif ($yyact < self::YYNSTATE + self::YYNRULE) {
+ $this->yy_reduce($yyact - self::YYNSTATE);
+ } elseif ($yyact == self::YY_ERROR_ACTION) {
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sSyntax Error!\n",
+ self::$yyTracePrompt);
+ }
+ if (self::YYERRORSYMBOL) {
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
+ ** grammar defines an error token "ERROR".
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if ($this->yyerrcnt < 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $yymx = $this->yystack[$this->yyidx]->major;
+ if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n",
+ self::$yyTracePrompt, self::$yyTokenName[$yymajor]);
+ }
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $yymajor = self::YYNOCODE;
+ } else {
+ while ($this->yyidx >= 0 &&
+ $yymx != self::YYERRORSYMBOL &&
+ ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE
+ ){
+ $this->yy_pop_parser_stack();
+ }
+ if ($this->yyidx < 0 || $yymajor==0) {
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $this->yy_parse_failed();
+ $yymajor = self::YYNOCODE;
+ } elseif ($yymx != self::YYERRORSYMBOL) {
+ $u2 = 0;
+ $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2);
+ }
+ }
+ $this->yyerrcnt = 3;
+ $yyerrorhit = 1;
+ } else {
+ /* YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if ($this->yyerrcnt <= 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $this->yyerrcnt = 3;
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ if ($yyendofinput) {
+ $this->yy_parse_failed();
+ }
+ $yymajor = self::YYNOCODE;
+ }
+ } else {
+ $this->yy_accept();
+ $yymajor = self::YYNOCODE;
+ }
+ } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
+ }
+}
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/Parser.y b/core/oql/build/PHP/LexerGenerator/Parser.y
new file mode 100644
index 000000000..cfa96d688
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Parser.y
@@ -0,0 +1,795 @@
+%name PHP_LexerGenerator_Parser
+%declare_class {class PHP_LexerGenerator_Parser}
+%include {
+/* ?>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_LexerGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category php
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Parser.y 246683 2007-11-22 04:43:52Z instance $
+ * @since File available since Release 0.1.0
+ */
+/**
+ * For regular expression validation
+ */
+require_once 'PHP/LexerGenerator/Regex/Lexer.php';
+require_once 'PHP/LexerGenerator/Regex/Parser.php';
+require_once 'PHP/LexerGenerator/Exception.php';
+/**
+ * Token parser for plex files.
+ *
+ * This parser converts tokens pulled from {@link PHP_LexerGenerator_Lexer}
+ * into abstract patterns and rules, then creates the output file
+ * @package PHP_LexerGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version @package_version@
+ * @since Class available since Release 0.1.0
+ */
+}
+%syntax_error {
+ echo "Syntax Error on line " . $this->lex->line . ": token '" .
+ $this->lex->value . "' while parsing rule:";
+ foreach ($this->yystack as $entry) {
+ echo $this->tokenName($entry->major) . ' ';
+ }
+ foreach ($this->yy_get_expected_tokens($yymajor) as $token) {
+ $expect[] = self::$yyTokenName[$token];
+ }
+ throw new Exception('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN
+ . '), expected one of: ' . implode(',', $expect));
+}
+%include_class {
+ private $patterns;
+ private $out;
+ private $lex;
+ private $input;
+ private $counter;
+ private $token;
+ private $value;
+ private $line;
+ private $matchlongest;
+ private $_regexLexer;
+ private $_regexParser;
+ private $_patternIndex = 0;
+ private $_outRuleIndex = 1;
+ private $caseinsensitive;
+ private $patternFlags;
+ private $unicode;
+
+ public $transTable = array(
+ 1 => self::PHPCODE,
+ 2 => self::COMMENTSTART,
+ 3 => self::COMMENTEND,
+ 4 => self::QUOTE,
+ 5 => self::SINGLEQUOTE,
+ 6 => self::PATTERN,
+ 7 => self::CODE,
+ 8 => self::SUBPATTERN,
+ 9 => self::PI,
+ );
+
+ function __construct($outfile, $lex)
+ {
+ $this->out = fopen($outfile, 'wb');
+ if (!$this->out) {
+ throw new Exception('unable to open lexer output file "' . $outfile . '"');
+ }
+ $this->lex = $lex;
+ $this->_regexLexer = new PHP_LexerGenerator_Regex_Lexer('');
+ $this->_regexParser = new PHP_LexerGenerator_Regex_Parser($this->_regexLexer);
+ }
+
+ function doLongestMatch($rules, $statename, $ruleindex)
+ {
+ fwrite($this->out, '
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ do {
+ $rules = array(');
+ foreach ($rules as $rule) {
+ fwrite($this->out, '
+ \'/\G' . $rule['pattern'] . '/' . $this->patternFlags . ' \',');
+ }
+ fwrite($this->out, '
+ );
+ $match = false;
+ foreach ($rules as $index => $rule) {
+ if (preg_match($rule, substr(' . $this->input . ', ' .
+ $this->counter . '), $yymatches)) {
+ if ($match) {
+ if (strlen($yymatches[0]) > strlen($match[0][0])) {
+ $match = array($yymatches, $index); // matches, token
+ }
+ } else {
+ $match = array($yymatches, $index);
+ }
+ }
+ }
+ if (!$match) {
+ throw new Exception(\'Unexpected input at line \' . ' . $this->line . ' .
+ \': \' . ' . $this->input . '[' . $this->counter . ']);
+ }
+ ' . $this->token . ' = $match[1];
+ ' . $this->value . ' = $match[0][0];
+ $yysubmatches = $match[0];
+ array_shift($yysubmatches);
+ if (!$yysubmatches) {
+ $yysubmatches = array();
+ }
+ $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}($yysubmatches);
+ if ($r === null) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {');
+ fwrite($this->out, '
+ $yy_yymore_patterns = array_slice($rules, $this->token, true);
+ // yymore is needed
+ do {
+ if (!isset($yy_yymore_patterns[' . $this->token . '])) {
+ throw new Exception(\'cannot do yymore for the last token\');
+ }
+ $match = false;
+ foreach ($yy_yymore_patterns[' . $this->token . '] as $index => $rule) {
+ if (preg_match(\'/\' . $rule . \'/' . $this->patternFlags . '\',
+ ' . $this->input . ', $yymatches, null, ' . $this->counter . ')) {
+ $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
+ if ($match) {
+ if (strlen($yymatches[0]) > strlen($match[0][0])) {
+ $match = array($yymatches, $index); // matches, token
+ }
+ } else {
+ $match = array($yymatches, $index);
+ }
+ }
+ }
+ if (!$match) {
+ throw new Exception(\'Unexpected input at line \' . ' . $this->line . ' .
+ \': \' . ' . $this->input . '[' . $this->counter . ']);
+ }
+ ' . $this->token . ' = $match[1];
+ ' . $this->value . ' = $match[0][0];
+ $yysubmatches = $match[0];
+ array_shift($yysubmatches);
+ if (!$yysubmatches) {
+ $yysubmatches = array();
+ }
+ ' . $this->line . ' = substr_count(' . $this->value . ', "\n");
+ $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}();
+ } while ($r !== null || !$r);
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } else {
+ // accept
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ return true;
+ }
+ }
+ } while (true);
+');
+ }
+
+ function doFirstMatch($rules, $statename, $ruleindex)
+ {
+ $patterns = array();
+ $pattern = '/';
+ $ruleMap = array();
+ $tokenindex = array();
+ $actualindex = 1;
+ $i = 0;
+ foreach ($rules as $rule) {
+ $ruleMap[$i++] = $actualindex;
+ $tokenindex[$actualindex] = $rule['subpatterns'];
+ $actualindex += $rule['subpatterns'] + 1;
+ $patterns[] = '\G(' . $rule['pattern'] . ')';
+ }
+ // Re-index tokencount from zero.
+ $tokencount = array_values($tokenindex);
+ $tokenindex = var_export($tokenindex, true);
+ $tokenindex = explode("\n", $tokenindex);
+ // indent for prettiness
+ $tokenindex = implode("\n ", $tokenindex);
+ $pattern .= implode('|', $patterns);
+ $pattern .= '/' . $this->patternFlags;
+ fwrite($this->out, '
+ $tokenMap = ' . $tokenindex . ';
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ ');
+ fwrite($this->out, '$yy_global_pattern = \'' .
+ $pattern . '\';' . "\n");
+ fwrite($this->out, '
+ do {
+ if (preg_match($yy_global_pattern,' . $this->input . ', $yymatches, null, ' .
+ $this->counter .
+ ')) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
+ if (!count($yymatches)) {
+ throw new Exception(\'Error: lexing failed because a rule matched\' .
+ \' an empty string. Input "\' . substr(' . $this->input . ',
+ ' . $this->counter . ', 5) . \'... state ' . $statename . '\');
+ }
+ next($yymatches); // skip global match
+ ' . $this->token . ' = key($yymatches); // token number
+ if ($tokenMap[' . $this->token . ']) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, ' . $this->token . ' + 1,
+ $tokenMap[' . $this->token . ']);
+ } else {
+ $yysubmatches = array();
+ }
+ ' . $this->value . ' = current($yymatches); // token value
+ $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}($yysubmatches);
+ if ($r === null) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {');
+ fwrite($this->out, '
+ $yy_yymore_patterns = array(' . "\n");
+ $extra = 0;
+ for($i = 0; count($patterns); $i++) {
+ unset($patterns[$i]);
+ $extra += $tokencount[0];
+ array_shift($tokencount);
+ fwrite($this->out, ' ' . $ruleMap[$i] . ' => array(' . $extra . ', "' .
+ implode('|', $patterns) . "\"),\n");
+ }
+ fwrite($this->out, ' );' . "\n");
+ fwrite($this->out, '
+ // yymore is needed
+ do {
+ if (!strlen($yy_yymore_patterns[' . $this->token . '][1])) {
+ throw new Exception(\'cannot do yymore for the last token\');
+ }
+ $yysubmatches = array();
+ if (preg_match(\'/\' . $yy_yymore_patterns[' . $this->token . '][1] . \'/' . $this->patternFlags . '\',
+ ' . $this->input . ', $yymatches, null, ' . $this->counter .')) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
+ next($yymatches); // skip global match
+ ' . $this->token . ' += key($yymatches) + $yy_yymore_patterns[' . $this->token . '][0]; // token number
+ ' . $this->value . ' = current($yymatches); // token value
+ ' . $this->line . ' = substr_count(' . $this->value . ', "\n");
+ if ($tokenMap[' . $this->token . ']) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, ' . $this->token . ' + 1,
+ $tokenMap[' . $this->token . ']);
+ } else {
+ $yysubmatches = array();
+ }
+ }
+ $r = $this->{\'yy_r' . $ruleindex . '_\' . ' . $this->token . '}($yysubmatches);
+ } while ($r !== null && !is_bool($r));
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ if (' . $this->counter . ' >= strlen(' . $this->input . ')) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ // accept
+ ' . $this->counter . ' += strlen(' . $this->value . ');
+ ' . $this->line . ' += substr_count(' . $this->value . ', "\n");
+ return true;
+ }
+ }
+ } else {
+ throw new Exception(\'Unexpected input at line\' . ' . $this->line . ' .
+ \': \' . ' . $this->input . '[' . $this->counter . ']);
+ }
+ break;
+ } while (true);
+');
+ }
+
+ function makeCaseInsensitve($string)
+ {
+ return preg_replace('/[a-z]/ie', "'[\\0'.strtoupper('\\0').']'", strtolower($string));
+ }
+
+ function outputRules($rules, $statename)
+ {
+ if (!$statename) {
+ $statename = $this -> _outRuleIndex;
+ }
+ fwrite($this->out, '
+ function yylex' . $this -> _outRuleIndex . '()
+ {');
+ if ($this->matchlongest) {
+ $ruleMap = array();
+ foreach ($rules as $i => $rule) {
+ $ruleMap[$i] = $i;
+ }
+ $this->doLongestMatch($rules, $statename, $this -> _outRuleIndex);
+ } else {
+ $ruleMap = array();
+ $actualindex = 1;
+ $i = 0;
+ foreach ($rules as $rule) {
+ $ruleMap[$i++] = $actualindex;
+ $actualindex += $rule['subpatterns'] + 1;
+ }
+ $this->doFirstMatch($rules, $statename, $this -> _outRuleIndex);
+ }
+ fwrite($this->out, '
+ } // end function
+
+');
+ if (is_string($statename)) {
+ fwrite($this->out, '
+ const ' . $statename . ' = ' . $this -> _outRuleIndex . ';
+');
+ }
+ foreach ($rules as $i => $rule) {
+ fwrite($this->out, ' function yy_r' . $this -> _outRuleIndex . '_' . $ruleMap[$i] . '($yy_subpatterns)
+ {
+' . $rule['code'] .
+' }
+');
+ }
+ $this -> _outRuleIndex++; // for next set of rules
+ }
+
+ function error($msg)
+ {
+ echo 'Error on line ' . $this->lex->line . ': ' , $msg;
+ }
+
+ function _validatePattern($pattern, $update = false)
+ {
+ $this->_regexLexer->reset($pattern, $this->lex->line);
+ $this->_regexParser->reset($this->_patternIndex, $update);
+ try {
+ while ($this->_regexLexer->yylex()) {
+ $this->_regexParser->doParse(
+ $this->_regexLexer->token, $this->_regexLexer->value);
+ }
+ $this->_regexParser->doParse(0, 0);
+ } catch (PHP_LexerGenerator_Exception $e) {
+ $this->error($e->getMessage());
+ throw new PHP_LexerGenerator_Exception('Invalid pattern "' . $pattern . '"');
+ }
+ return $this->_regexParser->result;
+ }
+}
+
+start ::= lexfile.
+
+lexfile ::= declare rules(B). {
+ fwrite($this->out, '
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{\'yylex\' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+');
+ foreach (B as $rule) {
+ $this->outputRules($rule['rules'], $rule['statename']);
+ if ($rule['code']) {
+ fwrite($this->out, $rule['code']);
+ }
+ }
+}
+lexfile ::= declare(D) PHPCODE(B) rules(C). {
+ fwrite($this->out, '
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{\'yylex\' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+');
+ if (strlen(B)) {
+ fwrite($this->out, B);
+ }
+ foreach (C as $rule) {
+ $this->outputRules($rule['rules'], $rule['statename']);
+ if ($rule['code']) {
+ fwrite($this->out, $rule['code']);
+ }
+ }
+}
+lexfile ::= PHPCODE(B) declare(D) rules(C). {
+ if (strlen(B)) {
+ fwrite($this->out, B);
+ }
+ fwrite($this->out, '
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{\'yylex\' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+');
+ foreach (C as $rule) {
+ $this->outputRules($rule['rules'], $rule['statename']);
+ if ($rule['code']) {
+ fwrite($this->out, $rule['code']);
+ }
+ }
+}
+lexfile ::= PHPCODE(A) declare(D) PHPCODE(B) rules(C). {
+ if (strlen(A)) {
+ fwrite($this->out, A);
+ }
+ fwrite($this->out, '
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{\'yylex\' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+');
+ if (strlen(B)) {
+ fwrite($this->out, B);
+ }
+ foreach (C as $rule) {
+ $this->outputRules($rule['rules'], $rule['statename']);
+ if ($rule['code']) {
+ fwrite($this->out, $rule['code']);
+ }
+ }
+}
+
+declare(A) ::= COMMENTSTART declarations(B) COMMENTEND. {
+ A = B;
+ $this->patterns = B['patterns'];
+ $this->_patternIndex = 1;
+}
+
+declarations(A) ::= processing_instructions(B) pattern_declarations(C). {
+ $expected = array(
+ 'counter' => true,
+ 'input' => true,
+ 'token' => true,
+ 'value' => true,
+ 'line' => true,
+ );
+ foreach (B as $pi) {
+ if (isset($expected[$pi['pi']])) {
+ unset($expected[$pi['pi']]);
+ continue;
+ }
+ if (count($expected)) {
+ throw new Exception('Processing Instructions "' .
+ implode(', ', array_keys($expected)) . '" must be defined');
+ }
+ }
+ $expected = array(
+ 'caseinsensitive' => true,
+ 'counter' => true,
+ 'input' => true,
+ 'token' => true,
+ 'value' => true,
+ 'line' => true,
+ 'matchlongest' => true,
+ 'unicode' => true,
+ );
+ foreach (B as $pi) {
+ if (isset($expected[$pi['pi']])) {
+ $this->{$pi['pi']} = $pi['definition'];
+ if ($pi['pi'] == 'matchlongest') {
+ $this->matchlongest = true;
+ }
+ continue;
+ }
+ $this->error('Unknown processing instruction %' . $pi['pi'] .
+ ', should be one of "' . implode(', ', array_keys($expected)) . '"');
+ }
+ $this->patternFlags = ($this->caseinsensitive ? 'i' : '')
+ . ($this->unicode ? 'u' : '');
+ A = array('patterns' => C, 'pis' => B);
+ $this->_patternIndex = 1;
+}
+
+processing_instructions(A) ::= PI(B) SUBPATTERN(C). {
+ A = array(array('pi' => B, 'definition' => C));
+}
+processing_instructions(A) ::= PI(B) CODE(C). {
+ A = array(array('pi' => B, 'definition' => C));
+}
+processing_instructions(A) ::= processing_instructions(P) PI(B) SUBPATTERN(C). {
+ A = P;
+ A[] = array('pi' => B, 'definition' => C);
+}
+processing_instructions(A) ::= processing_instructions(P) PI(B) CODE(C). {
+ A = P;
+ A[] = array('pi' => B, 'definition' => C);
+}
+
+pattern_declarations(A) ::= PATTERN(B) subpattern(C). {
+ A = array(B => C);
+ // reset internal indicator of where we are in a pattern
+ $this->_patternIndex = 0;
+}
+pattern_declarations(A) ::= pattern_declarations(B) PATTERN(C) subpattern(D). {
+ A = B;
+ if (isset(A[C])) {
+ throw new Exception('Pattern "' . C . '" is already defined as "' .
+ A[C] . '", cannot redefine as "' . D->string . '"');
+ }
+ A[C] = D;
+ // reset internal indicator of where we are in a pattern declaration
+ $this->_patternIndex = 0;
+}
+
+rules(A) ::= COMMENTSTART rule(B) COMMENTEND. {
+ A = array(array('rules' => B, 'code' => '', 'statename' => ''));
+}
+rules(A) ::= COMMENTSTART PI(P) SUBPATTERN(S) rule(B) COMMENTEND. {
+ if (P != 'statename') {
+ throw new Exception('Error: only %statename processing instruction ' .
+ 'is allowed in rule sections (found ' . P . ').');
+ }
+ A = array(array('rules' => B, 'code' => '', 'statename' => S));
+}
+rules(A) ::= COMMENTSTART rule(B) COMMENTEND PHPCODE(C). {
+ A = array(array('rules' => B, 'code' => C, 'statename' => ''));
+}
+rules(A) ::= COMMENTSTART PI(P) SUBPATTERN(S) rule(B) COMMENTEND PHPCODE(C). {
+ if (P != 'statename') {
+ throw new Exception('Error: only %statename processing instruction ' .
+ 'is allowed in rule sections (found ' . P . ').');
+ }
+ A = array(array('rules' => B, 'code' => C, 'statename' => S));
+ $this->_patternIndex = 1;
+}
+rules(A) ::= reset_rules(R) rule(B) COMMENTEND. {
+ A = R;
+ A[] = array('rules' => B, 'code' => '', 'statename' => '');
+ $this->_patternIndex = 1;
+}
+rules(A) ::= reset_rules(R) PI(P) SUBPATTERN(S) rule(B) COMMENTEND. {
+ if (P != 'statename') {
+ throw new Exception('Error: only %statename processing instruction ' .
+ 'is allowed in rule sections (found ' . P . ').');
+ }
+ A = R;
+ A[] = array('rules' => B, 'code' => '', 'statename' => S);
+}
+rules(A) ::= reset_rules(R) rule(B) COMMENTEND PHPCODE(C). {
+ A = R;
+ A[] = array('rules' => B, 'code' => C, 'statename' => '');
+}
+rules(A) ::= reset_rules(R) PI(P) SUBPATTERN(S) rule(B) COMMENTEND PHPCODE(C). {
+ if (P != 'statename') {
+ throw new Exception('Error: only %statename processing instruction ' .
+ 'is allowed in rule sections (found ' . P . ').');
+ }
+ A = R;
+ A[] = array('rules' => B, 'code' => C, 'statename' => S);
+}
+
+reset_rules(A) ::= rules(R) COMMENTSTART. {
+ A = R;
+ $this->_patternIndex = 1;
+}
+
+rule(A) ::= rule_subpattern(B) CODE(C). {
+ $name = B[1];
+ B = B[0];
+ B = $this->_validatePattern(B);
+ $this->_patternIndex += B['subpatterns'] + 1;
+ if (@preg_match('/' . str_replace('/', '\\/', B['pattern']) . '/', '')) {
+ $this->error('Rule "' . $name . '" can match the empty string, this will break lexing');
+ }
+ A = array(array('pattern' => str_replace('/', '\\/', B->string), 'code' => C, 'subpatterns' => B['subpatterns']));
+}
+rule(A) ::= rule(R) rule_subpattern(B) CODE(C).{
+ A = R;
+ $name = B[1];
+ B = B[0];
+ B = $this->_validatePattern(B);
+ $this->_patternIndex += B['subpatterns'] + 1;
+ if (@preg_match('/' . str_replace('/', '\\/', B['pattern']) . '/', '')) {
+ $this->error('Rule "' . $name . '" can match the empty string, this will break lexing');
+ }
+ A[] = array('pattern' => str_replace('/', '\\/', B->string), 'code' => C, 'subpatterns' => B['subpatterns']);
+}
+
+rule_subpattern(A) ::= QUOTE(B). {
+ A = array(preg_quote(B, '/'), B);
+}
+rule_subpattern(A) ::= SINGLEQUOTE(B). {
+ A = array($this->makeCaseInsensitve(preg_quote(B, '/')), B);
+}
+rule_subpattern(A) ::= SUBPATTERN(B). {
+ if (!isset($this->patterns[B])) {
+ $this->error('Undefined pattern "' . B . '" used in rules');
+ throw new Exception('Undefined pattern "' . B . '" used in rules');
+ }
+ A = array($this->patterns[B], B);
+}
+rule_subpattern(A) ::= rule_subpattern(B) QUOTE(C). {
+ A = array(B[0] . preg_quote(C, '/'), B[1] . ' ' . C);
+}
+rule_subpattern(A) ::= rule_subpattern(B) SINGLEQUOTE(C). {
+ A = array(B[0] . $this->makeCaseInsensitve(preg_quote(C, '/')), B[1] . ' ' . C);
+}
+rule_subpattern(A) ::= rule_subpattern(B) SUBPATTERN(C). {
+ if (!isset($this->patterns[C])) {
+ $this->error('Undefined pattern "' . C . '" used in rules');
+ throw new Exception('Undefined pattern "' . C . '" used in rules');
+ }
+ A = array(B[0] . $this->patterns[C], B[1] . ' ' . C);
+}
+
+subpattern(A) ::= QUOTE(B). {
+ A = preg_quote(B, '/');
+}
+subpattern(A) ::= SINGLEQUOTE(B). {
+ A = $this->makeCaseInsensitve(preg_quote(B, '/'));
+}
+subpattern(A) ::= SUBPATTERN(B). {
+ // increment internal sub-pattern counter
+ // adjust back-references in pattern based on previous pattern
+ $test = $this->_validatePattern(B, true);
+ $this->_patternIndex += $test['subpatterns'];
+ A = $test['pattern'];
+}
+subpattern(A) ::= subpattern(B) QUOTE(C). {
+ A = B . preg_quote(C, '/');
+}
+subpattern(A) ::= subpattern(B) SINGLEQUOTE(C). {
+ A = B . $this->makeCaseInsensitve(preg_quote(C, '/'));
+}
+subpattern(A) ::= subpattern(B) SUBPATTERN(C). {
+ // increment internal sub-pattern counter
+ // adjust back-references in pattern based on previous pattern
+ $test = $this->_validatePattern(C, true);
+ $this->_patternIndex += $test['subpatterns'];
+ A = B . $test['pattern'];
+}
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/Regex/Lexer.php b/core/oql/build/PHP/LexerGenerator/Regex/Lexer.php
new file mode 100644
index 000000000..f21839d50
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Regex/Lexer.php
@@ -0,0 +1,1028 @@
+input = $data;
+ $this->N = 0;
+ }
+
+ function reset($data, $line)
+ {
+ $this->input = $data;
+ $this->N = 0;
+ // passed in from parent parser
+ $this->line = $line;
+ $this->yybegin(self::INITIAL);
+ }
+
+
+ private $_yy_state = 1;
+ private $_yy_stack = array();
+
+ function yylex()
+ {
+ return $this->{'yylex' . $this->_yy_state}();
+ }
+
+ function yypushstate($state)
+ {
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ }
+
+ function yypopstate()
+ {
+ $this->_yy_state = array_pop($this->_yy_stack);
+ }
+
+ function yybegin($state)
+ {
+ $this->_yy_state = $state;
+ }
+
+
+
+ function yylex1()
+ {
+ $tokenMap = array (
+ 1 => 0,
+ 2 => 0,
+ 3 => 0,
+ 4 => 0,
+ 5 => 0,
+ 6 => 0,
+ 7 => 0,
+ 8 => 0,
+ 9 => 0,
+ 10 => 0,
+ 11 => 0,
+ 12 => 0,
+ 13 => 0,
+ 14 => 0,
+ 15 => 0,
+ 16 => 0,
+ 17 => 0,
+ 18 => 0,
+ 19 => 0,
+ 20 => 0,
+ 21 => 0,
+ 22 => 0,
+ 23 => 0,
+ );
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ $yy_global_pattern = '/\G(\\\\\\\\)|\G([^[\\\\^$.|()?*+{}]+)|\G(\\\\[][{}*.^$|?()+])|\G(\\[)|\G(\\|)|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)/';
+
+ do {
+ if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ if (!count($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' .
+ ' an empty string. Input "' . substr($this->input,
+ $this->N, 5) . '... state INITIAL');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r1_' . $this->token}($yysubmatches);
+ if ($r === null) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ $yy_yymore_patterns = array(
+ 1 => array(0, "\G([^[\\\\^$.|()?*+{}]+)|\G(\\\\[][{}*.^$|?()+])|\G(\\[)|\G(\\|)|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 2 => array(0, "\G(\\\\[][{}*.^$|?()+])|\G(\\[)|\G(\\|)|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 3 => array(0, "\G(\\[)|\G(\\|)|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 4 => array(0, "\G(\\|)|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 5 => array(0, "\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 6 => array(0, "\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 7 => array(0, "\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 8 => array(0, "\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 9 => array(0, "\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 10 => array(0, "\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 11 => array(0, "\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 12 => array(0, "\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 13 => array(0, "\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 14 => array(0, "\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 15 => array(0, "\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 16 => array(0, "\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 17 => array(0, "\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 18 => array(0, "\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 19 => array(0, "\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 20 => array(0, "\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 21 => array(0, "\G(\\\\p[CLMNPSZ])|\G(\\\\)"),
+ 22 => array(0, "\G(\\\\)"),
+ 23 => array(0, ""),
+ );
+
+ // yymore is needed
+ do {
+ if (!strlen($yy_yymore_patterns[$this->token][1])) {
+ throw new Exception('cannot do yymore for the last token');
+ }
+ $yysubmatches = array();
+ if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
+ $this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ next($yymatches); // skip global match
+ $this->token += key($yymatches) + $yy_yymore_patterns[$this->token][0]; // token number
+ $this->value = current($yymatches); // token value
+ $this->line = substr_count($this->value, "\n");
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ }
+ $r = $this->{'yy_r1_' . $this->token}($yysubmatches);
+ } while ($r !== null && !is_bool($r));
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ // accept
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ return true;
+ }
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line .
+ ': ' . $this->input[$this->N]);
+ }
+ break;
+ } while (true);
+
+ } // end function
+
+
+ const INITIAL = 1;
+ function yy_r1_1($yy_subpatterns)
+ {
+
+ $this->token = self::ESCAPEDBACKSLASH;
+ }
+ function yy_r1_2($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ }
+ function yy_r1_3($yy_subpatterns)
+ {
+
+ $this->token = self::CONTROLCHAR;
+ }
+ function yy_r1_4($yy_subpatterns)
+ {
+
+ $this->token = self::OPENCHARCLASS;
+ $this->yybegin(self::CHARACTERCLASSSTART);
+ }
+ function yy_r1_5($yy_subpatterns)
+ {
+
+ $this->token = self::BAR;
+ }
+ function yy_r1_6($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ }
+ function yy_r1_7($yy_subpatterns)
+ {
+
+ $this->token = self::COULDBEBACKREF;
+ }
+ function yy_r1_8($yy_subpatterns)
+ {
+
+ $this->token = self::CONTROLCHAR;
+ }
+ function yy_r1_9($yy_subpatterns)
+ {
+
+ $this->token = self::MATCHSTART;
+ }
+ function yy_r1_10($yy_subpatterns)
+ {
+
+ $this->token = self::MATCHSTART;
+ }
+ function yy_r1_11($yy_subpatterns)
+ {
+
+ $this->token = self::CLOSEPAREN;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r1_12($yy_subpatterns)
+ {
+
+ $this->token = self::MATCHEND;
+ }
+ function yy_r1_13($yy_subpatterns)
+ {
+
+ $this->token = self::MULTIPLIER;
+ }
+ function yy_r1_14($yy_subpatterns)
+ {
+
+ $this->token = self::MATCHEND;
+ }
+ function yy_r1_15($yy_subpatterns)
+ {
+
+ $this->token = self::OPENASSERTION;
+ $this->yybegin(self::ASSERTION);
+ }
+ function yy_r1_16($yy_subpatterns)
+ {
+
+ $this->token = self::OPENPAREN;
+ }
+ function yy_r1_17($yy_subpatterns)
+ {
+
+ $this->token = self::FULLSTOP;
+ }
+ function yy_r1_18($yy_subpatterns)
+ {
+
+ $this->token = self::BACKREFERENCE;
+ }
+ function yy_r1_19($yy_subpatterns)
+ {
+
+ $this->token = self::CONTROLCHAR;
+ }
+ function yy_r1_20($yy_subpatterns)
+ {
+
+ $this->token = self::CONTROLCHAR;
+ }
+ function yy_r1_21($yy_subpatterns)
+ {
+
+ $this->token = self::CONTROLCHAR;
+ }
+ function yy_r1_22($yy_subpatterns)
+ {
+
+ $this->token = self::CONTROLCHAR;
+ }
+ function yy_r1_23($yy_subpatterns)
+ {
+
+ return false;
+ }
+
+
+ function yylex2()
+ {
+ $tokenMap = array (
+ 1 => 0,
+ 2 => 0,
+ 3 => 0,
+ );
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ $yy_global_pattern = '/\G(\\^)|\G(\\])|\G(.)/';
+
+ do {
+ if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ if (!count($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' .
+ ' an empty string. Input "' . substr($this->input,
+ $this->N, 5) . '... state CHARACTERCLASSSTART');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r2_' . $this->token}($yysubmatches);
+ if ($r === null) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ $yy_yymore_patterns = array(
+ 1 => array(0, "\G(\\])|\G(.)"),
+ 2 => array(0, "\G(.)"),
+ 3 => array(0, ""),
+ );
+
+ // yymore is needed
+ do {
+ if (!strlen($yy_yymore_patterns[$this->token][1])) {
+ throw new Exception('cannot do yymore for the last token');
+ }
+ $yysubmatches = array();
+ if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
+ $this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ next($yymatches); // skip global match
+ $this->token += key($yymatches) + $yy_yymore_patterns[$this->token][0]; // token number
+ $this->value = current($yymatches); // token value
+ $this->line = substr_count($this->value, "\n");
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ }
+ $r = $this->{'yy_r2_' . $this->token}($yysubmatches);
+ } while ($r !== null && !is_bool($r));
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ // accept
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ return true;
+ }
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line .
+ ': ' . $this->input[$this->N]);
+ }
+ break;
+ } while (true);
+
+ } // end function
+
+
+ const CHARACTERCLASSSTART = 2;
+ function yy_r2_1($yy_subpatterns)
+ {
+
+ $this->token = self::NEGATE;
+ }
+ function yy_r2_2($yy_subpatterns)
+ {
+
+ $this->yybegin(self::CHARACTERCLASS);
+ $this->token = self::TEXT;
+ }
+ function yy_r2_3($yy_subpatterns)
+ {
+
+ $this->yybegin(self::CHARACTERCLASS);
+ return true;
+ }
+
+
+ function yylex3()
+ {
+ $tokenMap = array (
+ 1 => 0,
+ 2 => 0,
+ 3 => 0,
+ 4 => 0,
+ 5 => 0,
+ 6 => 0,
+ 7 => 0,
+ 8 => 0,
+ 9 => 0,
+ 10 => 0,
+ 11 => 0,
+ );
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ $yy_global_pattern = '/\G(\\\\\\\\)|\G(\\])|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)/';
+
+ do {
+ if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ if (!count($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' .
+ ' an empty string. Input "' . substr($this->input,
+ $this->N, 5) . '... state CHARACTERCLASS');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r3_' . $this->token}($yysubmatches);
+ if ($r === null) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ $yy_yymore_patterns = array(
+ 1 => array(0, "\G(\\])|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)"),
+ 2 => array(0, "\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)"),
+ 3 => array(0, "\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)"),
+ 4 => array(0, "\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)"),
+ 5 => array(0, "\G(\\\\[1-9])|\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)"),
+ 6 => array(0, "\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)"),
+ 7 => array(0, "\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)"),
+ 8 => array(0, "\G([^\-\\\\])|\G(\\\\)|\G(.)"),
+ 9 => array(0, "\G(\\\\)|\G(.)"),
+ 10 => array(0, "\G(.)"),
+ 11 => array(0, ""),
+ );
+
+ // yymore is needed
+ do {
+ if (!strlen($yy_yymore_patterns[$this->token][1])) {
+ throw new Exception('cannot do yymore for the last token');
+ }
+ $yysubmatches = array();
+ if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
+ $this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ next($yymatches); // skip global match
+ $this->token += key($yymatches) + $yy_yymore_patterns[$this->token][0]; // token number
+ $this->value = current($yymatches); // token value
+ $this->line = substr_count($this->value, "\n");
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ }
+ $r = $this->{'yy_r3_' . $this->token}($yysubmatches);
+ } while ($r !== null && !is_bool($r));
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ // accept
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ return true;
+ }
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line .
+ ': ' . $this->input[$this->N]);
+ }
+ break;
+ } while (true);
+
+ } // end function
+
+
+ const CHARACTERCLASS = 3;
+ function yy_r3_1($yy_subpatterns)
+ {
+
+ $this->token = self::ESCAPEDBACKSLASH;
+ }
+ function yy_r3_2($yy_subpatterns)
+ {
+
+ $this->yybegin(self::INITIAL);
+ $this->token = self::CLOSECHARCLASS;
+ }
+ function yy_r3_3($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ }
+ function yy_r3_4($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ }
+ function yy_r3_5($yy_subpatterns)
+ {
+
+ $this->token = self::COULDBEBACKREF;
+ }
+ function yy_r3_6($yy_subpatterns)
+ {
+
+ $this->token = self::BACKREFERENCE;
+ }
+ function yy_r3_7($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ }
+ function yy_r3_8($yy_subpatterns)
+ {
+
+ $this->token = self::HYPHEN;
+ $this->yybegin(self::RANGE);
+ }
+ function yy_r3_9($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ }
+ function yy_r3_10($yy_subpatterns)
+ {
+
+ return false; // ignore escaping of normal text
+ }
+ function yy_r3_11($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ }
+
+
+ function yylex4()
+ {
+ $tokenMap = array (
+ 1 => 0,
+ 2 => 0,
+ 3 => 0,
+ 4 => 0,
+ 5 => 0,
+ 6 => 0,
+ 7 => 0,
+ );
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ $yy_global_pattern = '/\G(\\\\\\\\)|\G(\\\\\\])|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G([^\-\\\\])|\G(\\\\)/';
+
+ do {
+ if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ if (!count($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' .
+ ' an empty string. Input "' . substr($this->input,
+ $this->N, 5) . '... state RANGE');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r4_' . $this->token}($yysubmatches);
+ if ($r === null) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ $yy_yymore_patterns = array(
+ 1 => array(0, "\G(\\\\\\])|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G([^\-\\\\])|\G(\\\\)"),
+ 2 => array(0, "\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G([^\-\\\\])|\G(\\\\)"),
+ 3 => array(0, "\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G([^\-\\\\])|\G(\\\\)"),
+ 4 => array(0, "\G(\\\\[1-9])|\G([^\-\\\\])|\G(\\\\)"),
+ 5 => array(0, "\G([^\-\\\\])|\G(\\\\)"),
+ 6 => array(0, "\G(\\\\)"),
+ 7 => array(0, ""),
+ );
+
+ // yymore is needed
+ do {
+ if (!strlen($yy_yymore_patterns[$this->token][1])) {
+ throw new Exception('cannot do yymore for the last token');
+ }
+ $yysubmatches = array();
+ if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
+ $this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ next($yymatches); // skip global match
+ $this->token += key($yymatches) + $yy_yymore_patterns[$this->token][0]; // token number
+ $this->value = current($yymatches); // token value
+ $this->line = substr_count($this->value, "\n");
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ }
+ $r = $this->{'yy_r4_' . $this->token}($yysubmatches);
+ } while ($r !== null && !is_bool($r));
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ // accept
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ return true;
+ }
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line .
+ ': ' . $this->input[$this->N]);
+ }
+ break;
+ } while (true);
+
+ } // end function
+
+
+ const RANGE = 4;
+ function yy_r4_1($yy_subpatterns)
+ {
+
+ $this->token = self::ESCAPEDBACKSLASH;
+ }
+ function yy_r4_2($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ $this->yybegin(self::CHARACTERCLASS);
+ }
+ function yy_r4_3($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ $this->yybegin(self::CHARACTERCLASS);
+ }
+ function yy_r4_4($yy_subpatterns)
+ {
+
+ $this->token = self::COULDBEBACKREF;
+ }
+ function yy_r4_5($yy_subpatterns)
+ {
+
+ $this->token = self::BACKREFERENCE;
+ }
+ function yy_r4_6($yy_subpatterns)
+ {
+
+ $this->token = self::TEXT;
+ $this->yybegin(self::CHARACTERCLASS);
+ }
+ function yy_r4_7($yy_subpatterns)
+ {
+
+ return false; // ignore escaping of normal text
+ }
+
+
+ function yylex5()
+ {
+ $tokenMap = array (
+ 1 => 0,
+ 2 => 0,
+ 3 => 0,
+ 4 => 0,
+ 5 => 0,
+ 6 => 0,
+ 7 => 0,
+ 8 => 0,
+ 9 => 0,
+ 10 => 0,
+ 11 => 0,
+ 12 => 0,
+ 13 => 0,
+ );
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ $yy_global_pattern = '/\G([imsxUX]+-[imsxUX]+|[imsxUX]+|-[imsxUX]+)|\G(:)|\G(\\))|\G(P<[^>]+>)|\G(<=)|\G()|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)/';
+
+ do {
+ if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ if (!count($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' .
+ ' an empty string. Input "' . substr($this->input,
+ $this->N, 5) . '... state ASSERTION');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r5_' . $this->token}($yysubmatches);
+ if ($r === null) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ $yy_yymore_patterns = array(
+ 1 => array(0, "\G(:)|\G(\\))|\G(P<[^>]+>)|\G(<=)|\G()|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 2 => array(0, "\G(\\))|\G(P<[^>]+>)|\G(<=)|\G()|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 3 => array(0, "\G(P<[^>]+>)|\G(<=)|\G()|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 4 => array(0, "\G(<=)|\G()|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 5 => array(0, "\G()|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 6 => array(0, "\G(=)|\G(!)|\G(>)|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 7 => array(0, "\G(!)|\G(>)|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 8 => array(0, "\G(>)|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 9 => array(0, "\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)"),
+ 10 => array(0, "\G(#[^)]+)|\G(R)|\G(.)"),
+ 11 => array(0, "\G(R)|\G(.)"),
+ 12 => array(0, "\G(.)"),
+ 13 => array(0, ""),
+ );
+
+ // yymore is needed
+ do {
+ if (!strlen($yy_yymore_patterns[$this->token][1])) {
+ throw new Exception('cannot do yymore for the last token');
+ }
+ $yysubmatches = array();
+ if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
+ $this->input, $yymatches, null, $this->N)) {
+ $yysubmatches = $yymatches;
+ $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
+ next($yymatches); // skip global match
+ $this->token += key($yymatches) + $yy_yymore_patterns[$this->token][0]; // token number
+ $this->value = current($yymatches); // token value
+ $this->line = substr_count($this->value, "\n");
+ if ($tokenMap[$this->token]) {
+ // extract sub-patterns for passing to lex function
+ $yysubmatches = array_slice($yysubmatches, $this->token + 1,
+ $tokenMap[$this->token]);
+ } else {
+ $yysubmatches = array();
+ }
+ }
+ $r = $this->{'yy_r5_' . $this->token}($yysubmatches);
+ } while ($r !== null && !is_bool($r));
+ if ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->N >= strlen($this->input)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ } else {
+ // accept
+ $this->N += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ return true;
+ }
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line .
+ ': ' . $this->input[$this->N]);
+ }
+ break;
+ } while (true);
+
+ } // end function
+
+
+ const ASSERTION = 5;
+ function yy_r5_1($yy_subpatterns)
+ {
+
+ $this->token = self::INTERNALOPTIONS;
+ }
+ function yy_r5_2($yy_subpatterns)
+ {
+
+ $this->token = self::COLON;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_3($yy_subpatterns)
+ {
+
+ $this->token = self::CLOSEPAREN;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_4($yy_subpatterns)
+ {
+
+ $this->token = self::PATTERNNAME;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_5($yy_subpatterns)
+ {
+
+ $this->token = self::POSITIVELOOKBEHIND;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_6($yy_subpatterns)
+ {
+
+ $this->token = self::NEGATIVELOOKBEHIND;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_7($yy_subpatterns)
+ {
+
+ $this->token = self::POSITIVELOOKAHEAD;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_8($yy_subpatterns)
+ {
+
+ $this->token = self::NEGATIVELOOKAHEAD;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_9($yy_subpatterns)
+ {
+
+ $this->token = self::ONCEONLY;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_10($yy_subpatterns)
+ {
+
+ $this->token = self::OPENASSERTION;
+ }
+ function yy_r5_11($yy_subpatterns)
+ {
+
+ $this->token = self::COMMENT;
+ $this->yybegin(self::INITIAL);
+ }
+ function yy_r5_12($yy_subpatterns)
+ {
+
+ $this->token = self::RECUR;
+ }
+ function yy_r5_13($yy_subpatterns)
+ {
+
+ $this->yybegin(self::INITIAL);
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/Regex/Lexer.plex b/core/oql/build/PHP/LexerGenerator/Regex/Lexer.plex
new file mode 100644
index 000000000..c5cad0fa6
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Regex/Lexer.plex
@@ -0,0 +1,285 @@
+input = $data;
+ $this->N = 0;
+ }
+
+ function reset($data, $line)
+ {
+ $this->input = $data;
+ $this->N = 0;
+ // passed in from parent parser
+ $this->line = $line;
+ $this->yybegin(self::INITIAL);
+ }
+
+/*!lex2php
+%input {$this->input}
+%counter {$this->N}
+%token {$this->token}
+%value {$this->value}
+%line {$this->line}
+NONESCAPE = /[^[\\^$.|()?*+{}]+/
+NONESCAPECHARCLASS = /[^\-\\]/
+ESCAPEDTHING = /\\[][{}*.^$|?()+]/
+ESCAPEDCHARCLASSTHING = /\\[]\.\-\^]/
+MULTIPLIER = /\*\?|\+\?|[*?+]|\{[0-9]+\}|\{[0-9]+,\}|\{[0-9]+,[0-9]+\}/
+STRINGCHAR = /\\[frnt]|\\x[0-9a-fA-F][0-9a-fA-F]?|\\[0-7][0-7][0-7]|\\x\{[0-9a-fA-F]+\}/
+CONTROLCHAR = /\\[abBGcedDsSwW0C]|\\c\\/
+COULDBEBACKREF = /\\[0-9][0-9]/
+CHARCLASSCONTROLCHAR = /\\[bacedDsSwW0C]|\\c\\|\\x\{[0-9a-fA-F]+\}|\\[0-7][0-7][0-7]|\\x[0-9a-fA-F][0-9a-fA-F]?/
+SUBJECTEND = /\\[zZ]/
+BACKREF = /\\[1-9]/
+UNICODESTUFF = /\\p\{\^?..?\}|\\P\{..?\}|\\X/
+PROPERTYCODES = /C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?/
+SIMPLEPROPERTYCODES = /[CLMNPSZ]/
+INTERNALOPTIONS = /[imsxUX]+-[imsxUX]+|[imsxUX]+|-[imsxUX]+/
+ANYTHING = /./
+PATTERNNAME = /[^>]+/
+COMMENT = /#[^)]+/
+HYPHEN = /-(?!])/
+*/
+/*!lex2php
+%statename INITIAL
+"\\\\" {
+ $this->token = self::ESCAPEDBACKSLASH;
+}
+NONESCAPE {
+ $this->token = self::TEXT;
+}
+ESCAPEDTHING {
+ $this->token = self::CONTROLCHAR;
+}
+"[" {
+ $this->token = self::OPENCHARCLASS;
+ $this->yybegin(self::CHARACTERCLASSSTART);
+}
+"|" {
+ $this->token = self::BAR;
+}
+STRINGCHAR {
+ $this->token = self::TEXT;
+}
+COULDBEBACKREF {
+ $this->token = self::COULDBEBACKREF;
+}
+CONTROLCHAR {
+ $this->token = self::CONTROLCHAR;
+}
+"^" {
+ $this->token = self::MATCHSTART;
+}
+"\\A" {
+ $this->token = self::MATCHSTART;
+}
+")" {
+ $this->token = self::CLOSEPAREN;
+ $this->yybegin(self::INITIAL);
+}
+"$" {
+ $this->token = self::MATCHEND;
+}
+MULTIPLIER {
+ $this->token = self::MULTIPLIER;
+}
+SUBJECTEND {
+ $this->token = self::MATCHEND;
+}
+"(?" {
+ $this->token = self::OPENASSERTION;
+ $this->yybegin(self::ASSERTION);
+}
+"(" {
+ $this->token = self::OPENPAREN;
+}
+"." {
+ $this->token = self::FULLSTOP;
+}
+BACKREF {
+ $this->token = self::BACKREFERENCE;
+}
+UNICODESTUFF {
+ $this->token = self::CONTROLCHAR;
+}
+"\\p{" PROPERTYCODES "}" {
+ $this->token = self::CONTROLCHAR;
+}
+"\\p{^" PROPERTYCODES "}" {
+ $this->token = self::CONTROLCHAR;
+}
+"\\p" SIMPLEPROPERTYCODES {
+ $this->token = self::CONTROLCHAR;
+}
+"\\" {
+ return false;
+}
+*/
+/*!lex2php
+%statename CHARACTERCLASSSTART
+"^" {
+ $this->token = self::NEGATE;
+}
+"]" {
+ $this->yybegin(self::CHARACTERCLASS);
+ $this->token = self::TEXT;
+}
+ANYTHING {
+ $this->yybegin(self::CHARACTERCLASS);
+ return true;
+}
+*/
+/*!lex2php
+%statename CHARACTERCLASS
+"\\\\" {
+ $this->token = self::ESCAPEDBACKSLASH;
+}
+"]" {
+ $this->yybegin(self::INITIAL);
+ $this->token = self::CLOSECHARCLASS;
+}
+STRINGCHAR {
+ $this->token = self::TEXT;
+}
+CHARCLASSCONTROLCHAR {
+ $this->token = self::TEXT;
+}
+COULDBEBACKREF {
+ $this->token = self::COULDBEBACKREF;
+}
+BACKREF {
+ $this->token = self::BACKREFERENCE;
+}
+ESCAPEDCHARCLASSTHING {
+ $this->token = self::TEXT;
+}
+HYPHEN {
+ $this->token = self::HYPHEN;
+ $this->yybegin(self::RANGE);
+}
+NONESCAPECHARCLASS {
+ $this->token = self::TEXT;
+}
+"\\" {
+ return false; // ignore escaping of normal text
+}
+ANYTHING {
+ $this->token = self::TEXT;
+}
+*/
+/*!lex2php
+%statename RANGE
+"\\\\" {
+ $this->token = self::ESCAPEDBACKSLASH;
+}
+"\\]" {
+ $this->token = self::TEXT;
+ $this->yybegin(self::CHARACTERCLASS);
+}
+CHARCLASSCONTROLCHAR {
+ $this->token = self::TEXT;
+ $this->yybegin(self::CHARACTERCLASS);
+}
+COULDBEBACKREF {
+ $this->token = self::COULDBEBACKREF;
+}
+BACKREF {
+ $this->token = self::BACKREFERENCE;
+}
+NONESCAPECHARCLASS {
+ $this->token = self::TEXT;
+ $this->yybegin(self::CHARACTERCLASS);
+}
+"\\" {
+ return false; // ignore escaping of normal text
+}
+*/
+/*!lex2php
+%statename ASSERTION
+INTERNALOPTIONS {
+ $this->token = self::INTERNALOPTIONS;
+}
+":" {
+ $this->token = self::COLON;
+ $this->yybegin(self::INITIAL);
+}
+")" {
+ $this->token = self::CLOSEPAREN;
+ $this->yybegin(self::INITIAL);
+}
+"P<" PATTERNNAME ">" {
+ $this->token = self::PATTERNNAME;
+ $this->yybegin(self::INITIAL);
+}
+"<=" {
+ $this->token = self::POSITIVELOOKBEHIND;
+ $this->yybegin(self::INITIAL);
+}
+"token = self::NEGATIVELOOKBEHIND;
+ $this->yybegin(self::INITIAL);
+}
+"=" {
+ $this->token = self::POSITIVELOOKAHEAD;
+ $this->yybegin(self::INITIAL);
+}
+"!" {
+ $this->token = self::NEGATIVELOOKAHEAD;
+ $this->yybegin(self::INITIAL);
+}
+">" {
+ $this->token = self::ONCEONLY;
+ $this->yybegin(self::INITIAL);
+}
+"(?" {
+ $this->token = self::OPENASSERTION;
+}
+COMMENT {
+ $this->token = self::COMMENT;
+ $this->yybegin(self::INITIAL);
+}
+"R" {
+ $this->token = self::RECUR;
+}
+ANYTHING {
+ $this->yybegin(self::INITIAL);
+ return true;
+}
+*/
+}
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/Regex/Parser.out b/core/oql/build/PHP/LexerGenerator/Regex/Parser.out
new file mode 100644
index 000000000..752e2c3d6
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Regex/Parser.out
@@ -0,0 +1,2568 @@
+State 0:
+ start ::= * pattern
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ start accept
+ pattern shift 45
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 1:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= OPENASSERTION NEGATIVELOOKAHEAD * pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 37
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 2:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= OPENASSERTION COLON * pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ grouping ::= OPENASSERTION COLON * pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 30
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 3:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN * pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN * pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 33
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 4:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= OPENASSERTION NEGATIVELOOKBEHIND * pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 34
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 5:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= OPENASSERTION POSITIVELOOKAHEAD * pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 40
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 6:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ assertion ::= OPENASSERTION INTERNALOPTIONS COLON * pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 25
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 7:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= OPENASSERTION lookahead * pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION lookahead * pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 39
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 8:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= OPENASSERTION lookbehind * pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION lookbehind * pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 32
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 9:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= OPENPAREN * pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= OPENPAREN * pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 28
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 10:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= OPENASSERTION PATTERNNAME * pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= OPENASSERTION PATTERNNAME * pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 35
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 11:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= OPENASSERTION POSITIVELOOKBEHIND * pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 38
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 12:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ pattern ::= pattern BAR * pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 92
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 13:
+ pattern ::= * MATCHSTART basic_pattern MATCHEND
+ pattern ::= * MATCHSTART basic_pattern
+ pattern ::= * basic_pattern MATCHEND
+ pattern ::= * basic_pattern
+ pattern ::= * pattern BAR pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ onceonly ::= OPENASSERTION ONCEONLY * pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHSTART shift 14
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ pattern shift 36
+ basic_pattern shift 15
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 14:
+ pattern ::= MATCHSTART * basic_pattern MATCHEND
+ pattern ::= MATCHSTART * basic_pattern
+ basic_pattern ::= * basic_text
+ basic_pattern ::= * character_class
+ basic_pattern ::= * assertion
+ basic_pattern ::= * grouping
+ basic_pattern ::= * lookahead
+ basic_pattern ::= * lookbehind
+ basic_pattern ::= * subpattern
+ basic_pattern ::= * onceonly
+ basic_pattern ::= * comment
+ basic_pattern ::= * recur
+ basic_pattern ::= * conditional
+ basic_pattern ::= * basic_pattern basic_text
+ basic_pattern ::= * basic_pattern character_class
+ basic_pattern ::= * basic_pattern assertion
+ basic_pattern ::= * basic_pattern grouping
+ basic_pattern ::= * basic_pattern lookahead
+ basic_pattern ::= * basic_pattern lookbehind
+ basic_pattern ::= * basic_pattern subpattern
+ basic_pattern ::= * basic_pattern onceonly
+ basic_pattern ::= * basic_pattern comment
+ basic_pattern ::= * basic_pattern recur
+ basic_pattern ::= * basic_pattern conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ basic_pattern shift 16
+ basic_text shift 23
+ character_class shift 104
+ assertion shift 106
+ grouping shift 107
+ lookahead shift 109
+ lookbehind shift 108
+ subpattern shift 118
+ onceonly shift 119
+ comment shift 129
+ recur shift 128
+ conditional shift 130
+
+State 15:
+ pattern ::= basic_pattern * MATCHEND
+ (4) pattern ::= basic_pattern *
+ basic_pattern ::= basic_pattern * basic_text
+ basic_pattern ::= basic_pattern * character_class
+ basic_pattern ::= basic_pattern * assertion
+ basic_pattern ::= basic_pattern * grouping
+ basic_pattern ::= basic_pattern * lookahead
+ basic_pattern ::= basic_pattern * lookbehind
+ basic_pattern ::= basic_pattern * subpattern
+ basic_pattern ::= basic_pattern * onceonly
+ basic_pattern ::= basic_pattern * comment
+ basic_pattern ::= basic_pattern * recur
+ basic_pattern ::= basic_pattern * conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHEND shift 117
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ basic_text shift 22
+ character_class shift 72
+ assertion shift 76
+ grouping shift 85
+ lookahead shift 84
+ lookbehind shift 82
+ subpattern shift 81
+ onceonly shift 80
+ comment shift 97
+ recur shift 134
+ conditional shift 125
+ {default} reduce 4
+
+State 16:
+ pattern ::= MATCHSTART basic_pattern * MATCHEND
+ (2) pattern ::= MATCHSTART basic_pattern *
+ basic_pattern ::= basic_pattern * basic_text
+ basic_pattern ::= basic_pattern * character_class
+ basic_pattern ::= basic_pattern * assertion
+ basic_pattern ::= basic_pattern * grouping
+ basic_pattern ::= basic_pattern * lookahead
+ basic_pattern ::= basic_pattern * lookbehind
+ basic_pattern ::= basic_pattern * subpattern
+ basic_pattern ::= basic_pattern * onceonly
+ basic_pattern ::= basic_pattern * comment
+ basic_pattern ::= basic_pattern * recur
+ basic_pattern ::= basic_pattern * conditional
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= * OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= * OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ basic_text ::= * TEXT
+ basic_text ::= * TEXT MULTIPLIER
+ basic_text ::= * FULLSTOP
+ basic_text ::= * FULLSTOP MULTIPLIER
+ basic_text ::= * CONTROLCHAR
+ basic_text ::= * CONTROLCHAR MULTIPLIER
+ basic_text ::= * ESCAPEDBACKSLASH
+ basic_text ::= * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * BACKREFERENCE
+ basic_text ::= * BACKREFERENCE MULTIPLIER
+ basic_text ::= * COULDBEBACKREF
+ basic_text ::= * COULDBEBACKREF MULTIPLIER
+ basic_text ::= * basic_text TEXT
+ basic_text ::= * basic_text TEXT MULTIPLIER
+ basic_text ::= * basic_text FULLSTOP
+ basic_text ::= * basic_text FULLSTOP MULTIPLIER
+ basic_text ::= * basic_text CONTROLCHAR
+ basic_text ::= * basic_text CONTROLCHAR MULTIPLIER
+ basic_text ::= * basic_text ESCAPEDBACKSLASH
+ basic_text ::= * basic_text ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= * basic_text BACKREFERENCE
+ basic_text ::= * basic_text BACKREFERENCE MULTIPLIER
+ basic_text ::= * basic_text COULDBEBACKREF
+ basic_text ::= * basic_text COULDBEBACKREF MULTIPLIER
+ assertion ::= * OPENASSERTION INTERNALOPTIONS CLOSEPAREN
+ assertion ::= * OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN
+ grouping ::= * OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN
+ conditional ::= * OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= * OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN
+ subpattern ::= * OPENPAREN pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= * OPENASSERTION ONCEONLY pattern CLOSEPAREN
+ comment ::= * OPENASSERTION COMMENT CLOSEPAREN
+ recur ::= * OPENASSERTION RECUR CLOSEPAREN
+
+ OPENPAREN shift 9
+ OPENASSERTION shift 17
+ MATCHEND shift 91
+ OPENCHARCLASS shift 18
+ TEXT shift 52
+ ESCAPEDBACKSLASH shift 43
+ BACKREFERENCE shift 44
+ COULDBEBACKREF shift 57
+ CONTROLCHAR shift 42
+ FULLSTOP shift 41
+ basic_text shift 22
+ character_class shift 72
+ assertion shift 76
+ grouping shift 85
+ lookahead shift 84
+ lookbehind shift 82
+ subpattern shift 81
+ onceonly shift 80
+ comment shift 97
+ recur shift 134
+ conditional shift 125
+ {default} reduce 2
+
+State 17:
+ assertion ::= OPENASSERTION * INTERNALOPTIONS CLOSEPAREN
+ assertion ::= OPENASSERTION * INTERNALOPTIONS COLON pattern CLOSEPAREN
+ grouping ::= OPENASSERTION * COLON pattern CLOSEPAREN
+ grouping ::= OPENASSERTION * COLON pattern CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION * OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION * OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN
+ conditional ::= OPENASSERTION * lookahead pattern CLOSEPAREN
+ conditional ::= OPENASSERTION * lookahead pattern CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION * lookbehind pattern CLOSEPAREN
+ conditional ::= OPENASSERTION * lookbehind pattern CLOSEPAREN MULTIPLIER
+ lookahead ::= * OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= OPENASSERTION * POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= * OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= OPENASSERTION * NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= OPENASSERTION * POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= * OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= OPENASSERTION * NEGATIVELOOKBEHIND pattern CLOSEPAREN
+ subpattern ::= OPENASSERTION * PATTERNNAME pattern CLOSEPAREN
+ subpattern ::= OPENASSERTION * PATTERNNAME pattern CLOSEPAREN MULTIPLIER
+ onceonly ::= OPENASSERTION * ONCEONLY pattern CLOSEPAREN
+ comment ::= OPENASSERTION * COMMENT CLOSEPAREN
+ recur ::= OPENASSERTION * RECUR CLOSEPAREN
+
+ OPENPAREN shift 54
+ OPENASSERTION shift 24
+ INTERNALOPTIONS shift 26
+ COLON shift 2
+ POSITIVELOOKAHEAD shift 5
+ NEGATIVELOOKAHEAD shift 1
+ POSITIVELOOKBEHIND shift 11
+ NEGATIVELOOKBEHIND shift 4
+ PATTERNNAME shift 10
+ ONCEONLY shift 13
+ COMMENT shift 49
+ RECUR shift 50
+ lookahead shift 7
+ lookbehind shift 8
+
+State 18:
+ character_class ::= OPENCHARCLASS * character_class_contents CLOSECHARCLASS
+ character_class ::= OPENCHARCLASS * NEGATE character_class_contents CLOSECHARCLASS
+ character_class ::= OPENCHARCLASS * character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class ::= OPENCHARCLASS * NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class_contents ::= * TEXT
+ character_class_contents ::= * ESCAPEDBACKSLASH
+ character_class_contents ::= * ESCAPEDBACKSLASH HYPHEN TEXT
+ character_class_contents ::= * TEXT HYPHEN TEXT
+ character_class_contents ::= * TEXT HYPHEN ESCAPEDBACKSLASH
+ character_class_contents ::= * BACKREFERENCE
+ character_class_contents ::= * COULDBEBACKREF
+ character_class_contents ::= * character_class_contents CONTROLCHAR
+ character_class_contents ::= * character_class_contents ESCAPEDBACKSLASH
+ character_class_contents ::= * character_class_contents TEXT
+ character_class_contents ::= * character_class_contents ESCAPEDBACKSLASH HYPHEN CONTROLCHAR
+ character_class_contents ::= * character_class_contents ESCAPEDBACKSLASH HYPHEN TEXT
+ character_class_contents ::= * character_class_contents TEXT HYPHEN ESCAPEDBACKSLASH
+ character_class_contents ::= * character_class_contents TEXT HYPHEN TEXT
+ character_class_contents ::= * character_class_contents BACKREFERENCE
+ character_class_contents ::= * character_class_contents COULDBEBACKREF
+
+ NEGATE shift 19
+ TEXT shift 67
+ ESCAPEDBACKSLASH shift 69
+ BACKREFERENCE shift 101
+ COULDBEBACKREF shift 87
+ character_class_contents shift 20
+
+State 19:
+ character_class ::= OPENCHARCLASS NEGATE * character_class_contents CLOSECHARCLASS
+ character_class ::= OPENCHARCLASS NEGATE * character_class_contents CLOSECHARCLASS MULTIPLIER
+ character_class_contents ::= * TEXT
+ character_class_contents ::= * ESCAPEDBACKSLASH
+ character_class_contents ::= * ESCAPEDBACKSLASH HYPHEN TEXT
+ character_class_contents ::= * TEXT HYPHEN TEXT
+ character_class_contents ::= * TEXT HYPHEN ESCAPEDBACKSLASH
+ character_class_contents ::= * BACKREFERENCE
+ character_class_contents ::= * COULDBEBACKREF
+ character_class_contents ::= * character_class_contents CONTROLCHAR
+ character_class_contents ::= * character_class_contents ESCAPEDBACKSLASH
+ character_class_contents ::= * character_class_contents TEXT
+ character_class_contents ::= * character_class_contents ESCAPEDBACKSLASH HYPHEN CONTROLCHAR
+ character_class_contents ::= * character_class_contents ESCAPEDBACKSLASH HYPHEN TEXT
+ character_class_contents ::= * character_class_contents TEXT HYPHEN ESCAPEDBACKSLASH
+ character_class_contents ::= * character_class_contents TEXT HYPHEN TEXT
+ character_class_contents ::= * character_class_contents BACKREFERENCE
+ character_class_contents ::= * character_class_contents COULDBEBACKREF
+
+ TEXT shift 67
+ ESCAPEDBACKSLASH shift 69
+ BACKREFERENCE shift 101
+ COULDBEBACKREF shift 87
+ character_class_contents shift 21
+
+State 20:
+ character_class ::= OPENCHARCLASS character_class_contents * CLOSECHARCLASS
+ character_class ::= OPENCHARCLASS character_class_contents * CLOSECHARCLASS MULTIPLIER
+ character_class_contents ::= character_class_contents * CONTROLCHAR
+ character_class_contents ::= character_class_contents * ESCAPEDBACKSLASH
+ character_class_contents ::= character_class_contents * TEXT
+ character_class_contents ::= character_class_contents * ESCAPEDBACKSLASH HYPHEN CONTROLCHAR
+ character_class_contents ::= character_class_contents * ESCAPEDBACKSLASH HYPHEN TEXT
+ character_class_contents ::= character_class_contents * TEXT HYPHEN ESCAPEDBACKSLASH
+ character_class_contents ::= character_class_contents * TEXT HYPHEN TEXT
+ character_class_contents ::= character_class_contents * BACKREFERENCE
+ character_class_contents ::= character_class_contents * COULDBEBACKREF
+
+ CLOSECHARCLASS shift 59
+ TEXT shift 60
+ ESCAPEDBACKSLASH shift 68
+ BACKREFERENCE shift 111
+ COULDBEBACKREF shift 116
+ CONTROLCHAR shift 122
+
+State 21:
+ character_class ::= OPENCHARCLASS NEGATE character_class_contents * CLOSECHARCLASS
+ character_class ::= OPENCHARCLASS NEGATE character_class_contents * CLOSECHARCLASS MULTIPLIER
+ character_class_contents ::= character_class_contents * CONTROLCHAR
+ character_class_contents ::= character_class_contents * ESCAPEDBACKSLASH
+ character_class_contents ::= character_class_contents * TEXT
+ character_class_contents ::= character_class_contents * ESCAPEDBACKSLASH HYPHEN CONTROLCHAR
+ character_class_contents ::= character_class_contents * ESCAPEDBACKSLASH HYPHEN TEXT
+ character_class_contents ::= character_class_contents * TEXT HYPHEN ESCAPEDBACKSLASH
+ character_class_contents ::= character_class_contents * TEXT HYPHEN TEXT
+ character_class_contents ::= character_class_contents * BACKREFERENCE
+ character_class_contents ::= character_class_contents * COULDBEBACKREF
+
+ CLOSECHARCLASS shift 61
+ TEXT shift 60
+ ESCAPEDBACKSLASH shift 68
+ BACKREFERENCE shift 111
+ COULDBEBACKREF shift 116
+ CONTROLCHAR shift 122
+
+State 22:
+ (17) basic_pattern ::= basic_pattern basic_text *
+ basic_text ::= basic_text * TEXT
+ basic_text ::= basic_text * TEXT MULTIPLIER
+ basic_text ::= basic_text * FULLSTOP
+ basic_text ::= basic_text * FULLSTOP MULTIPLIER
+ basic_text ::= basic_text * CONTROLCHAR
+ basic_text ::= basic_text * CONTROLCHAR MULTIPLIER
+ basic_text ::= basic_text * ESCAPEDBACKSLASH
+ basic_text ::= basic_text * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= basic_text * BACKREFERENCE
+ basic_text ::= basic_text * BACKREFERENCE MULTIPLIER
+ basic_text ::= basic_text * COULDBEBACKREF
+ basic_text ::= basic_text * COULDBEBACKREF MULTIPLIER
+
+ TEXT shift 64
+ TEXT reduce 17 ** Parsing conflict **
+ ESCAPEDBACKSLASH shift 63
+ ESCAPEDBACKSLASH reduce 17 ** Parsing conflict **
+ BACKREFERENCE shift 62
+ BACKREFERENCE reduce 17 ** Parsing conflict **
+ COULDBEBACKREF shift 58
+ COULDBEBACKREF reduce 17 ** Parsing conflict **
+ CONTROLCHAR shift 66
+ CONTROLCHAR reduce 17 ** Parsing conflict **
+ FULLSTOP shift 65
+ FULLSTOP reduce 17 ** Parsing conflict **
+ {default} reduce 17
+
+State 23:
+ (6) basic_pattern ::= basic_text *
+ basic_text ::= basic_text * TEXT
+ basic_text ::= basic_text * TEXT MULTIPLIER
+ basic_text ::= basic_text * FULLSTOP
+ basic_text ::= basic_text * FULLSTOP MULTIPLIER
+ basic_text ::= basic_text * CONTROLCHAR
+ basic_text ::= basic_text * CONTROLCHAR MULTIPLIER
+ basic_text ::= basic_text * ESCAPEDBACKSLASH
+ basic_text ::= basic_text * ESCAPEDBACKSLASH MULTIPLIER
+ basic_text ::= basic_text * BACKREFERENCE
+ basic_text ::= basic_text * BACKREFERENCE MULTIPLIER
+ basic_text ::= basic_text * COULDBEBACKREF
+ basic_text ::= basic_text * COULDBEBACKREF MULTIPLIER
+
+ TEXT shift 64
+ TEXT reduce 6 ** Parsing conflict **
+ ESCAPEDBACKSLASH shift 63
+ ESCAPEDBACKSLASH reduce 6 ** Parsing conflict **
+ BACKREFERENCE shift 62
+ BACKREFERENCE reduce 6 ** Parsing conflict **
+ COULDBEBACKREF shift 58
+ COULDBEBACKREF reduce 6 ** Parsing conflict **
+ CONTROLCHAR shift 66
+ CONTROLCHAR reduce 6 ** Parsing conflict **
+ FULLSTOP shift 65
+ FULLSTOP reduce 6 ** Parsing conflict **
+ {default} reduce 6
+
+State 24:
+ lookahead ::= OPENASSERTION * POSITIVELOOKAHEAD pattern CLOSEPAREN
+ lookahead ::= OPENASSERTION * NEGATIVELOOKAHEAD pattern CLOSEPAREN
+ lookbehind ::= OPENASSERTION * POSITIVELOOKBEHIND pattern CLOSEPAREN
+ lookbehind ::= OPENASSERTION * NEGATIVELOOKBEHIND pattern CLOSEPAREN
+
+ POSITIVELOOKAHEAD shift 5
+ NEGATIVELOOKAHEAD shift 1
+ POSITIVELOOKBEHIND shift 11
+ NEGATIVELOOKBEHIND shift 4
+
+State 25:
+ pattern ::= pattern * BAR pattern
+ assertion ::= OPENASSERTION INTERNALOPTIONS COLON pattern * CLOSEPAREN
+
+ BAR shift 12
+ CLOSEPAREN shift 133
+
+State 26:
+ assertion ::= OPENASSERTION INTERNALOPTIONS * CLOSEPAREN
+ assertion ::= OPENASSERTION INTERNALOPTIONS * COLON pattern CLOSEPAREN
+
+ CLOSEPAREN shift 112
+ COLON shift 6
+
+State 27:
+ character_class_contents ::= character_class_contents TEXT HYPHEN * ESCAPEDBACKSLASH
+ character_class_contents ::= character_class_contents TEXT HYPHEN * TEXT
+
+ TEXT shift 105
+ ESCAPEDBACKSLASH shift 131
+
+State 28:
+ pattern ::= pattern * BAR pattern
+ subpattern ::= OPENPAREN pattern * CLOSEPAREN
+ subpattern ::= OPENPAREN pattern * CLOSEPAREN MULTIPLIER
+
+ BAR shift 12
+ CLOSEPAREN shift 56
+
+State 29:
+ character_class_contents ::= TEXT HYPHEN * TEXT
+ character_class_contents ::= TEXT HYPHEN * ESCAPEDBACKSLASH
+
+ TEXT shift 113
+ ESCAPEDBACKSLASH shift 124
+
+State 30:
+ pattern ::= pattern * BAR pattern
+ grouping ::= OPENASSERTION COLON pattern * CLOSEPAREN
+ grouping ::= OPENASSERTION COLON pattern * CLOSEPAREN MULTIPLIER
+
+ BAR shift 12
+ CLOSEPAREN shift 53
+
+State 31:
+ character_class_contents ::= character_class_contents ESCAPEDBACKSLASH HYPHEN * CONTROLCHAR
+ character_class_contents ::= character_class_contents ESCAPEDBACKSLASH HYPHEN * TEXT
+
+ TEXT shift 127
+ CONTROLCHAR shift 126
+
+State 32:
+ pattern ::= pattern * BAR pattern
+ conditional ::= OPENASSERTION lookbehind pattern * CLOSEPAREN
+ conditional ::= OPENASSERTION lookbehind pattern * CLOSEPAREN MULTIPLIER
+
+ BAR shift 12
+ CLOSEPAREN shift 47
+
+State 33:
+ pattern ::= pattern * BAR pattern
+ conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern * CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern * CLOSEPAREN
+
+ BAR shift 12
+ CLOSEPAREN shift 46
+
+State 34:
+ pattern ::= pattern * BAR pattern
+ lookbehind ::= OPENASSERTION NEGATIVELOOKBEHIND pattern * CLOSEPAREN
+
+ BAR shift 12
+ CLOSEPAREN shift 98
+
+State 35:
+ pattern ::= pattern * BAR pattern
+ subpattern ::= OPENASSERTION PATTERNNAME pattern * CLOSEPAREN
+ subpattern ::= OPENASSERTION PATTERNNAME pattern * CLOSEPAREN MULTIPLIER
+
+ BAR shift 12
+ CLOSEPAREN shift 48
+
+State 36:
+ pattern ::= pattern * BAR pattern
+ onceonly ::= OPENASSERTION ONCEONLY pattern * CLOSEPAREN
+
+ BAR shift 12
+ CLOSEPAREN shift 88
+
+State 37:
+ pattern ::= pattern * BAR pattern
+ lookahead ::= OPENASSERTION NEGATIVELOOKAHEAD pattern * CLOSEPAREN
+
+ BAR shift 12
+ CLOSEPAREN shift 77
+
+State 38:
+ pattern ::= pattern * BAR pattern
+ lookbehind ::= OPENASSERTION POSITIVELOOKBEHIND pattern * CLOSEPAREN
+
+ BAR shift 12
+ CLOSEPAREN shift 102
+
+State 39:
+ pattern ::= pattern * BAR pattern
+ conditional ::= OPENASSERTION lookahead pattern * CLOSEPAREN
+ conditional ::= OPENASSERTION lookahead pattern * CLOSEPAREN MULTIPLIER
+
+ BAR shift 12
+ CLOSEPAREN shift 51
+
+State 40:
+ pattern ::= pattern * BAR pattern
+ lookahead ::= OPENASSERTION POSITIVELOOKAHEAD pattern * CLOSEPAREN
+
+ BAR shift 12
+ CLOSEPAREN shift 71
+
+State 41:
+ (50) basic_text ::= FULLSTOP *
+ basic_text ::= FULLSTOP * MULTIPLIER
+
+ MULTIPLIER shift 94
+ {default} reduce 50
+
+State 42:
+ (52) basic_text ::= CONTROLCHAR *
+ basic_text ::= CONTROLCHAR * MULTIPLIER
+
+ MULTIPLIER shift 96
+ {default} reduce 52
+
+State 43:
+ (54) basic_text ::= ESCAPEDBACKSLASH *
+ basic_text ::= ESCAPEDBACKSLASH * MULTIPLIER
+
+ MULTIPLIER shift 75
+ {default} reduce 54
+
+State 44:
+ (56) basic_text ::= BACKREFERENCE *
+ basic_text ::= BACKREFERENCE * MULTIPLIER
+
+ MULTIPLIER shift 132
+ {default} reduce 56
+
+State 45:
+ (0) start ::= pattern *
+ pattern ::= pattern * BAR pattern
+
+ BAR shift 12
+ {default} reduce 0
+
+State 46:
+ conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN * MULTIPLIER
+ (77) conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN *
+
+ MULTIPLIER shift 103
+ {default} reduce 77
+
+State 47:
+ (80) conditional ::= OPENASSERTION lookbehind pattern CLOSEPAREN *
+ conditional ::= OPENASSERTION lookbehind pattern CLOSEPAREN * MULTIPLIER
+
+ MULTIPLIER shift 78
+ {default} reduce 80
+
+State 48:
+ (86) subpattern ::= OPENASSERTION PATTERNNAME pattern CLOSEPAREN *
+ subpattern ::= OPENASSERTION PATTERNNAME pattern CLOSEPAREN * MULTIPLIER
+
+ MULTIPLIER shift 95
+ {default} reduce 86
+
+State 49:
+ comment ::= OPENASSERTION COMMENT * CLOSEPAREN
+
+ CLOSEPAREN shift 90
+
+State 50:
+ recur ::= OPENASSERTION RECUR * CLOSEPAREN
+
+ CLOSEPAREN shift 93
+
+State 51:
+ (78) conditional ::= OPENASSERTION lookahead pattern CLOSEPAREN *
+ conditional ::= OPENASSERTION lookahead pattern CLOSEPAREN * MULTIPLIER
+
+ MULTIPLIER shift 79
+ {default} reduce 78
+
+State 52:
+ (48) basic_text ::= TEXT *
+ basic_text ::= TEXT * MULTIPLIER
+
+ MULTIPLIER shift 120
+ {default} reduce 48
+
+State 53:
+ (74) grouping ::= OPENASSERTION COLON pattern CLOSEPAREN *
+ grouping ::= OPENASSERTION COLON pattern CLOSEPAREN * MULTIPLIER
+
+ MULTIPLIER shift 121
+ {default} reduce 74
+
+State 54:
+ conditional ::= OPENASSERTION OPENPAREN * TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION OPENPAREN * TEXT CLOSEPAREN pattern CLOSEPAREN
+
+ TEXT shift 55
+
+State 55:
+ conditional ::= OPENASSERTION OPENPAREN TEXT * CLOSEPAREN pattern CLOSEPAREN MULTIPLIER
+ conditional ::= OPENASSERTION OPENPAREN TEXT * CLOSEPAREN pattern CLOSEPAREN
+
+ CLOSEPAREN shift 3
+
+State 56:
+ (88) subpattern ::= OPENPAREN pattern CLOSEPAREN *
+ subpattern ::= OPENPAREN pattern CLOSEPAREN * MULTIPLIER
+
+ MULTIPLIER shift 110
+ {default} reduce 88
+
+State 57:
+ (58) basic_text ::= COULDBEBACKREF *
+ basic_text ::= COULDBEBACKREF * MULTIPLIER
+
+ MULTIPLIER shift 114
+ {default} reduce 58
+
+State 58:
+ (70) basic_text ::= basic_text COULDBEBACKREF *
+ basic_text ::= basic_text COULDBEBACKREF * MULTIPLIER
+
+ MULTIPLIER shift 74
+ {default} reduce 70
+
+State 59:
+ (28) character_class ::= OPENCHARCLASS character_class_contents CLOSECHARCLASS *
+ character_class ::= OPENCHARCLASS character_class_contents CLOSECHARCLASS * MULTIPLIER
+
+ MULTIPLIER shift 123
+ {default} reduce 28
+
+State 60:
+ (41) character_class_contents ::= character_class_contents TEXT *
+ character_class_contents ::= character_class_contents TEXT * HYPHEN ESCAPEDBACKSLASH
+ character_class_contents ::= character_class_contents TEXT * HYPHEN TEXT
+
+ HYPHEN shift 27
+ {default} reduce 41
+
+State 61:
+ (29) character_class ::= OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS *
+ character_class ::= OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS * MULTIPLIER
+
+ MULTIPLIER shift 115
+ {default} reduce 29
+
+State 62:
+ (68) basic_text ::= basic_text BACKREFERENCE *
+ basic_text ::= basic_text BACKREFERENCE * MULTIPLIER
+
+ MULTIPLIER shift 73
+ {default} reduce 68
+
+State 63:
+ (66) basic_text ::= basic_text ESCAPEDBACKSLASH *
+ basic_text ::= basic_text ESCAPEDBACKSLASH * MULTIPLIER
+
+ MULTIPLIER shift 86
+ {default} reduce 66
+
+State 64:
+ (60) basic_text ::= basic_text TEXT *
+ basic_text ::= basic_text TEXT * MULTIPLIER
+
+ MULTIPLIER shift 89
+ {default} reduce 60
+
+State 65:
+ (62) basic_text ::= basic_text FULLSTOP *
+ basic_text ::= basic_text FULLSTOP * MULTIPLIER
+
+ MULTIPLIER shift 100
+ {default} reduce 62
+
+State 66:
+ (64) basic_text ::= basic_text CONTROLCHAR *
+ basic_text ::= basic_text CONTROLCHAR * MULTIPLIER
+
+ MULTIPLIER shift 99
+ {default} reduce 64
+
+State 67:
+ (32) character_class_contents ::= TEXT *
+ character_class_contents ::= TEXT * HYPHEN TEXT
+ character_class_contents ::= TEXT * HYPHEN ESCAPEDBACKSLASH
+
+ HYPHEN shift 29
+ {default} reduce 32
+
+State 68:
+ (40) character_class_contents ::= character_class_contents ESCAPEDBACKSLASH *
+ character_class_contents ::= character_class_contents ESCAPEDBACKSLASH * HYPHEN CONTROLCHAR
+ character_class_contents ::= character_class_contents ESCAPEDBACKSLASH * HYPHEN TEXT
+
+ HYPHEN shift 31
+ {default} reduce 40
+
+State 69:
+ (33) character_class_contents ::= ESCAPEDBACKSLASH *
+ character_class_contents ::= ESCAPEDBACKSLASH * HYPHEN TEXT
+
+ HYPHEN shift 70
+ {default} reduce 33
+
+State 70:
+ character_class_contents ::= ESCAPEDBACKSLASH HYPHEN * TEXT
+
+ TEXT shift 83
+
+State 71:
+ (82) lookahead ::= OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN *
+
+ {default} reduce 82
+
+State 72:
+ (18) basic_pattern ::= basic_pattern character_class *
+
+ {default} reduce 18
+
+State 73:
+ (69) basic_text ::= basic_text BACKREFERENCE MULTIPLIER *
+
+ {default} reduce 69
+
+State 74:
+ (71) basic_text ::= basic_text COULDBEBACKREF MULTIPLIER *
+
+ {default} reduce 71
+
+State 75:
+ (55) basic_text ::= ESCAPEDBACKSLASH MULTIPLIER *
+
+ {default} reduce 55
+
+State 76:
+ (19) basic_pattern ::= basic_pattern assertion *
+
+ {default} reduce 19
+
+State 77:
+ (83) lookahead ::= OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN *
+
+ {default} reduce 83
+
+State 78:
+ (81) conditional ::= OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER *
+
+ {default} reduce 81
+
+State 79:
+ (79) conditional ::= OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER *
+
+ {default} reduce 79
+
+State 80:
+ (24) basic_pattern ::= basic_pattern onceonly *
+
+ {default} reduce 24
+
+State 81:
+ (23) basic_pattern ::= basic_pattern subpattern *
+
+ {default} reduce 23
+
+State 82:
+ (22) basic_pattern ::= basic_pattern lookbehind *
+
+ {default} reduce 22
+
+State 83:
+ (34) character_class_contents ::= ESCAPEDBACKSLASH HYPHEN TEXT *
+
+ {default} reduce 34
+
+State 84:
+ (21) basic_pattern ::= basic_pattern lookahead *
+
+ {default} reduce 21
+
+State 85:
+ (20) basic_pattern ::= basic_pattern grouping *
+
+ {default} reduce 20
+
+State 86:
+ (67) basic_text ::= basic_text ESCAPEDBACKSLASH MULTIPLIER *
+
+ {default} reduce 67
+
+State 87:
+ (38) character_class_contents ::= COULDBEBACKREF *
+
+ {default} reduce 38
+
+State 88:
+ (90) onceonly ::= OPENASSERTION ONCEONLY pattern CLOSEPAREN *
+
+ {default} reduce 90
+
+State 89:
+ (61) basic_text ::= basic_text TEXT MULTIPLIER *
+
+ {default} reduce 61
+
+State 90:
+ (91) comment ::= OPENASSERTION COMMENT CLOSEPAREN *
+
+ {default} reduce 91
+
+State 91:
+ (1) pattern ::= MATCHSTART basic_pattern MATCHEND *
+
+ {default} reduce 1
+
+State 92:
+ pattern ::= pattern * BAR pattern
+ (5) pattern ::= pattern BAR pattern *
+
+ {default} reduce 5
+
+State 93:
+ (92) recur ::= OPENASSERTION RECUR CLOSEPAREN *
+
+ {default} reduce 92
+
+State 94:
+ (51) basic_text ::= FULLSTOP MULTIPLIER *
+
+ {default} reduce 51
+
+State 95:
+ (87) subpattern ::= OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER *
+
+ {default} reduce 87
+
+State 96:
+ (53) basic_text ::= CONTROLCHAR MULTIPLIER *
+
+ {default} reduce 53
+
+State 97:
+ (25) basic_pattern ::= basic_pattern comment *
+
+ {default} reduce 25
+
+State 98:
+ (85) lookbehind ::= OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN *
+
+ {default} reduce 85
+
+State 99:
+ (65) basic_text ::= basic_text CONTROLCHAR MULTIPLIER *
+
+ {default} reduce 65
+
+State 100:
+ (63) basic_text ::= basic_text FULLSTOP MULTIPLIER *
+
+ {default} reduce 63
+
+State 101:
+ (37) character_class_contents ::= BACKREFERENCE *
+
+ {default} reduce 37
+
+State 102:
+ (84) lookbehind ::= OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN *
+
+ {default} reduce 84
+
+State 103:
+ (76) conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER *
+
+ {default} reduce 76
+
+State 104:
+ (7) basic_pattern ::= character_class *
+
+ {default} reduce 7
+
+State 105:
+ (45) character_class_contents ::= character_class_contents TEXT HYPHEN TEXT *
+
+ {default} reduce 45
+
+State 106:
+ (8) basic_pattern ::= assertion *
+
+ {default} reduce 8
+
+State 107:
+ (9) basic_pattern ::= grouping *
+
+ {default} reduce 9
+
+State 108:
+ (11) basic_pattern ::= lookbehind *
+
+ {default} reduce 11
+
+State 109:
+ (10) basic_pattern ::= lookahead *
+
+ {default} reduce 10
+
+State 110:
+ (89) subpattern ::= OPENPAREN pattern CLOSEPAREN MULTIPLIER *
+
+ {default} reduce 89
+
+State 111:
+ (46) character_class_contents ::= character_class_contents BACKREFERENCE *
+
+ {default} reduce 46
+
+State 112:
+ (72) assertion ::= OPENASSERTION INTERNALOPTIONS CLOSEPAREN *
+
+ {default} reduce 72
+
+State 113:
+ (35) character_class_contents ::= TEXT HYPHEN TEXT *
+
+ {default} reduce 35
+
+State 114:
+ (59) basic_text ::= COULDBEBACKREF MULTIPLIER *
+
+ {default} reduce 59
+
+State 115:
+ (31) character_class ::= OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER *
+
+ {default} reduce 31
+
+State 116:
+ (47) character_class_contents ::= character_class_contents COULDBEBACKREF *
+
+ {default} reduce 47
+
+State 117:
+ (3) pattern ::= basic_pattern MATCHEND *
+
+ {default} reduce 3
+
+State 118:
+ (12) basic_pattern ::= subpattern *
+
+ {default} reduce 12
+
+State 119:
+ (13) basic_pattern ::= onceonly *
+
+ {default} reduce 13
+
+State 120:
+ (49) basic_text ::= TEXT MULTIPLIER *
+
+ {default} reduce 49
+
+State 121:
+ (75) grouping ::= OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER *
+
+ {default} reduce 75
+
+State 122:
+ (39) character_class_contents ::= character_class_contents CONTROLCHAR *
+
+ {default} reduce 39
+
+State 123:
+ (30) character_class ::= OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER *
+
+ {default} reduce 30
+
+State 124:
+ (36) character_class_contents ::= TEXT HYPHEN ESCAPEDBACKSLASH *
+
+ {default} reduce 36
+
+State 125:
+ (27) basic_pattern ::= basic_pattern conditional *
+
+ {default} reduce 27
+
+State 126:
+ (42) character_class_contents ::= character_class_contents ESCAPEDBACKSLASH HYPHEN CONTROLCHAR *
+
+ {default} reduce 42
+
+State 127:
+ (43) character_class_contents ::= character_class_contents ESCAPEDBACKSLASH HYPHEN TEXT *
+
+ {default} reduce 43
+
+State 128:
+ (15) basic_pattern ::= recur *
+
+ {default} reduce 15
+
+State 129:
+ (14) basic_pattern ::= comment *
+
+ {default} reduce 14
+
+State 130:
+ (16) basic_pattern ::= conditional *
+
+ {default} reduce 16
+
+State 131:
+ (44) character_class_contents ::= character_class_contents TEXT HYPHEN ESCAPEDBACKSLASH *
+
+ {default} reduce 44
+
+State 132:
+ (57) basic_text ::= BACKREFERENCE MULTIPLIER *
+
+ {default} reduce 57
+
+State 133:
+ (73) assertion ::= OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN *
+
+ {default} reduce 73
+
+State 134:
+ (26) basic_pattern ::= basic_pattern recur *
+
+ {default} reduce 26
+
diff --git a/core/oql/build/PHP/LexerGenerator/Regex/Parser.php b/core/oql/build/PHP/LexerGenerator/Regex/Parser.php
new file mode 100644
index 000000000..4e1faf1fd
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Regex/Parser.php
@@ -0,0 +1,1933 @@
+string = $s->string;
+ $this->metadata = $s->metadata;
+ } else {
+ $this->string = (string) $s;
+ if ($m instanceof PHP_LexerGenerator_Regex_yyToken) {
+ $this->metadata = $m->metadata;
+ } elseif (is_array($m)) {
+ $this->metadata = $m;
+ }
+ }
+ }
+
+ function __toString()
+ {
+ return $this->_string;
+ }
+
+ function offsetExists($offset)
+ {
+ return isset($this->metadata[$offset]);
+ }
+
+ function offsetGet($offset)
+ {
+ return $this->metadata[$offset];
+ }
+
+ function offsetSet($offset, $value)
+ {
+ if ($offset === null) {
+ if (isset($value[0])) {
+ $x = ($value instanceof PHP_LexerGenerator_Regex_yyToken) ?
+ $value->metadata : $value;
+ $this->metadata = array_merge($this->metadata, $x);
+ return;
+ }
+ $offset = count($this->metadata);
+ }
+ if ($value === null) {
+ return;
+ }
+ if ($value instanceof PHP_LexerGenerator_Regex_yyToken) {
+ if ($value->metadata) {
+ $this->metadata[$offset] = $value->metadata;
+ }
+ } elseif ($value) {
+ $this->metadata[$offset] = $value;
+ }
+ }
+
+ function offsetUnset($offset)
+ {
+ unset($this->metadata[$offset]);
+ }
+}
+
+/** The following structure represents a single element of the
+ * parser's stack. Information stored includes:
+ *
+ * + The state number for the parser at this level of the stack.
+ *
+ * + The value of the token stored at this level of the stack.
+ * (In other words, the "major" token.)
+ *
+ * + The semantic value stored at this level of the stack. This is
+ * the information used by the action routines in the grammar.
+ * It is sometimes called the "minor" token.
+ */
+class PHP_LexerGenerator_Regex_yyStackEntry
+{
+ public $stateno; /* The state-number */
+ public $major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ public $minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+
+// code external to the class is included here
+#line 2 "Parser.y"
+
+require_once 'PHP/LexerGenerator/Exception.php';
+#line 102 "Parser.php"
+
+// declare_class is output here
+#line 5 "Parser.y"
+class PHP_LexerGenerator_Regex_Parser#line 107 "Parser.php"
+{
+/* First off, code is included which follows the "include_class" declaration
+** in the input file. */
+#line 21 "Parser.y"
+
+ private $_lex;
+ private $_subpatterns;
+ private $_updatePattern;
+ private $_patternIndex;
+ public $result;
+ function __construct($lex)
+ {
+ $this->result = new PHP_LexerGenerator_ParseryyToken('');
+ $this->_lex = $lex;
+ $this->_subpatterns = 0;
+ $this->_patternIndex = 1;
+ }
+
+ function reset($patternIndex, $updatePattern = false)
+ {
+ $this->_updatePattern = $updatePattern;
+ $this->_patternIndex = $patternIndex;
+ $this->_subpatterns = 0;
+ $this->result = new PHP_LexerGenerator_ParseryyToken('');
+ }
+#line 134 "Parser.php"
+
+/* Next is all token values, as class constants
+*/
+/*
+** These constants (all generated automatically by the parser generator)
+** specify the various kinds of tokens (terminals) that the parser
+** understands.
+**
+** Each symbol here is a terminal symbol in the grammar.
+*/
+ const OPENPAREN = 1;
+ const OPENASSERTION = 2;
+ const BAR = 3;
+ const MULTIPLIER = 4;
+ const MATCHSTART = 5;
+ const MATCHEND = 6;
+ const OPENCHARCLASS = 7;
+ const CLOSECHARCLASS = 8;
+ const NEGATE = 9;
+ const TEXT = 10;
+ const ESCAPEDBACKSLASH = 11;
+ const HYPHEN = 12;
+ const BACKREFERENCE = 13;
+ const COULDBEBACKREF = 14;
+ const CONTROLCHAR = 15;
+ const FULLSTOP = 16;
+ const INTERNALOPTIONS = 17;
+ const CLOSEPAREN = 18;
+ const COLON = 19;
+ const POSITIVELOOKAHEAD = 20;
+ const NEGATIVELOOKAHEAD = 21;
+ const POSITIVELOOKBEHIND = 22;
+ const NEGATIVELOOKBEHIND = 23;
+ const PATTERNNAME = 24;
+ const ONCEONLY = 25;
+ const COMMENT = 26;
+ const RECUR = 27;
+ const YY_NO_ACTION = 230;
+ const YY_ACCEPT_ACTION = 229;
+ const YY_ERROR_ACTION = 228;
+
+/* Next are that tables used to determine what action to take based on the
+** current state and lookahead token. These tables are used to implement
+** functions that take a state number and lookahead value and return an
+** action integer.
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N < self::YYNSTATE Shift N. That is,
+** push the lookahead
+** token onto the stack
+** and goto state N.
+**
+** self::YYNSTATE <= N < self::YYNSTATE+self::YYNRULE Reduce by rule N-YYNSTATE.
+**
+** N == self::YYNSTATE+self::YYNRULE A syntax error has occurred.
+**
+** N == self::YYNSTATE+self::YYNRULE+1 The parser accepts its
+** input. (and concludes parsing)
+**
+** N == self::YYNSTATE+self::YYNRULE+2 No such action. Denotes unused
+** slots in the yy_action[] table.
+**
+** The action table is constructed as a single large static array $yy_action.
+** Given state S and lookahead X, the action is computed as
+**
+** self::$yy_action[self::$yy_shift_ofst[S] + X ]
+**
+** If the index value self::$yy_shift_ofst[S]+X is out of range or if the value
+** self::$yy_lookahead[self::$yy_shift_ofst[S]+X] is not equal to X or if
+** self::$yy_shift_ofst[S] is equal to self::YY_SHIFT_USE_DFLT, it means that
+** the action is not in the table and that self::$yy_default[S] should be used instead.
+**
+** The formula above is for computing the action when the lookahead is
+** a terminal symbol. If the lookahead is a non-terminal (as occurs after
+** a reduce action) then the static $yy_reduce_ofst array is used in place of
+** the static $yy_shift_ofst array and self::YY_REDUCE_USE_DFLT is used in place of
+** self::YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** self::$yy_action A single table containing all actions.
+** self::$yy_lookahead A table containing the lookahead for each entry in
+** yy_action. Used to detect hash collisions.
+** self::$yy_shift_ofst For each state, the offset into self::$yy_action for
+** shifting terminals.
+** self::$yy_reduce_ofst For each state, the offset into self::$yy_action for
+** shifting non-terminals after a reduce.
+** self::$yy_default Default action for each state.
+*/
+ const YY_SZ_ACTTAB = 354;
+static public $yy_action = array(
+ /* 0 */ 229, 45, 15, 23, 104, 106, 107, 109, 108, 118,
+ /* 10 */ 119, 129, 128, 130, 36, 15, 23, 104, 106, 107,
+ /* 20 */ 109, 108, 118, 119, 129, 128, 130, 39, 15, 23,
+ /* 30 */ 104, 106, 107, 109, 108, 118, 119, 129, 128, 130,
+ /* 40 */ 25, 15, 23, 104, 106, 107, 109, 108, 118, 119,
+ /* 50 */ 129, 128, 130, 32, 15, 23, 104, 106, 107, 109,
+ /* 60 */ 108, 118, 119, 129, 128, 130, 28, 15, 23, 104,
+ /* 70 */ 106, 107, 109, 108, 118, 119, 129, 128, 130, 35,
+ /* 80 */ 15, 23, 104, 106, 107, 109, 108, 118, 119, 129,
+ /* 90 */ 128, 130, 92, 15, 23, 104, 106, 107, 109, 108,
+ /* 100 */ 118, 119, 129, 128, 130, 38, 15, 23, 104, 106,
+ /* 110 */ 107, 109, 108, 118, 119, 129, 128, 130, 40, 15,
+ /* 120 */ 23, 104, 106, 107, 109, 108, 118, 119, 129, 128,
+ /* 130 */ 130, 33, 15, 23, 104, 106, 107, 109, 108, 118,
+ /* 140 */ 119, 129, 128, 130, 30, 15, 23, 104, 106, 107,
+ /* 150 */ 109, 108, 118, 119, 129, 128, 130, 37, 15, 23,
+ /* 160 */ 104, 106, 107, 109, 108, 118, 119, 129, 128, 130,
+ /* 170 */ 34, 15, 23, 104, 106, 107, 109, 108, 118, 119,
+ /* 180 */ 129, 128, 130, 16, 23, 104, 106, 107, 109, 108,
+ /* 190 */ 118, 119, 129, 128, 130, 54, 24, 22, 72, 76,
+ /* 200 */ 85, 84, 82, 81, 80, 97, 134, 125, 93, 12,
+ /* 210 */ 12, 26, 83, 2, 5, 1, 11, 4, 10, 13,
+ /* 220 */ 49, 50, 9, 17, 46, 98, 14, 12, 18, 113,
+ /* 230 */ 124, 52, 43, 79, 44, 57, 42, 41, 9, 17,
+ /* 240 */ 127, 12, 53, 91, 18, 126, 12, 52, 43, 120,
+ /* 250 */ 44, 57, 42, 41, 9, 17, 47, 12, 31, 117,
+ /* 260 */ 18, 88, 99, 52, 43, 75, 44, 57, 42, 41,
+ /* 270 */ 9, 17, 51, 19, 67, 69, 18, 101, 87, 52,
+ /* 280 */ 43, 12, 44, 57, 42, 41, 132, 64, 63, 103,
+ /* 290 */ 62, 58, 66, 65, 59, 12, 60, 68, 90, 111,
+ /* 300 */ 116, 122, 61, 100, 60, 68, 12, 111, 116, 122,
+ /* 310 */ 71, 5, 1, 11, 4, 67, 69, 12, 101, 87,
+ /* 320 */ 12, 102, 12, 12, 112, 6, 105, 131, 78, 7,
+ /* 330 */ 8, 95, 77, 74, 70, 56, 123, 48, 133, 73,
+ /* 340 */ 27, 114, 86, 55, 115, 89, 110, 121, 3, 94,
+ /* 350 */ 21, 29, 96, 20,
+ );
+ static public $yy_lookahead = array(
+ /* 0 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ /* 10 */ 39, 40, 41, 42, 30, 31, 32, 33, 34, 35,
+ /* 20 */ 36, 37, 38, 39, 40, 41, 42, 30, 31, 32,
+ /* 30 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ /* 40 */ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ /* 50 */ 40, 41, 42, 30, 31, 32, 33, 34, 35, 36,
+ /* 60 */ 37, 38, 39, 40, 41, 42, 30, 31, 32, 33,
+ /* 70 */ 34, 35, 36, 37, 38, 39, 40, 41, 42, 30,
+ /* 80 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ /* 90 */ 41, 42, 30, 31, 32, 33, 34, 35, 36, 37,
+ /* 100 */ 38, 39, 40, 41, 42, 30, 31, 32, 33, 34,
+ /* 110 */ 35, 36, 37, 38, 39, 40, 41, 42, 30, 31,
+ /* 120 */ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ /* 130 */ 42, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ /* 140 */ 39, 40, 41, 42, 30, 31, 32, 33, 34, 35,
+ /* 150 */ 36, 37, 38, 39, 40, 41, 42, 30, 31, 32,
+ /* 160 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ /* 170 */ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ /* 180 */ 40, 41, 42, 31, 32, 33, 34, 35, 36, 37,
+ /* 190 */ 38, 39, 40, 41, 42, 1, 2, 32, 33, 34,
+ /* 200 */ 35, 36, 37, 38, 39, 40, 41, 42, 18, 3,
+ /* 210 */ 3, 17, 10, 19, 20, 21, 22, 23, 24, 25,
+ /* 220 */ 26, 27, 1, 2, 18, 18, 5, 3, 7, 10,
+ /* 230 */ 11, 10, 11, 4, 13, 14, 15, 16, 1, 2,
+ /* 240 */ 10, 3, 18, 6, 7, 15, 3, 10, 11, 4,
+ /* 250 */ 13, 14, 15, 16, 1, 2, 18, 3, 12, 6,
+ /* 260 */ 7, 18, 4, 10, 11, 4, 13, 14, 15, 16,
+ /* 270 */ 1, 2, 18, 9, 10, 11, 7, 13, 14, 10,
+ /* 280 */ 11, 3, 13, 14, 15, 16, 4, 10, 11, 4,
+ /* 290 */ 13, 14, 15, 16, 8, 3, 10, 11, 18, 13,
+ /* 300 */ 14, 15, 8, 4, 10, 11, 3, 13, 14, 15,
+ /* 310 */ 18, 20, 21, 22, 23, 10, 11, 3, 13, 14,
+ /* 320 */ 3, 18, 3, 3, 18, 19, 10, 11, 4, 36,
+ /* 330 */ 37, 4, 18, 4, 12, 18, 4, 18, 18, 4,
+ /* 340 */ 12, 4, 4, 10, 4, 4, 4, 4, 18, 4,
+ /* 350 */ 43, 12, 4, 43,
+);
+ const YY_SHIFT_USE_DFLT = -1;
+ const YY_SHIFT_MAX = 70;
+ static public $yy_shift_ofst = array(
+ /* 0 */ 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
+ /* 10 */ 221, 221, 221, 221, 269, 253, 237, 194, 264, 305,
+ /* 20 */ 286, 294, 277, 277, 291, 320, 306, 316, 317, 219,
+ /* 30 */ 224, 230, 238, 206, 207, 319, 243, 314, 303, 254,
+ /* 40 */ 292, 345, 348, 261, 282, 278, 285, 324, 327, 280,
+ /* 50 */ 190, 229, 245, 343, 333, 330, 342, 337, 329, 332,
+ /* 60 */ 328, 340, 335, 338, 341, 299, 258, 339, 246, 322,
+ /* 70 */ 202,
+);
+ const YY_REDUCE_USE_DFLT = -30;
+ const YY_REDUCE_MAX = 19;
+ static public $yy_reduce_ofst = array(
+ /* 0 */ -29, 127, 114, 101, 140, 88, 10, -3, 23, 36,
+ /* 10 */ 49, 75, 62, -16, 152, 165, 165, 293, 310, 307,
+);
+ static public $yyExpectedTokens = array(
+ /* 0 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 1 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 2 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 3 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 4 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 5 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 6 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 7 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 8 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 9 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 10 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 11 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 12 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 13 */ array(1, 2, 5, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 14 */ array(1, 2, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 15 */ array(1, 2, 6, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 16 */ array(1, 2, 6, 7, 10, 11, 13, 14, 15, 16, ),
+ /* 17 */ array(1, 2, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, ),
+ /* 18 */ array(9, 10, 11, 13, 14, ),
+ /* 19 */ array(10, 11, 13, 14, ),
+ /* 20 */ array(8, 10, 11, 13, 14, 15, ),
+ /* 21 */ array(8, 10, 11, 13, 14, 15, ),
+ /* 22 */ array(10, 11, 13, 14, 15, 16, ),
+ /* 23 */ array(10, 11, 13, 14, 15, 16, ),
+ /* 24 */ array(20, 21, 22, 23, ),
+ /* 25 */ array(3, 18, ),
+ /* 26 */ array(18, 19, ),
+ /* 27 */ array(10, 11, ),
+ /* 28 */ array(3, 18, ),
+ /* 29 */ array(10, 11, ),
+ /* 30 */ array(3, 18, ),
+ /* 31 */ array(10, 15, ),
+ /* 32 */ array(3, 18, ),
+ /* 33 */ array(3, 18, ),
+ /* 34 */ array(3, 18, ),
+ /* 35 */ array(3, 18, ),
+ /* 36 */ array(3, 18, ),
+ /* 37 */ array(3, 18, ),
+ /* 38 */ array(3, 18, ),
+ /* 39 */ array(3, 18, ),
+ /* 40 */ array(3, 18, ),
+ /* 41 */ array(4, ),
+ /* 42 */ array(4, ),
+ /* 43 */ array(4, ),
+ /* 44 */ array(4, ),
+ /* 45 */ array(3, ),
+ /* 46 */ array(4, ),
+ /* 47 */ array(4, ),
+ /* 48 */ array(4, ),
+ /* 49 */ array(18, ),
+ /* 50 */ array(18, ),
+ /* 51 */ array(4, ),
+ /* 52 */ array(4, ),
+ /* 53 */ array(4, ),
+ /* 54 */ array(10, ),
+ /* 55 */ array(18, ),
+ /* 56 */ array(4, ),
+ /* 57 */ array(4, ),
+ /* 58 */ array(4, ),
+ /* 59 */ array(4, ),
+ /* 60 */ array(12, ),
+ /* 61 */ array(4, ),
+ /* 62 */ array(4, ),
+ /* 63 */ array(4, ),
+ /* 64 */ array(4, ),
+ /* 65 */ array(4, ),
+ /* 66 */ array(4, ),
+ /* 67 */ array(12, ),
+ /* 68 */ array(12, ),
+ /* 69 */ array(12, ),
+ /* 70 */ array(10, ),
+ /* 71 */ array(),
+ /* 72 */ array(),
+ /* 73 */ array(),
+ /* 74 */ array(),
+ /* 75 */ array(),
+ /* 76 */ array(),
+ /* 77 */ array(),
+ /* 78 */ array(),
+ /* 79 */ array(),
+ /* 80 */ array(),
+ /* 81 */ array(),
+ /* 82 */ array(),
+ /* 83 */ array(),
+ /* 84 */ array(),
+ /* 85 */ array(),
+ /* 86 */ array(),
+ /* 87 */ array(),
+ /* 88 */ array(),
+ /* 89 */ array(),
+ /* 90 */ array(),
+ /* 91 */ array(),
+ /* 92 */ array(),
+ /* 93 */ array(),
+ /* 94 */ array(),
+ /* 95 */ array(),
+ /* 96 */ array(),
+ /* 97 */ array(),
+ /* 98 */ array(),
+ /* 99 */ array(),
+ /* 100 */ array(),
+ /* 101 */ array(),
+ /* 102 */ array(),
+ /* 103 */ array(),
+ /* 104 */ array(),
+ /* 105 */ array(),
+ /* 106 */ array(),
+ /* 107 */ array(),
+ /* 108 */ array(),
+ /* 109 */ array(),
+ /* 110 */ array(),
+ /* 111 */ array(),
+ /* 112 */ array(),
+ /* 113 */ array(),
+ /* 114 */ array(),
+ /* 115 */ array(),
+ /* 116 */ array(),
+ /* 117 */ array(),
+ /* 118 */ array(),
+ /* 119 */ array(),
+ /* 120 */ array(),
+ /* 121 */ array(),
+ /* 122 */ array(),
+ /* 123 */ array(),
+ /* 124 */ array(),
+ /* 125 */ array(),
+ /* 126 */ array(),
+ /* 127 */ array(),
+ /* 128 */ array(),
+ /* 129 */ array(),
+ /* 130 */ array(),
+ /* 131 */ array(),
+ /* 132 */ array(),
+ /* 133 */ array(),
+ /* 134 */ array(),
+);
+ static public $yy_default = array(
+ /* 0 */ 228, 228, 228, 228, 228, 228, 228, 228, 228, 228,
+ /* 10 */ 228, 228, 228, 228, 228, 139, 137, 228, 228, 228,
+ /* 20 */ 228, 228, 152, 141, 228, 228, 228, 228, 228, 228,
+ /* 30 */ 228, 228, 228, 228, 228, 228, 228, 228, 228, 228,
+ /* 40 */ 228, 185, 187, 189, 191, 135, 212, 215, 221, 228,
+ /* 50 */ 228, 213, 183, 209, 228, 228, 223, 193, 205, 163,
+ /* 60 */ 176, 164, 203, 201, 195, 197, 199, 167, 175, 168,
+ /* 70 */ 228, 217, 153, 204, 206, 190, 154, 218, 216, 214,
+ /* 80 */ 159, 158, 157, 169, 156, 155, 202, 173, 225, 196,
+ /* 90 */ 226, 136, 140, 227, 186, 222, 188, 160, 220, 200,
+ /* 100 */ 198, 172, 219, 211, 142, 180, 143, 144, 146, 145,
+ /* 110 */ 224, 181, 207, 170, 194, 166, 182, 138, 147, 148,
+ /* 120 */ 184, 210, 174, 165, 171, 162, 177, 178, 150, 149,
+ /* 130 */ 151, 179, 192, 208, 161,
+);
+/* The next thing included is series of defines which control
+** various aspects of the generated parser.
+** self::YYNOCODE is a number which corresponds
+** to no legal terminal or nonterminal number. This
+** number is used to fill in empty slots of the hash
+** table.
+** self::YYFALLBACK If defined, this indicates that one or more tokens
+** have fall-back values which should be used if the
+** original value of the token will not parse.
+** self::YYSTACKDEPTH is the maximum depth of the parser's stack.
+** self::YYNSTATE the combined number of states.
+** self::YYNRULE the number of rules in the grammar
+** self::YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+*/
+ const YYNOCODE = 45;
+ const YYSTACKDEPTH = 100;
+ const YYNSTATE = 135;
+ const YYNRULE = 93;
+ const YYERRORSYMBOL = 28;
+ const YYERRSYMDT = 'yy0';
+ const YYFALLBACK = 0;
+ /** The next table maps tokens into fallback tokens. If a construct
+ * like the following:
+ *
+ * %fallback ID X Y Z.
+ *
+ * appears in the grammer, then ID becomes a fallback token for X, Y,
+ * and Z. Whenever one of the tokens X, Y, or Z is input to the parser
+ * but it does not parse, the type of the token is changed to ID and
+ * the parse is retried before an error is thrown.
+ */
+ static public $yyFallback = array(
+ );
+ /**
+ * Turn parser tracing on by giving a stream to which to write the trace
+ * and a prompt to preface each trace message. Tracing is turned off
+ * by making either argument NULL
+ *
+ * Inputs:
+ *
+ * - A stream resource to which trace output should be written.
+ * If NULL, then tracing is turned off.
+ * - A prefix string written at the beginning of every
+ * line of trace output. If NULL, then tracing is
+ * turned off.
+ *
+ * Outputs:
+ *
+ * - None.
+ * @param resource
+ * @param string
+ */
+ static function Trace($TraceFILE, $zTracePrompt)
+ {
+ if (!$TraceFILE) {
+ $zTracePrompt = 0;
+ } elseif (!$zTracePrompt) {
+ $TraceFILE = 0;
+ }
+ self::$yyTraceFILE = $TraceFILE;
+ self::$yyTracePrompt = $zTracePrompt;
+ }
+
+ /**
+ * Output debug information to output (php://output stream)
+ */
+ static function PrintTrace()
+ {
+ self::$yyTraceFILE = fopen('php://output', 'w');
+ self::$yyTracePrompt = '';
+ }
+
+ /**
+ * @var resource|0
+ */
+ static public $yyTraceFILE;
+ /**
+ * String to prepend to debug output
+ * @var string|0
+ */
+ static public $yyTracePrompt;
+ /**
+ * @var int
+ */
+ public $yyidx; /* Index of top element in stack */
+ /**
+ * @var int
+ */
+ public $yyerrcnt; /* Shifts left before out of the error */
+ /**
+ * @var array
+ */
+ public $yystack = array(); /* The parser's stack */
+
+ /**
+ * For tracing shifts, the names of all terminals and nonterminals
+ * are required. The following table supplies these names
+ * @var array
+ */
+ static public $yyTokenName = array(
+ '$', 'OPENPAREN', 'OPENASSERTION', 'BAR',
+ 'MULTIPLIER', 'MATCHSTART', 'MATCHEND', 'OPENCHARCLASS',
+ 'CLOSECHARCLASS', 'NEGATE', 'TEXT', 'ESCAPEDBACKSLASH',
+ 'HYPHEN', 'BACKREFERENCE', 'COULDBEBACKREF', 'CONTROLCHAR',
+ 'FULLSTOP', 'INTERNALOPTIONS', 'CLOSEPAREN', 'COLON',
+ 'POSITIVELOOKAHEAD', 'NEGATIVELOOKAHEAD', 'POSITIVELOOKBEHIND', 'NEGATIVELOOKBEHIND',
+ 'PATTERNNAME', 'ONCEONLY', 'COMMENT', 'RECUR',
+ 'error', 'start', 'pattern', 'basic_pattern',
+ 'basic_text', 'character_class', 'assertion', 'grouping',
+ 'lookahead', 'lookbehind', 'subpattern', 'onceonly',
+ 'comment', 'recur', 'conditional', 'character_class_contents',
+ );
+
+ /**
+ * For tracing reduce actions, the names of all rules are required.
+ * @var array
+ */
+ static public $yyRuleName = array(
+ /* 0 */ "start ::= pattern",
+ /* 1 */ "pattern ::= MATCHSTART basic_pattern MATCHEND",
+ /* 2 */ "pattern ::= MATCHSTART basic_pattern",
+ /* 3 */ "pattern ::= basic_pattern MATCHEND",
+ /* 4 */ "pattern ::= basic_pattern",
+ /* 5 */ "pattern ::= pattern BAR pattern",
+ /* 6 */ "basic_pattern ::= basic_text",
+ /* 7 */ "basic_pattern ::= character_class",
+ /* 8 */ "basic_pattern ::= assertion",
+ /* 9 */ "basic_pattern ::= grouping",
+ /* 10 */ "basic_pattern ::= lookahead",
+ /* 11 */ "basic_pattern ::= lookbehind",
+ /* 12 */ "basic_pattern ::= subpattern",
+ /* 13 */ "basic_pattern ::= onceonly",
+ /* 14 */ "basic_pattern ::= comment",
+ /* 15 */ "basic_pattern ::= recur",
+ /* 16 */ "basic_pattern ::= conditional",
+ /* 17 */ "basic_pattern ::= basic_pattern basic_text",
+ /* 18 */ "basic_pattern ::= basic_pattern character_class",
+ /* 19 */ "basic_pattern ::= basic_pattern assertion",
+ /* 20 */ "basic_pattern ::= basic_pattern grouping",
+ /* 21 */ "basic_pattern ::= basic_pattern lookahead",
+ /* 22 */ "basic_pattern ::= basic_pattern lookbehind",
+ /* 23 */ "basic_pattern ::= basic_pattern subpattern",
+ /* 24 */ "basic_pattern ::= basic_pattern onceonly",
+ /* 25 */ "basic_pattern ::= basic_pattern comment",
+ /* 26 */ "basic_pattern ::= basic_pattern recur",
+ /* 27 */ "basic_pattern ::= basic_pattern conditional",
+ /* 28 */ "character_class ::= OPENCHARCLASS character_class_contents CLOSECHARCLASS",
+ /* 29 */ "character_class ::= OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS",
+ /* 30 */ "character_class ::= OPENCHARCLASS character_class_contents CLOSECHARCLASS MULTIPLIER",
+ /* 31 */ "character_class ::= OPENCHARCLASS NEGATE character_class_contents CLOSECHARCLASS MULTIPLIER",
+ /* 32 */ "character_class_contents ::= TEXT",
+ /* 33 */ "character_class_contents ::= ESCAPEDBACKSLASH",
+ /* 34 */ "character_class_contents ::= ESCAPEDBACKSLASH HYPHEN TEXT",
+ /* 35 */ "character_class_contents ::= TEXT HYPHEN TEXT",
+ /* 36 */ "character_class_contents ::= TEXT HYPHEN ESCAPEDBACKSLASH",
+ /* 37 */ "character_class_contents ::= BACKREFERENCE",
+ /* 38 */ "character_class_contents ::= COULDBEBACKREF",
+ /* 39 */ "character_class_contents ::= character_class_contents CONTROLCHAR",
+ /* 40 */ "character_class_contents ::= character_class_contents ESCAPEDBACKSLASH",
+ /* 41 */ "character_class_contents ::= character_class_contents TEXT",
+ /* 42 */ "character_class_contents ::= character_class_contents ESCAPEDBACKSLASH HYPHEN CONTROLCHAR",
+ /* 43 */ "character_class_contents ::= character_class_contents ESCAPEDBACKSLASH HYPHEN TEXT",
+ /* 44 */ "character_class_contents ::= character_class_contents TEXT HYPHEN ESCAPEDBACKSLASH",
+ /* 45 */ "character_class_contents ::= character_class_contents TEXT HYPHEN TEXT",
+ /* 46 */ "character_class_contents ::= character_class_contents BACKREFERENCE",
+ /* 47 */ "character_class_contents ::= character_class_contents COULDBEBACKREF",
+ /* 48 */ "basic_text ::= TEXT",
+ /* 49 */ "basic_text ::= TEXT MULTIPLIER",
+ /* 50 */ "basic_text ::= FULLSTOP",
+ /* 51 */ "basic_text ::= FULLSTOP MULTIPLIER",
+ /* 52 */ "basic_text ::= CONTROLCHAR",
+ /* 53 */ "basic_text ::= CONTROLCHAR MULTIPLIER",
+ /* 54 */ "basic_text ::= ESCAPEDBACKSLASH",
+ /* 55 */ "basic_text ::= ESCAPEDBACKSLASH MULTIPLIER",
+ /* 56 */ "basic_text ::= BACKREFERENCE",
+ /* 57 */ "basic_text ::= BACKREFERENCE MULTIPLIER",
+ /* 58 */ "basic_text ::= COULDBEBACKREF",
+ /* 59 */ "basic_text ::= COULDBEBACKREF MULTIPLIER",
+ /* 60 */ "basic_text ::= basic_text TEXT",
+ /* 61 */ "basic_text ::= basic_text TEXT MULTIPLIER",
+ /* 62 */ "basic_text ::= basic_text FULLSTOP",
+ /* 63 */ "basic_text ::= basic_text FULLSTOP MULTIPLIER",
+ /* 64 */ "basic_text ::= basic_text CONTROLCHAR",
+ /* 65 */ "basic_text ::= basic_text CONTROLCHAR MULTIPLIER",
+ /* 66 */ "basic_text ::= basic_text ESCAPEDBACKSLASH",
+ /* 67 */ "basic_text ::= basic_text ESCAPEDBACKSLASH MULTIPLIER",
+ /* 68 */ "basic_text ::= basic_text BACKREFERENCE",
+ /* 69 */ "basic_text ::= basic_text BACKREFERENCE MULTIPLIER",
+ /* 70 */ "basic_text ::= basic_text COULDBEBACKREF",
+ /* 71 */ "basic_text ::= basic_text COULDBEBACKREF MULTIPLIER",
+ /* 72 */ "assertion ::= OPENASSERTION INTERNALOPTIONS CLOSEPAREN",
+ /* 73 */ "assertion ::= OPENASSERTION INTERNALOPTIONS COLON pattern CLOSEPAREN",
+ /* 74 */ "grouping ::= OPENASSERTION COLON pattern CLOSEPAREN",
+ /* 75 */ "grouping ::= OPENASSERTION COLON pattern CLOSEPAREN MULTIPLIER",
+ /* 76 */ "conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN MULTIPLIER",
+ /* 77 */ "conditional ::= OPENASSERTION OPENPAREN TEXT CLOSEPAREN pattern CLOSEPAREN",
+ /* 78 */ "conditional ::= OPENASSERTION lookahead pattern CLOSEPAREN",
+ /* 79 */ "conditional ::= OPENASSERTION lookahead pattern CLOSEPAREN MULTIPLIER",
+ /* 80 */ "conditional ::= OPENASSERTION lookbehind pattern CLOSEPAREN",
+ /* 81 */ "conditional ::= OPENASSERTION lookbehind pattern CLOSEPAREN MULTIPLIER",
+ /* 82 */ "lookahead ::= OPENASSERTION POSITIVELOOKAHEAD pattern CLOSEPAREN",
+ /* 83 */ "lookahead ::= OPENASSERTION NEGATIVELOOKAHEAD pattern CLOSEPAREN",
+ /* 84 */ "lookbehind ::= OPENASSERTION POSITIVELOOKBEHIND pattern CLOSEPAREN",
+ /* 85 */ "lookbehind ::= OPENASSERTION NEGATIVELOOKBEHIND pattern CLOSEPAREN",
+ /* 86 */ "subpattern ::= OPENASSERTION PATTERNNAME pattern CLOSEPAREN",
+ /* 87 */ "subpattern ::= OPENASSERTION PATTERNNAME pattern CLOSEPAREN MULTIPLIER",
+ /* 88 */ "subpattern ::= OPENPAREN pattern CLOSEPAREN",
+ /* 89 */ "subpattern ::= OPENPAREN pattern CLOSEPAREN MULTIPLIER",
+ /* 90 */ "onceonly ::= OPENASSERTION ONCEONLY pattern CLOSEPAREN",
+ /* 91 */ "comment ::= OPENASSERTION COMMENT CLOSEPAREN",
+ /* 92 */ "recur ::= OPENASSERTION RECUR CLOSEPAREN",
+ );
+
+ /**
+ * This function returns the symbolic name associated with a token
+ * value.
+ * @param int
+ * @return string
+ */
+ function tokenName($tokenType)
+ {
+ if ($tokenType === 0) {
+ return 'End of Input';
+ }
+ if ($tokenType > 0 && $tokenType < count(self::$yyTokenName)) {
+ return self::$yyTokenName[$tokenType];
+ } else {
+ return "Unknown";
+ }
+ }
+
+ /**
+ * The following function deletes the value associated with a
+ * symbol. The symbol can be either a terminal or nonterminal.
+ * @param int the symbol code
+ * @param mixed the symbol's value
+ */
+ static function yy_destructor($yymajor, $yypminor)
+ {
+ switch ($yymajor) {
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
+ ** reduce or during error processing or when a parser is
+ ** being destroyed before it is finished parsing.
+ **
+ ** Note: during a reduce, the only symbols destroyed are those
+ ** which appear on the RHS of the rule, but which are not used
+ ** inside the C code.
+ */
+ default: break; /* If no destructor action specified: do nothing */
+ }
+ }
+
+ /**
+ * Pop the parser's stack once.
+ *
+ * If there is a destructor routine associated with the token which
+ * is popped from the stack, then call it.
+ *
+ * Return the major token number for the symbol popped.
+ * @param PHP_LexerGenerator_Regex_yyParser
+ * @return int
+ */
+ function yy_pop_parser_stack()
+ {
+ if (!count($this->yystack)) {
+ return;
+ }
+ $yytos = array_pop($this->yystack);
+ if (self::$yyTraceFILE && $this->yyidx >= 0) {
+ fwrite(self::$yyTraceFILE,
+ self::$yyTracePrompt . 'Popping ' . self::$yyTokenName[$yytos->major] .
+ "\n");
+ }
+ $yymajor = $yytos->major;
+ self::yy_destructor($yymajor, $yytos->minor);
+ $this->yyidx--;
+ return $yymajor;
+ }
+
+ /**
+ * Deallocate and destroy a parser. Destructors are all called for
+ * all stack elements before shutting the parser down.
+ */
+ function __destruct()
+ {
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ if (is_resource(self::$yyTraceFILE)) {
+ fclose(self::$yyTraceFILE);
+ }
+ }
+
+ /**
+ * Based on the current state and parser stack, get a list of all
+ * possible lookahead tokens
+ * @param int
+ * @return array
+ */
+ function yy_get_expected_tokens($token)
+ {
+ $state = $this->yystack[$this->yyidx]->stateno;
+ $expected = self::$yyExpectedTokens[$state];
+ if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return $expected;
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return array_unique($expected);
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+ $nextstate = $this->yy_find_reduce_action(
+ $this->yystack[$this->yyidx]->stateno,
+ self::$yyRuleInfo[$yyruleno]['lhs']);
+ if (isset(self::$yyExpectedTokens[$nextstate])) {
+ $expected += self::$yyExpectedTokens[$nextstate];
+ if (in_array($token,
+ self::$yyExpectedTokens[$nextstate], true)) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return array_unique($expected);
+ }
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new PHP_LexerGenerator_Regex_yyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return array_unique($expected);
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return $expected;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ return array_unique($expected);
+ }
+
+ /**
+ * Based on the parser state and current parser stack, determine whether
+ * the lookahead token is possible.
+ *
+ * The parser will convert the token value to an error token if not. This
+ * catches some unusual edge cases where the parser would fail.
+ * @param int
+ * @return bool
+ */
+ function yy_is_expected_token($token)
+ {
+ if ($token === 0) {
+ return true; // 0 is not part of this
+ }
+ $state = $this->yystack[$this->yyidx]->stateno;
+ if (in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return true;
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return true;
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs'];
+ $nextstate = $this->yy_find_reduce_action(
+ $this->yystack[$this->yyidx]->stateno,
+ self::$yyRuleInfo[$yyruleno]['lhs']);
+ if (isset(self::$yyExpectedTokens[$nextstate]) &&
+ in_array($token, self::$yyExpectedTokens[$nextstate], true)) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new PHP_LexerGenerator_Regex_yyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ if (!$token) {
+ // end of input: this is valid
+ return true;
+ }
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return false;
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return true;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+
+ /**
+ * Find the appropriate action for a parser given the terminal
+ * look-ahead token iLookAhead.
+ *
+ * If the look-ahead token is YYNOCODE, then check to see if the action is
+ * independent of the look-ahead. If it is, return the action, otherwise
+ * return YY_NO_ACTION.
+ * @param int The look-ahead token
+ */
+ function yy_find_shift_action($iLookAhead)
+ {
+ $stateno = $this->yystack[$this->yyidx]->stateno;
+
+ /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */
+ if (!isset(self::$yy_shift_ofst[$stateno])) {
+ // no shift actions
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_shift_ofst[$stateno];
+ if ($i === self::YY_SHIFT_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+ self::$yy_lookahead[$i] != $iLookAhead) {
+ if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback)
+ && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) {
+ if (self::$yyTraceFILE) {
+ fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " .
+ self::$yyTokenName[$iLookAhead] . " => " .
+ self::$yyTokenName[$iFallback] . "\n");
+ }
+ return $this->yy_find_shift_action($iFallback);
+ }
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ /**
+ * Find the appropriate action for a parser given the non-terminal
+ * look-ahead token $iLookAhead.
+ *
+ * If the look-ahead token is self::YYNOCODE, then check to see if the action is
+ * independent of the look-ahead. If it is, return the action, otherwise
+ * return self::YY_NO_ACTION.
+ * @param int Current state number
+ * @param int The look-ahead token
+ */
+ function yy_find_reduce_action($stateno, $iLookAhead)
+ {
+ /* $stateno = $this->yystack[$this->yyidx]->stateno; */
+
+ if (!isset(self::$yy_reduce_ofst[$stateno])) {
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_reduce_ofst[$stateno];
+ if ($i == self::YY_REDUCE_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB ||
+ self::$yy_lookahead[$i] != $iLookAhead) {
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ /**
+ * Perform a shift action.
+ * @param int The new state to shift in
+ * @param int The major token to shift in
+ * @param mixed the minor token to shift in
+ */
+ function yy_shift($yyNewState, $yyMajor, $yypMinor)
+ {
+ $this->yyidx++;
+ if ($this->yyidx >= self::YYSTACKDEPTH) {
+ $this->yyidx--;
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will execute if the parser
+ ** stack ever overflows */
+ return;
+ }
+ $yytos = new PHP_LexerGenerator_Regex_yyStackEntry;
+ $yytos->stateno = $yyNewState;
+ $yytos->major = $yyMajor;
+ $yytos->minor = $yypMinor;
+ array_push($this->yystack, $yytos);
+ if (self::$yyTraceFILE && $this->yyidx > 0) {
+ fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt,
+ $yyNewState);
+ fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt);
+ for($i = 1; $i <= $this->yyidx; $i++) {
+ fprintf(self::$yyTraceFILE, " %s",
+ self::$yyTokenName[$this->yystack[$i]->major]);
+ }
+ fwrite(self::$yyTraceFILE,"\n");
+ }
+ }
+
+ /**
+ * The following table contains information about every rule that
+ * is used during the reduce.
+ *
+ *
+ * array(
+ * array(
+ * int $lhs; Symbol on the left-hand side of the rule
+ * int $nrhs; Number of right-hand side symbols in the rule
+ * ),...
+ * );
+ *
+ */
+ static public $yyRuleInfo = array(
+ array( 'lhs' => 29, 'rhs' => 1 ),
+ array( 'lhs' => 30, 'rhs' => 3 ),
+ array( 'lhs' => 30, 'rhs' => 2 ),
+ array( 'lhs' => 30, 'rhs' => 2 ),
+ array( 'lhs' => 30, 'rhs' => 1 ),
+ array( 'lhs' => 30, 'rhs' => 3 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 1 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 31, 'rhs' => 2 ),
+ array( 'lhs' => 33, 'rhs' => 3 ),
+ array( 'lhs' => 33, 'rhs' => 4 ),
+ array( 'lhs' => 33, 'rhs' => 4 ),
+ array( 'lhs' => 33, 'rhs' => 5 ),
+ array( 'lhs' => 43, 'rhs' => 1 ),
+ array( 'lhs' => 43, 'rhs' => 1 ),
+ array( 'lhs' => 43, 'rhs' => 3 ),
+ array( 'lhs' => 43, 'rhs' => 3 ),
+ array( 'lhs' => 43, 'rhs' => 3 ),
+ array( 'lhs' => 43, 'rhs' => 1 ),
+ array( 'lhs' => 43, 'rhs' => 1 ),
+ array( 'lhs' => 43, 'rhs' => 2 ),
+ array( 'lhs' => 43, 'rhs' => 2 ),
+ array( 'lhs' => 43, 'rhs' => 2 ),
+ array( 'lhs' => 43, 'rhs' => 4 ),
+ array( 'lhs' => 43, 'rhs' => 4 ),
+ array( 'lhs' => 43, 'rhs' => 4 ),
+ array( 'lhs' => 43, 'rhs' => 4 ),
+ array( 'lhs' => 43, 'rhs' => 2 ),
+ array( 'lhs' => 43, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 1 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 1 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 1 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 1 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 1 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 1 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 3 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 3 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 3 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 3 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 3 ),
+ array( 'lhs' => 32, 'rhs' => 2 ),
+ array( 'lhs' => 32, 'rhs' => 3 ),
+ array( 'lhs' => 34, 'rhs' => 3 ),
+ array( 'lhs' => 34, 'rhs' => 5 ),
+ array( 'lhs' => 35, 'rhs' => 4 ),
+ array( 'lhs' => 35, 'rhs' => 5 ),
+ array( 'lhs' => 42, 'rhs' => 7 ),
+ array( 'lhs' => 42, 'rhs' => 6 ),
+ array( 'lhs' => 42, 'rhs' => 4 ),
+ array( 'lhs' => 42, 'rhs' => 5 ),
+ array( 'lhs' => 42, 'rhs' => 4 ),
+ array( 'lhs' => 42, 'rhs' => 5 ),
+ array( 'lhs' => 36, 'rhs' => 4 ),
+ array( 'lhs' => 36, 'rhs' => 4 ),
+ array( 'lhs' => 37, 'rhs' => 4 ),
+ array( 'lhs' => 37, 'rhs' => 4 ),
+ array( 'lhs' => 38, 'rhs' => 4 ),
+ array( 'lhs' => 38, 'rhs' => 5 ),
+ array( 'lhs' => 38, 'rhs' => 3 ),
+ array( 'lhs' => 38, 'rhs' => 4 ),
+ array( 'lhs' => 39, 'rhs' => 4 ),
+ array( 'lhs' => 40, 'rhs' => 3 ),
+ array( 'lhs' => 41, 'rhs' => 3 ),
+ );
+
+ /**
+ * The following table contains a mapping of reduce action to method name
+ * that handles the reduction.
+ *
+ * If a rule is not set, it has no handler.
+ */
+ static public $yyReduceMap = array(
+ 0 => 0,
+ 1 => 1,
+ 2 => 2,
+ 3 => 3,
+ 4 => 4,
+ 6 => 4,
+ 7 => 4,
+ 9 => 4,
+ 10 => 4,
+ 12 => 4,
+ 13 => 4,
+ 14 => 4,
+ 15 => 4,
+ 16 => 4,
+ 5 => 5,
+ 17 => 17,
+ 18 => 17,
+ 20 => 17,
+ 21 => 17,
+ 23 => 17,
+ 24 => 17,
+ 25 => 17,
+ 26 => 17,
+ 27 => 17,
+ 28 => 28,
+ 29 => 29,
+ 30 => 30,
+ 31 => 31,
+ 32 => 32,
+ 48 => 32,
+ 50 => 32,
+ 33 => 33,
+ 54 => 33,
+ 34 => 34,
+ 35 => 35,
+ 36 => 36,
+ 37 => 37,
+ 56 => 37,
+ 38 => 38,
+ 58 => 38,
+ 39 => 39,
+ 64 => 39,
+ 40 => 40,
+ 66 => 40,
+ 41 => 41,
+ 60 => 41,
+ 62 => 41,
+ 42 => 42,
+ 43 => 43,
+ 44 => 44,
+ 45 => 45,
+ 46 => 46,
+ 68 => 46,
+ 47 => 47,
+ 70 => 47,
+ 49 => 49,
+ 51 => 49,
+ 52 => 52,
+ 53 => 53,
+ 55 => 55,
+ 57 => 57,
+ 59 => 59,
+ 61 => 61,
+ 63 => 61,
+ 65 => 65,
+ 67 => 67,
+ 69 => 69,
+ 71 => 71,
+ 72 => 72,
+ 73 => 73,
+ 74 => 74,
+ 75 => 75,
+ 76 => 76,
+ 77 => 77,
+ 78 => 78,
+ 79 => 79,
+ 80 => 80,
+ 84 => 80,
+ 81 => 81,
+ 82 => 82,
+ 83 => 83,
+ 85 => 85,
+ 86 => 86,
+ 87 => 87,
+ 88 => 88,
+ 89 => 89,
+ 90 => 90,
+ 91 => 91,
+ 92 => 92,
+ );
+ /* Beginning here are the reduction cases. A typical example
+ ** follows:
+ ** #line
+ ** function yy_r0($yymsp){ ... } // User supplied code
+ ** #line
+ */
+#line 47 "Parser.y"
+ function yy_r0(){
+ $this->yystack[$this->yyidx + 0]->minor->string = str_replace('"', '\\"', $this->yystack[$this->yyidx + 0]->minor->string);
+ $x = $this->yystack[$this->yyidx + 0]->minor->metadata;
+ $x['subpatterns'] = $this->_subpatterns;
+ $this->yystack[$this->yyidx + 0]->minor->metadata = $x;
+ $this->_subpatterns = 0;
+ $this->result = $this->yystack[$this->yyidx + 0]->minor;
+ }
+#line 1259 "Parser.php"
+#line 56 "Parser.y"
+ function yy_r1(){
+ throw new PHP_LexerGenerator_Exception('Cannot include start match "' .
+ $this->yystack[$this->yyidx + -2]->minor . '" or end match "' . $this->yystack[$this->yyidx + 0]->minor . '"');
+ }
+#line 1265 "Parser.php"
+#line 60 "Parser.y"
+ function yy_r2(){
+ throw new PHP_LexerGenerator_Exception('Cannot include start match "' .
+ B . '"');
+ }
+#line 1271 "Parser.php"
+#line 64 "Parser.y"
+ function yy_r3(){
+ throw new PHP_LexerGenerator_Exception('Cannot include end match "' . $this->yystack[$this->yyidx + 0]->minor . '"');
+ }
+#line 1276 "Parser.php"
+#line 67 "Parser.y"
+ function yy_r4(){$this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; }
+#line 1279 "Parser.php"
+#line 68 "Parser.y"
+ function yy_r5(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -2]->minor->string . '|' . $this->yystack[$this->yyidx + 0]->minor->string, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor['pattern'] . '|' . $this->yystack[$this->yyidx + 0]->minor['pattern']));
+ }
+#line 1285 "Parser.php"
+#line 84 "Parser.y"
+ function yy_r17(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor->string . $this->yystack[$this->yyidx + 0]->minor->string, array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor['pattern'] . $this->yystack[$this->yyidx + 0]->minor['pattern']));
+ }
+#line 1291 "Parser.php"
+#line 123 "Parser.y"
+ function yy_r28(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('[' . $this->yystack[$this->yyidx + -1]->minor->string . ']', array(
+ 'pattern' => '[' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ']'));
+ }
+#line 1297 "Parser.php"
+#line 127 "Parser.y"
+ function yy_r29(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('[^' . $this->yystack[$this->yyidx + -1]->minor->string . ']', array(
+ 'pattern' => '[^' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ']'));
+ }
+#line 1303 "Parser.php"
+#line 131 "Parser.y"
+ function yy_r30(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('[' . $this->yystack[$this->yyidx + -2]->minor->string . ']' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => '[' . $this->yystack[$this->yyidx + -2]->minor['pattern'] . ']' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1309 "Parser.php"
+#line 135 "Parser.y"
+ function yy_r31(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('[^' . $this->yystack[$this->yyidx + -2]->minor->string . ']' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => '[^' . $this->yystack[$this->yyidx + -2]->minor['pattern'] . ']' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1315 "Parser.php"
+#line 140 "Parser.y"
+ function yy_r32(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1321 "Parser.php"
+#line 144 "Parser.y"
+ function yy_r33(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\\\' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1327 "Parser.php"
+#line 148 "Parser.y"
+ function yy_r34(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\\\' . $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1333 "Parser.php"
+#line 152 "Parser.y"
+ function yy_r35(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1339 "Parser.php"
+#line 156 "Parser.y"
+ function yy_r36(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -2]->minor . '-\\\\' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1345 "Parser.php"
+#line 160 "Parser.y"
+ function yy_r37(){
+ if (((int) substr($this->yystack[$this->yyidx + 0]->minor, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr($this->yystack[$this->yyidx + 0]->minor, 1));
+ }
+ $this->yystack[$this->yyidx + 0]->minor = substr($this->yystack[$this->yyidx + 0]->minor, 1);
+ // adjust back-reference for containing ()
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\\\' . ($this->yystack[$this->yyidx + 0]->minor + $this->_patternIndex), array(
+ 'pattern' => '\\' . ($this->_updatePattern ? ($this->yystack[$this->yyidx + 0]->minor + $this->_patternIndex) : $this->yystack[$this->yyidx + 0]->minor)));
+ }
+#line 1357 "Parser.php"
+#line 170 "Parser.y"
+ function yy_r38(){
+ if (((int) substr($this->yystack[$this->yyidx + 0]->minor, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception($this->yystack[$this->yyidx + 0]->minor . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr($this->yystack[$this->yyidx + 0]->minor, 1) . ' for octal');
+ }
+ $this->yystack[$this->yyidx + 0]->minor = substr($this->yystack[$this->yyidx + 0]->minor, 1);
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\\\' . ($this->yystack[$this->yyidx + 0]->minor + $this->_patternIndex), array(
+ 'pattern' => '\\' . ($this->_updatePattern ? ($this->yystack[$this->yyidx + 0]->minor + $this->_patternIndex) : $this->yystack[$this->yyidx + 0]->minor)));
+ }
+#line 1368 "Parser.php"
+#line 179 "Parser.y"
+ function yy_r39(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor->string . '\\' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor['pattern'] . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1374 "Parser.php"
+#line 183 "Parser.y"
+ function yy_r40(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor->string . '\\\\' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor['pattern'] . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1380 "Parser.php"
+#line 187 "Parser.y"
+ function yy_r41(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor->string . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor['pattern'] . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1386 "Parser.php"
+#line 191 "Parser.y"
+ function yy_r42(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -3]->minor->string . '\\\\' . $this->yystack[$this->yyidx + -2]->minor . '-\\' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -3]->minor['pattern'] . $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1392 "Parser.php"
+#line 195 "Parser.y"
+ function yy_r43(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -3]->minor->string . '\\\\' . $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -3]->minor['pattern'] . $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1398 "Parser.php"
+#line 199 "Parser.y"
+ function yy_r44(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -3]->minor->string . $this->yystack[$this->yyidx + -2]->minor . '-\\\\' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -3]->minor['pattern'] . $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1404 "Parser.php"
+#line 203 "Parser.y"
+ function yy_r45(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -3]->minor->string . $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -3]->minor['pattern'] . $this->yystack[$this->yyidx + -2]->minor . '-' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1410 "Parser.php"
+#line 207 "Parser.y"
+ function yy_r46(){
+ if (((int) substr($this->yystack[$this->yyidx + 0]->minor, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr($this->yystack[$this->yyidx + 0]->minor, 1));
+ }
+ $this->yystack[$this->yyidx + 0]->minor = substr($this->yystack[$this->yyidx + 0]->minor, 1);
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor->string . '\\\\' . ($this->yystack[$this->yyidx + 0]->minor + $this->_patternIndex), array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor['pattern'] . '\\' . ($this->_updatePattern ? ($this->yystack[$this->yyidx + 0]->minor + $this->_patternIndex) : $this->yystack[$this->yyidx + 0]->minor)));
+ }
+#line 1421 "Parser.php"
+#line 216 "Parser.y"
+ function yy_r47(){
+ if (((int) substr($this->yystack[$this->yyidx + 0]->minor, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception($this->yystack[$this->yyidx + 0]->minor . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr($this->yystack[$this->yyidx + 0]->minor, 1) . ' for octal');
+ }
+ $this->yystack[$this->yyidx + 0]->minor = substr($this->yystack[$this->yyidx + 0]->minor, 1);
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor->string . '\\\\' . ($this->yystack[$this->yyidx + 0]->minor + $this->_patternIndex), array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor['pattern'] . '\\' . ($this->_updatePattern ? ($this->yystack[$this->yyidx + 0]->minor + $this->_patternIndex) : $this->yystack[$this->yyidx + 0]->minor)));
+ }
+#line 1432 "Parser.php"
+#line 230 "Parser.y"
+ function yy_r49(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1438 "Parser.php"
+#line 242 "Parser.y"
+ function yy_r52(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1444 "Parser.php"
+#line 246 "Parser.y"
+ function yy_r53(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\' . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1450 "Parser.php"
+#line 254 "Parser.y"
+ function yy_r55(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\\\' . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1456 "Parser.php"
+#line 268 "Parser.y"
+ function yy_r57(){
+ if (((int) substr($this->yystack[$this->yyidx + -1]->minor, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr($this->yystack[$this->yyidx + -1]->minor, 1));
+ }
+ $this->yystack[$this->yyidx + -1]->minor = substr($this->yystack[$this->yyidx + -1]->minor, 1);
+ // adjust back-reference for containing ()
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\\\' . ($this->yystack[$this->yyidx + -1]->minor + $this->_patternIndex) . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => '\\' . ($this->_updatePattern ? ($this->yystack[$this->yyidx + -1]->minor + $this->_patternIndex) : $this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1468 "Parser.php"
+#line 287 "Parser.y"
+ function yy_r59(){
+ if (((int) substr($this->yystack[$this->yyidx + -1]->minor, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception($this->yystack[$this->yyidx + -1]->minor . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr($this->yystack[$this->yyidx + -1]->minor, 1) . ' for octal');
+ }
+ $this->yystack[$this->yyidx + -1]->minor = substr($this->yystack[$this->yyidx + -1]->minor, 1);
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('\\\\' . ($this->yystack[$this->yyidx + -1]->minor + $this->_patternIndex) . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => '\\' . ($this->_updatePattern ? ($this->yystack[$this->yyidx + -1]->minor + $this->_patternIndex) : $this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1479 "Parser.php"
+#line 300 "Parser.y"
+ function yy_r61(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -2]->minor->string . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor['pattern'] . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1485 "Parser.php"
+#line 316 "Parser.y"
+ function yy_r65(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -2]->minor->string . '\\' . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor['pattern'] . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1491 "Parser.php"
+#line 324 "Parser.y"
+ function yy_r67(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -2]->minor->string . '\\\\' . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor['pattern'] . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1497 "Parser.php"
+#line 337 "Parser.y"
+ function yy_r69(){
+ if (((int) substr($this->yystack[$this->yyidx + -1]->minor, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr($this->yystack[$this->yyidx + -1]->minor, 1));
+ }
+ $this->yystack[$this->yyidx + -1]->minor = substr($this->yystack[$this->yyidx + -1]->minor, 1);
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -2]->minor->string . '\\\\' . ($this->yystack[$this->yyidx + -1]->minor + $this->_patternIndex) . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor['pattern'] . '\\' . ($this->_updatePattern ? ($this->yystack[$this->yyidx + -1]->minor + $this->_patternIndex) : $this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1508 "Parser.php"
+#line 355 "Parser.y"
+ function yy_r71(){
+ if (((int) substr($this->yystack[$this->yyidx + -1]->minor, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception($this->yystack[$this->yyidx + -1]->minor . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr($this->yystack[$this->yyidx + -1]->minor, 1) . ' for octal');
+ }
+ $this->yystack[$this->yyidx + -1]->minor = substr($this->yystack[$this->yyidx + -1]->minor, 1);
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken($this->yystack[$this->yyidx + -2]->minor->string . '\\\\' . ($this->yystack[$this->yyidx + -1]->minor + $this->_patternIndex) . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => $this->yystack[$this->yyidx + -2]->minor['pattern'] . '\\' . ($this->_updatePattern ? ($this->yystack[$this->yyidx + -1]->minor + $this->_patternIndex) : $this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1519 "Parser.php"
+#line 365 "Parser.y"
+ function yy_r72(){
+ throw new PHP_LexerGenerator_Exception('Error: cannot set preg options directly with "' .
+ $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor . '"');
+ }
+#line 1525 "Parser.php"
+#line 369 "Parser.y"
+ function yy_r73(){
+ throw new PHP_LexerGenerator_Exception('Error: cannot set preg options directly with "' .
+ $this->yystack[$this->yyidx + -4]->minor . $this->yystack[$this->yyidx + -3]->minor . $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + -1]->minor['pattern'] . $this->yystack[$this->yyidx + 0]->minor . '"');
+ }
+#line 1531 "Parser.php"
+#line 374 "Parser.y"
+ function yy_r74(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?:' . $this->yystack[$this->yyidx + -1]->minor->string . ')', array(
+ 'pattern' => '(?:' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')'));
+ }
+#line 1537 "Parser.php"
+#line 378 "Parser.y"
+ function yy_r75(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?:' . $this->yystack[$this->yyidx + -2]->minor->string . ')' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => '(?:' . $this->yystack[$this->yyidx + -2]->minor['pattern'] . ')' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1543 "Parser.php"
+#line 383 "Parser.y"
+ function yy_r76(){
+ if ($this->yystack[$this->yyidx + -4]->minor != 'R') {
+ if (!preg_match('/[1-9][0-9]*/', $this->yystack[$this->yyidx + -4]->minor)) {
+ throw new PHP_LexerGenerator_Exception('Invalid sub-pattern conditional: "(?(' . $this->yystack[$this->yyidx + -4]->minor . ')"');
+ }
+ if ($this->yystack[$this->yyidx + -4]->minor > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('sub-pattern conditional . "' . $this->yystack[$this->yyidx + -4]->minor . '" refers to non-existent sub-pattern');
+ }
+ } else {
+ throw new PHP_LexerGenerator_Exception('Recursive conditional (?(' . $this->yystack[$this->yyidx + -4]->minor . ')" cannot work in this lexer');
+ }
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?(' . $this->yystack[$this->yyidx + -4]->minor . ')' . $this->yystack[$this->yyidx + -2]->minor->string . ')' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => '(?(' . $this->yystack[$this->yyidx + -4]->minor . ')' . $this->yystack[$this->yyidx + -2]->minor['pattern'] . ')' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1559 "Parser.php"
+#line 397 "Parser.y"
+ function yy_r77(){
+ if ($this->yystack[$this->yyidx + -3]->minor != 'R') {
+ if (!preg_match('/[1-9][0-9]*/', $this->yystack[$this->yyidx + -3]->minor)) {
+ throw new PHP_LexerGenerator_Exception('Invalid sub-pattern conditional: "(?(' . $this->yystack[$this->yyidx + -3]->minor . ')"');
+ }
+ if ($this->yystack[$this->yyidx + -3]->minor > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('sub-pattern conditional . "' . $this->yystack[$this->yyidx + -3]->minor . '" refers to non-existent sub-pattern');
+ }
+ } else {
+ throw new PHP_LexerGenerator_Exception('Recursive conditional (?(' . $this->yystack[$this->yyidx + -3]->minor . ')" cannot work in this lexer');
+ }
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?(' . $this->yystack[$this->yyidx + -3]->minor . ')' . $this->yystack[$this->yyidx + -1]->minor->string . ')', array(
+ 'pattern' => '(?(' . $this->yystack[$this->yyidx + -3]->minor . ')' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')'));
+ }
+#line 1575 "Parser.php"
+#line 411 "Parser.y"
+ function yy_r78(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?' . $this->yystack[$this->yyidx + -2]->minor->string . $this->yystack[$this->yyidx + -1]->minor->string . ')', array(
+ 'pattern' => '(?' . $this->yystack[$this->yyidx + -2]->minor['pattern'] . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')'));
+ }
+#line 1581 "Parser.php"
+#line 415 "Parser.y"
+ function yy_r79(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?' . $this->yystack[$this->yyidx + -3]->minor->string . $this->yystack[$this->yyidx + -2]->minor->string . ')' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => '(?' . $this->yystack[$this->yyidx + -3]->minor['pattern'] . $this->yystack[$this->yyidx + -2]->minor['pattern'] . ')' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1587 "Parser.php"
+#line 419 "Parser.y"
+ function yy_r80(){
+ throw new PHP_LexerGenerator_Exception('Look-behind assertions cannot be used: "(?<=' .
+ $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')');
+ }
+#line 1593 "Parser.php"
+#line 423 "Parser.y"
+ function yy_r81(){
+ throw new PHP_LexerGenerator_Exception('Look-behind assertions cannot be used: "(?<=' .
+ $this->yystack[$this->yyidx + -2]->minor['pattern'] . ')');
+ }
+#line 1599 "Parser.php"
+#line 428 "Parser.y"
+ function yy_r82(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?=' . $this->yystack[$this->yyidx + -1]->minor->string . ')', array(
+ 'pattern '=> '(?=' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')'));
+ }
+#line 1605 "Parser.php"
+#line 432 "Parser.y"
+ function yy_r83(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?!' . $this->yystack[$this->yyidx + -1]->minor->string . ')', array(
+ 'pattern' => '(?!' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')'));
+ }
+#line 1611 "Parser.php"
+#line 441 "Parser.y"
+ function yy_r85(){
+ throw new PHP_LexerGenerator_Exception('Look-behind assertions cannot be used: "(?yystack[$this->yyidx + -1]->minor['pattern'] . ')');
+ }
+#line 1617 "Parser.php"
+#line 446 "Parser.y"
+ function yy_r86(){
+ throw new PHP_LexerGenerator_Exception('Cannot use named sub-patterns: "(' .
+ $this->yystack[$this->yyidx + -2]->minor['pattern'] . ')');
+ }
+#line 1623 "Parser.php"
+#line 450 "Parser.y"
+ function yy_r87(){
+ throw new PHP_LexerGenerator_Exception('Cannot use named sub-patterns: "(' .
+ $this->yystack[$this->yyidx + -3]->minor['pattern'] . ')');
+ }
+#line 1629 "Parser.php"
+#line 454 "Parser.y"
+ function yy_r88(){
+ $this->_subpatterns++;
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(' . $this->yystack[$this->yyidx + -1]->minor->string . ')', array(
+ 'pattern' => '(' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')'));
+ }
+#line 1636 "Parser.php"
+#line 459 "Parser.y"
+ function yy_r89(){
+ $this->_subpatterns++;
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(' . $this->yystack[$this->yyidx + -2]->minor->string . ')' . $this->yystack[$this->yyidx + 0]->minor, array(
+ 'pattern' => '(' . $this->yystack[$this->yyidx + -2]->minor['pattern'] . ')' . $this->yystack[$this->yyidx + 0]->minor));
+ }
+#line 1643 "Parser.php"
+#line 465 "Parser.y"
+ function yy_r90(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(?>' . $this->yystack[$this->yyidx + -1]->minor->string . ')', array(
+ 'pattern' => '(?>' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')'));
+ }
+#line 1649 "Parser.php"
+#line 470 "Parser.y"
+ function yy_r91(){
+ $this->_retvalue = new PHP_LexerGenerator_ParseryyToken('(' . $this->yystack[$this->yyidx + -1]->minor->string . ')', array(
+ 'pattern' => '(' . $this->yystack[$this->yyidx + -1]->minor['pattern'] . ')'));
+ }
+#line 1655 "Parser.php"
+#line 475 "Parser.y"
+ function yy_r92(){
+ throw new Exception('(?R) cannot work in this lexer');
+ }
+#line 1660 "Parser.php"
+
+ /**
+ * placeholder for the left hand side in a reduce operation.
+ *
+ * For a parser with a rule like this:
+ *
+ * rule(A) ::= B. { A = 1; }
+ *
+ *
+ * The parser will translate to something like:
+ *
+ *
+ * function yy_r0(){$this->_retvalue = 1;}
+ *
+ */
+ private $_retvalue;
+
+ /**
+ * Perform a reduce action and the shift that must immediately
+ * follow the reduce.
+ *
+ * For a rule such as:
+ *
+ *
+ * A ::= B blah C. { dosomething(); }
+ *
+ *
+ * This function will first call the action, if any, ("dosomething();" in our
+ * example), and then it will pop three states from the stack,
+ * one for each entry on the right-hand side of the expression
+ * (B, blah, and C in our example rule), and then push the result of the action
+ * back on to the stack with the resulting state reduced to (as described in the .out
+ * file)
+ * @param int Number of the rule by which to reduce
+ */
+ function yy_reduce($yyruleno)
+ {
+ //int $yygoto; /* The next state */
+ //int $yyact; /* The next action */
+ //mixed $yygotominor; /* The LHS of the rule reduced */
+ //PHP_LexerGenerator_Regex_yyStackEntry $yymsp; /* The top of the parser's stack */
+ //int $yysize; /* Amount to pop the stack */
+ $yymsp = $this->yystack[$this->yyidx];
+ if (self::$yyTraceFILE && $yyruleno >= 0
+ && $yyruleno < count(self::$yyRuleName)) {
+ fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n",
+ self::$yyTracePrompt, $yyruleno,
+ self::$yyRuleName[$yyruleno]);
+ }
+
+ $this->_retvalue = $yy_lefthand_side = null;
+ if (array_key_exists($yyruleno, self::$yyReduceMap)) {
+ // call the action
+ $this->_retvalue = null;
+ $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}();
+ $yy_lefthand_side = $this->_retvalue;
+ }
+ $yygoto = self::$yyRuleInfo[$yyruleno]['lhs'];
+ $yysize = self::$yyRuleInfo[$yyruleno]['rhs'];
+ $this->yyidx -= $yysize;
+ for($i = $yysize; $i; $i--) {
+ // pop all of the right-hand side parameters
+ array_pop($this->yystack);
+ }
+ $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto);
+ if ($yyact < self::YYNSTATE) {
+ /* If we are not debugging and the reduce action popped at least
+ ** one element off the stack, then we can push the new element back
+ ** onto the stack here, and skip the stack overflow test in yy_shift().
+ ** That gives a significant speed improvement. */
+ if (!self::$yyTraceFILE && $yysize) {
+ $this->yyidx++;
+ $x = new PHP_LexerGenerator_Regex_yyStackEntry;
+ $x->stateno = $yyact;
+ $x->major = $yygoto;
+ $x->minor = $yy_lefthand_side;
+ $this->yystack[$this->yyidx] = $x;
+ } else {
+ $this->yy_shift($yyact, $yygoto, $yy_lefthand_side);
+ }
+ } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yy_accept();
+ }
+ }
+
+ /**
+ * The following code executes when the parse fails
+ *
+ * Code from %parse_fail is inserted here
+ */
+ function yy_parse_failed()
+ {
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+ }
+
+ /**
+ * The following code executes when a syntax error first occurs.
+ *
+ * %syntax_error code is inserted here
+ * @param int The major type of the error token
+ * @param mixed The minor type of the error token
+ */
+ function yy_syntax_error($yymajor, $TOKEN)
+ {
+#line 6 "Parser.y"
+
+/* ?>_lex->line . ": token '" .
+ $this->_lex->value . "' while parsing rule:";
+ foreach ($this->yystack as $entry) {
+ echo $this->tokenName($entry->major) . ' ';
+ }
+ foreach ($this->yy_get_expected_tokens($yymajor) as $token) {
+ $expect[] = self::$yyTokenName[$token];
+ }
+ throw new Exception('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN
+ . '), expected one of: ' . implode(',', $expect));
+#line 1788 "Parser.php"
+ }
+
+ /**
+ * The following is executed when the parser accepts
+ *
+ * %parse_accept code is inserted here
+ */
+ function yy_accept()
+ {
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $stack = $this->yy_pop_parser_stack();
+ }
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+ }
+
+ /**
+ * The main parser program.
+ *
+ * The first argument is the major token number. The second is
+ * the token value string as scanned from the input.
+ *
+ * @param int the token number
+ * @param mixed the token value
+ * @param mixed any extra arguments that should be passed to handlers
+ */
+ function doParse($yymajor, $yytokenvalue)
+ {
+// $yyact; /* The parser action. */
+// $yyendofinput; /* True if we are at the end of input */
+ $yyerrorhit = 0; /* True if yymajor has invoked an error */
+
+ /* (re)initialize the parser, if necessary */
+ if ($this->yyidx === null || $this->yyidx < 0) {
+ /* if ($yymajor == 0) return; // not sure why this was here... */
+ $this->yyidx = 0;
+ $this->yyerrcnt = -1;
+ $x = new PHP_LexerGenerator_Regex_yyStackEntry;
+ $x->stateno = 0;
+ $x->major = 0;
+ $this->yystack = array();
+ array_push($this->yystack, $x);
+ }
+ $yyendofinput = ($yymajor==0);
+
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sInput %s\n",
+ self::$yyTracePrompt, self::$yyTokenName[$yymajor]);
+ }
+
+ do {
+ $yyact = $this->yy_find_shift_action($yymajor);
+ if ($yymajor < self::YYERRORSYMBOL &&
+ !$this->yy_is_expected_token($yymajor)) {
+ // force a syntax error
+ $yyact = self::YY_ERROR_ACTION;
+ }
+ if ($yyact < self::YYNSTATE) {
+ $this->yy_shift($yyact, $yymajor, $yytokenvalue);
+ $this->yyerrcnt--;
+ if ($yyendofinput && $this->yyidx >= 0) {
+ $yymajor = 0;
+ } else {
+ $yymajor = self::YYNOCODE;
+ }
+ } elseif ($yyact < self::YYNSTATE + self::YYNRULE) {
+ $this->yy_reduce($yyact - self::YYNSTATE);
+ } elseif ($yyact == self::YY_ERROR_ACTION) {
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sSyntax Error!\n",
+ self::$yyTracePrompt);
+ }
+ if (self::YYERRORSYMBOL) {
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
+ ** grammar defines an error token "ERROR".
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if ($this->yyerrcnt < 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $yymx = $this->yystack[$this->yyidx]->major;
+ if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){
+ if (self::$yyTraceFILE) {
+ fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n",
+ self::$yyTracePrompt, self::$yyTokenName[$yymajor]);
+ }
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $yymajor = self::YYNOCODE;
+ } else {
+ while ($this->yyidx >= 0 &&
+ $yymx != self::YYERRORSYMBOL &&
+ ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE
+ ){
+ $this->yy_pop_parser_stack();
+ }
+ if ($this->yyidx < 0 || $yymajor==0) {
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $this->yy_parse_failed();
+ $yymajor = self::YYNOCODE;
+ } elseif ($yymx != self::YYERRORSYMBOL) {
+ $u2 = 0;
+ $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2);
+ }
+ }
+ $this->yyerrcnt = 3;
+ $yyerrorhit = 1;
+ } else {
+ /* YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if ($this->yyerrcnt <= 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $this->yyerrcnt = 3;
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ if ($yyendofinput) {
+ $this->yy_parse_failed();
+ }
+ $yymajor = self::YYNOCODE;
+ }
+ } else {
+ $this->yy_accept();
+ $yymajor = self::YYNOCODE;
+ }
+ } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
+ }
+}
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/Regex/Parser.y b/core/oql/build/PHP/LexerGenerator/Regex/Parser.y
new file mode 100644
index 000000000..bb74738dd
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/Regex/Parser.y
@@ -0,0 +1,477 @@
+%name PHP_LexerGenerator_Regex_
+%include {
+require_once 'PHP/LexerGenerator/Exception.php';
+}
+%declare_class {class PHP_LexerGenerator_Regex_Parser}
+%syntax_error {
+/* ?>_lex->line . ": token '" .
+ $this->_lex->value . "' while parsing rule:";
+ foreach ($this->yystack as $entry) {
+ echo $this->tokenName($entry->major) . ' ';
+ }
+ foreach ($this->yy_get_expected_tokens($yymajor) as $token) {
+ $expect[] = self::$yyTokenName[$token];
+ }
+ throw new Exception('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN
+ . '), expected one of: ' . implode(',', $expect));
+}
+%include_class {
+ private $_lex;
+ private $_subpatterns;
+ private $_updatePattern;
+ private $_patternIndex;
+ public $result;
+ function __construct($lex)
+ {
+ $this->result = new PHP_LexerGenerator_ParseryyToken('');
+ $this->_lex = $lex;
+ $this->_subpatterns = 0;
+ $this->_patternIndex = 1;
+ }
+
+ function reset($patternIndex, $updatePattern = false)
+ {
+ $this->_updatePattern = $updatePattern;
+ $this->_patternIndex = $patternIndex;
+ $this->_subpatterns = 0;
+ $this->result = new PHP_LexerGenerator_ParseryyToken('');
+ }
+}
+
+%left OPENPAREN OPENASSERTION BAR.
+%right MULTIPLIER.
+
+start ::= pattern(B). {
+ B->string = str_replace('"', '\\"', B->string);
+ $x = B->metadata;
+ $x['subpatterns'] = $this->_subpatterns;
+ B->metadata = $x;
+ $this->_subpatterns = 0;
+ $this->result = B;
+}
+
+pattern ::= MATCHSTART(B) basic_pattern MATCHEND(C). {
+ throw new PHP_LexerGenerator_Exception('Cannot include start match "' .
+ B . '" or end match "' . C . '"');
+}
+pattern ::= MATCHSTART basic_pattern. {
+ throw new PHP_LexerGenerator_Exception('Cannot include start match "' .
+ B . '"');
+}
+pattern ::= basic_pattern MATCHEND(C). {
+ throw new PHP_LexerGenerator_Exception('Cannot include end match "' . C . '"');
+}
+pattern(A) ::= basic_pattern(B). {A = B;}
+pattern(A) ::= pattern(B) BAR pattern(C). {
+ A = new PHP_LexerGenerator_ParseryyToken(B->string . '|' . C->string, array(
+ 'pattern' => B['pattern'] . '|' . C['pattern']));
+}
+
+basic_pattern(A) ::= basic_text(B). {A = B;}
+basic_pattern(A) ::= character_class(B). {A = B;}
+basic_pattern ::= assertion.
+basic_pattern(A) ::= grouping(B). {A = B;}
+basic_pattern(A) ::= lookahead(B). {A = B;}
+basic_pattern ::= lookbehind.
+basic_pattern(A) ::= subpattern(B). {A = B;}
+basic_pattern(A) ::= onceonly(B). {A = B;}
+basic_pattern(A) ::= comment(B). {A = B;}
+basic_pattern(A) ::= recur(B). {A = B;}
+basic_pattern(A) ::= conditional(B). {A = B;}
+basic_pattern(A) ::= basic_pattern(P) basic_text(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+basic_pattern(A) ::= basic_pattern(P) character_class(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+basic_pattern ::= basic_pattern assertion.
+basic_pattern(A) ::= basic_pattern(P) grouping(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+basic_pattern(A) ::= basic_pattern(P) lookahead(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+basic_pattern ::= basic_pattern lookbehind.
+basic_pattern(A) ::= basic_pattern(P) subpattern(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+basic_pattern(A) ::= basic_pattern(P) onceonly(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+basic_pattern(A) ::= basic_pattern(P) comment(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+basic_pattern(A) ::= basic_pattern(P) recur(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+basic_pattern(A) ::= basic_pattern(P) conditional(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . B->string, array(
+ 'pattern' => P['pattern'] . B['pattern']));
+}
+
+character_class(A) ::= OPENCHARCLASS character_class_contents(B) CLOSECHARCLASS. {
+ A = new PHP_LexerGenerator_ParseryyToken('[' . B->string . ']', array(
+ 'pattern' => '[' . B['pattern'] . ']'));
+}
+character_class(A) ::= OPENCHARCLASS NEGATE character_class_contents(B) CLOSECHARCLASS. {
+ A = new PHP_LexerGenerator_ParseryyToken('[^' . B->string . ']', array(
+ 'pattern' => '[^' . B['pattern'] . ']'));
+}
+character_class(A) ::= OPENCHARCLASS character_class_contents(B) CLOSECHARCLASS MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken('[' . B->string . ']' . M, array(
+ 'pattern' => '[' . B['pattern'] . ']' . M));
+}
+character_class(A) ::= OPENCHARCLASS NEGATE character_class_contents(B) CLOSECHARCLASS MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken('[^' . B->string . ']' . M, array(
+ 'pattern' => '[^' . B['pattern'] . ']' . M));
+}
+
+character_class_contents(A) ::= TEXT(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(B, array(
+ 'pattern' => B));
+}
+character_class_contents(A) ::= ESCAPEDBACKSLASH(B). {
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . B, array(
+ 'pattern' => B));
+}
+character_class_contents(A) ::= ESCAPEDBACKSLASH(B) HYPHEN TEXT(C). {
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . B . '-' . C, array(
+ 'pattern' => B . '-' . C));
+}
+character_class_contents(A) ::= TEXT(B) HYPHEN TEXT(C). {
+ A = new PHP_LexerGenerator_ParseryyToken(B . '-' . C, array(
+ 'pattern' => B . '-' . C));
+}
+character_class_contents(A) ::= TEXT(B) HYPHEN ESCAPEDBACKSLASH(C). {
+ A = new PHP_LexerGenerator_ParseryyToken(B . '-\\\\' . C, array(
+ 'pattern' => B . '-' . C));
+}
+character_class_contents(A) ::= BACKREFERENCE(B). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr(B, 1));
+ }
+ B = substr(B, 1);
+ // adjust back-reference for containing ()
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . (B + $this->_patternIndex), array(
+ 'pattern' => '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B)));
+}
+character_class_contents(A) ::= COULDBEBACKREF(B). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception(B . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr(B, 1) . ' for octal');
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . (B + $this->_patternIndex), array(
+ 'pattern' => '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B)));
+}
+character_class_contents(A) ::= character_class_contents(D) CONTROLCHAR(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(D->string . '\\' . B, array(
+ 'pattern' => D['pattern'] . B));
+}
+character_class_contents(A) ::= character_class_contents(D) ESCAPEDBACKSLASH(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(D->string . '\\\\' . B, array(
+ 'pattern' => D['pattern'] . B));
+}
+character_class_contents(A) ::= character_class_contents(D) TEXT(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(D->string . B, array(
+ 'pattern' => D['pattern'] . B));
+}
+character_class_contents(A) ::= character_class_contents(D) ESCAPEDBACKSLASH(B) HYPHEN CONTROLCHAR(C). {
+ A = new PHP_LexerGenerator_ParseryyToken(D->string . '\\\\' . B . '-\\' . C, array(
+ 'pattern' => D['pattern'] . B . '-' . C));
+}
+character_class_contents(A) ::= character_class_contents(D) ESCAPEDBACKSLASH(B) HYPHEN TEXT(C). {
+ A = new PHP_LexerGenerator_ParseryyToken(D->string . '\\\\' . B . '-' . C, array(
+ 'pattern' => D['pattern'] . B . '-' . C));
+}
+character_class_contents(A) ::= character_class_contents(D) TEXT(B) HYPHEN ESCAPEDBACKSLASH(C). {
+ A = new PHP_LexerGenerator_ParseryyToken(D->string . B . '-\\\\' . C, array(
+ 'pattern' => D['pattern'] . B . '-' . C));
+}
+character_class_contents(A) ::= character_class_contents(D) TEXT(B) HYPHEN TEXT(C). {
+ A = new PHP_LexerGenerator_ParseryyToken(D->string . B . '-' . C, array(
+ 'pattern' => D['pattern'] . B . '-' . C));
+}
+character_class_contents(A) ::= character_class_contents(P) BACKREFERENCE(B). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr(B, 1));
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . '\\\\' . (B + $this->_patternIndex), array(
+ 'pattern' => P['pattern'] . '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B)));
+}
+character_class_contents(A) ::= character_class_contents(P) COULDBEBACKREF(B). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception(B . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr(B, 1) . ' for octal');
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . '\\\\' . (B + $this->_patternIndex), array(
+ 'pattern' => P['pattern'] . '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B)));
+}
+
+basic_text(A) ::= TEXT(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(B, array(
+ 'pattern' => B));
+}
+basic_text(A) ::= TEXT(B) MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken(B . M, array(
+ 'pattern' => B . M));
+}
+basic_text(A) ::= FULLSTOP(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(B, array(
+ 'pattern' => B));
+}
+basic_text(A) ::= FULLSTOP(B) MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken(B . M, array(
+ 'pattern' => B . M));
+}
+basic_text(A) ::= CONTROLCHAR(B). {
+ A = new PHP_LexerGenerator_ParseryyToken('\\' . B, array(
+ 'pattern' => B));
+}
+basic_text(A) ::= CONTROLCHAR(B) MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken('\\' . B . M, array(
+ 'pattern' => B . M));
+}
+basic_text(A) ::= ESCAPEDBACKSLASH(B). {
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . B, array(
+ 'pattern' => B));
+}
+basic_text(A) ::= ESCAPEDBACKSLASH(B) MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . B . M, array(
+ 'pattern' => B . M));
+}
+basic_text(A) ::= BACKREFERENCE(B). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr(B, 1));
+ }
+ B = substr(B, 1);
+ // adjust back-reference for containing ()
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . (B + $this->_patternIndex), array(
+ 'pattern' => '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B)));
+}
+basic_text(A) ::= BACKREFERENCE(B) MULTIPLIER(M). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr(B, 1));
+ }
+ B = substr(B, 1);
+ // adjust back-reference for containing ()
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . (B + $this->_patternIndex) . M, array(
+ 'pattern' => '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B) . M));
+}
+basic_text(A) ::= COULDBEBACKREF(B). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception(B . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr(B, 1) . ' for octal');
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . (B + $this->_patternIndex), array(
+ 'pattern' => '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B)));
+}
+basic_text(A) ::= COULDBEBACKREF(B) MULTIPLIER(M). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception(B . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr(B, 1) . ' for octal');
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken('\\\\' . (B + $this->_patternIndex) . M, array(
+ 'pattern' => '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B) . M));
+}
+basic_text(A) ::= basic_text(T) TEXT(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(T->string . B, array(
+ 'pattern' => T['pattern'] . B));
+}
+basic_text(A) ::= basic_text(T) TEXT(B) MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken(T->string . B . M, array(
+ 'pattern' => T['pattern'] . B . M));
+}
+basic_text(A) ::= basic_text(T) FULLSTOP(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(T->string . B, array(
+ 'pattern' => T['pattern'] . B));
+}
+basic_text(A) ::= basic_text(T) FULLSTOP(B) MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken(T->string . B . M, array(
+ 'pattern' => T['pattern'] . B . M));
+}
+basic_text(A) ::= basic_text(T) CONTROLCHAR(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(T->string . '\\' . B, array(
+ 'pattern' => T['pattern'] . B));
+}
+basic_text(A) ::= basic_text(T) CONTROLCHAR(B) MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken(T->string . '\\' . B . M, array(
+ 'pattern' => T['pattern'] . B . M));
+}
+basic_text(A) ::= basic_text(T) ESCAPEDBACKSLASH(B). {
+ A = new PHP_LexerGenerator_ParseryyToken(T->string . '\\\\' . B, array(
+ 'pattern' => T['pattern'] . B));
+}
+basic_text(A) ::= basic_text(T) ESCAPEDBACKSLASH(B) MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken(T->string . '\\\\' . B . M, array(
+ 'pattern' => T['pattern'] . B . M));
+}
+basic_text(A) ::= basic_text(P) BACKREFERENCE(B). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr(B, 1));
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . '\\\\' . (B + $this->_patternIndex), array(
+ 'pattern' => P['pattern'] . '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B)));
+}
+basic_text(A) ::= basic_text(P) BACKREFERENCE(B) MULTIPLIER(M). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('Back-reference refers to non-existent ' .
+ 'sub-pattern ' . substr(B, 1));
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . '\\\\' . (B + $this->_patternIndex) . M, array(
+ 'pattern' => P['pattern'] . '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B) . M));
+}
+basic_text(A) ::= basic_text(P) COULDBEBACKREF(B). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception(B . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr(B, 1) . ' for octal');
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . '\\\\' . (B + $this->_patternIndex), array(
+ 'pattern' => P['pattern'] . '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B)));
+}
+basic_text(A) ::= basic_text(P) COULDBEBACKREF(B) MULTIPLIER(M). {
+ if (((int) substr(B, 1)) > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception(B . ' will be interpreted as an invalid' .
+ ' back-reference, use "\\0' . substr(B, 1) . ' for octal');
+ }
+ B = substr(B, 1);
+ A = new PHP_LexerGenerator_ParseryyToken(P->string . '\\\\' . (B + $this->_patternIndex) . M, array(
+ 'pattern' => P['pattern'] . '\\' . ($this->_updatePattern ? (B + $this->_patternIndex) : B) . M));
+}
+
+assertion ::= OPENASSERTION(B) INTERNALOPTIONS(C) CLOSEPAREN(D). {
+ throw new PHP_LexerGenerator_Exception('Error: cannot set preg options directly with "' .
+ B . C . D . '"');
+}
+assertion ::= OPENASSERTION(B) INTERNALOPTIONS(C) COLON(D) pattern(E) CLOSEPAREN(F). {
+ throw new PHP_LexerGenerator_Exception('Error: cannot set preg options directly with "' .
+ B . C . D . E['pattern'] . F . '"');
+}
+
+grouping(A) ::= OPENASSERTION COLON pattern(B) CLOSEPAREN. {
+ A = new PHP_LexerGenerator_ParseryyToken('(?:' . B->string . ')', array(
+ 'pattern' => '(?:' . B['pattern'] . ')'));
+}
+grouping(A) ::= OPENASSERTION COLON pattern(B) CLOSEPAREN MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken('(?:' . B->string . ')' . M, array(
+ 'pattern' => '(?:' . B['pattern'] . ')' . M));
+}
+
+conditional(A) ::= OPENASSERTION OPENPAREN TEXT(T) CLOSEPAREN pattern(B) CLOSEPAREN MULTIPLIER(M). {
+ if (T != 'R') {
+ if (!preg_match('/[1-9][0-9]*/', T)) {
+ throw new PHP_LexerGenerator_Exception('Invalid sub-pattern conditional: "(?(' . T . ')"');
+ }
+ if (T > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('sub-pattern conditional . "' . T . '" refers to non-existent sub-pattern');
+ }
+ } else {
+ throw new PHP_LexerGenerator_Exception('Recursive conditional (?(' . T . ')" cannot work in this lexer');
+ }
+ A = new PHP_LexerGenerator_ParseryyToken('(?(' . T . ')' . B->string . ')' . M, array(
+ 'pattern' => '(?(' . T . ')' . B['pattern'] . ')' . M));
+}
+conditional(A) ::= OPENASSERTION OPENPAREN TEXT(T) CLOSEPAREN pattern(B) CLOSEPAREN. {
+ if (T != 'R') {
+ if (!preg_match('/[1-9][0-9]*/', T)) {
+ throw new PHP_LexerGenerator_Exception('Invalid sub-pattern conditional: "(?(' . T . ')"');
+ }
+ if (T > $this->_subpatterns) {
+ throw new PHP_LexerGenerator_Exception('sub-pattern conditional . "' . T . '" refers to non-existent sub-pattern');
+ }
+ } else {
+ throw new PHP_LexerGenerator_Exception('Recursive conditional (?(' . T . ')" cannot work in this lexer');
+ }
+ A = new PHP_LexerGenerator_ParseryyToken('(?(' . T . ')' . B->string . ')', array(
+ 'pattern' => '(?(' . T . ')' . B['pattern'] . ')'));
+}
+conditional(A) ::= OPENASSERTION lookahead(B) pattern(C) CLOSEPAREN. {
+ A = new PHP_LexerGenerator_ParseryyToken('(?' . B->string . C->string . ')', array(
+ 'pattern' => '(?' . B['pattern'] . C['pattern'] . ')'));
+}
+conditional(A) ::= OPENASSERTION lookahead(B) pattern(C) CLOSEPAREN MULTIPLIER(M). {
+ A = new PHP_LexerGenerator_ParseryyToken('(?' . B->string . C->string . ')' . M, array(
+ 'pattern' => '(?' . B['pattern'] . C['pattern'] . ')' . M));
+}
+conditional ::= OPENASSERTION lookbehind pattern(B) CLOSEPAREN. {
+ throw new PHP_LexerGenerator_Exception('Look-behind assertions cannot be used: "(?<=' .
+ B['pattern'] . ')');
+}
+conditional ::= OPENASSERTION lookbehind pattern(B) CLOSEPAREN MULTIPLIER. {
+ throw new PHP_LexerGenerator_Exception('Look-behind assertions cannot be used: "(?<=' .
+ B['pattern'] . ')');
+}
+
+lookahead(A) ::= OPENASSERTION POSITIVELOOKAHEAD pattern(B) CLOSEPAREN. {
+ A = new PHP_LexerGenerator_ParseryyToken('(?=' . B->string . ')', array(
+ 'pattern '=> '(?=' . B['pattern'] . ')'));
+}
+lookahead(A) ::= OPENASSERTION NEGATIVELOOKAHEAD pattern(B) CLOSEPAREN. {
+ A = new PHP_LexerGenerator_ParseryyToken('(?!' . B->string . ')', array(
+ 'pattern' => '(?!' . B['pattern'] . ')'));
+}
+
+lookbehind ::= OPENASSERTION POSITIVELOOKBEHIND pattern(B) CLOSEPAREN. {
+ throw new PHP_LexerGenerator_Exception('Look-behind assertions cannot be used: "(?<=' .
+ B['pattern'] . ')');
+}
+lookbehind ::= OPENASSERTION NEGATIVELOOKBEHIND pattern(B) CLOSEPAREN. {
+ throw new PHP_LexerGenerator_Exception('Look-behind assertions cannot be used: "(?_subpatterns++;
+ A = new PHP_LexerGenerator_ParseryyToken('(' . B->string . ')', array(
+ 'pattern' => '(' . B['pattern'] . ')'));
+}
+subpattern(A) ::= OPENPAREN pattern(B) CLOSEPAREN MULTIPLIER(M). {
+ $this->_subpatterns++;
+ A = new PHP_LexerGenerator_ParseryyToken('(' . B->string . ')' . M, array(
+ 'pattern' => '(' . B['pattern'] . ')' . M));
+}
+
+onceonly(A) ::= OPENASSERTION ONCEONLY pattern(B) CLOSEPAREN. {
+ A = new PHP_LexerGenerator_ParseryyToken('(?>' . B->string . ')', array(
+ 'pattern' => '(?>' . B['pattern'] . ')'));
+}
+
+comment(A) ::= OPENASSERTION COMMENT(B) CLOSEPAREN. {
+ A = new PHP_LexerGenerator_ParseryyToken('(' . B->string . ')', array(
+ 'pattern' => '(' . B['pattern'] . ')'));
+}
+
+recur ::= OPENASSERTION RECUR CLOSEPAREN. {
+ throw new Exception('(?R) cannot work in this lexer');
+}
\ No newline at end of file
diff --git a/core/oql/build/PHP/LexerGenerator/cli.php b/core/oql/build/PHP/LexerGenerator/cli.php
new file mode 100644
index 000000000..82f73167f
--- /dev/null
+++ b/core/oql/build/PHP/LexerGenerator/cli.php
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/core/oql/build/PHP/ParserGenerator.php b/core/oql/build/PHP/ParserGenerator.php
new file mode 100644
index 000000000..4a6fa08a4
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator.php
@@ -0,0 +1,806 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: ParserGenerator.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+/**#@+
+ * Basic components of the parser generator
+ */
+require_once 'PHP/ParserGenerator/Action.php';
+require_once 'PHP/ParserGenerator/ActionTable.php';
+require_once 'PHP/ParserGenerator/Config.php';
+require_once 'PHP/ParserGenerator/Data.php';
+require_once 'PHP/ParserGenerator/Symbol.php';
+require_once 'PHP/ParserGenerator/Rule.php';
+require_once 'PHP/ParserGenerator/Parser.php';
+require_once 'PHP/ParserGenerator/PropagationLink.php';
+require_once 'PHP/ParserGenerator/State.php';
+/**#@-*/
+/**
+ * The basic home class for the parser generator
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ * @example Lempar.php
+ * @example examples/Parser.y Sample parser file format (PHP_LexerGenerator's parser)
+ * @example examples/Parser.php Sample parser file format PHP code (PHP_LexerGenerator's parser)
+ */
+class PHP_ParserGenerator
+{
+ /**
+ * Set this to 1 to turn on debugging of Lemon's parsing of
+ * grammar files.
+ */
+ const DEBUG = 0;
+ const MAXRHS = 1000;
+ const OPT_FLAG = 1, OPT_INT = 2, OPT_DBL = 3, OPT_STR = 4,
+ OPT_FFLAG = 5, OPT_FINT = 6, OPT_FDBL = 7, OPT_FSTR = 8;
+ public $azDefine = array();
+ private static $_options = array(
+ 'b' => array(
+ 'type' => self::OPT_FLAG,
+ 'arg' => 'basisflag',
+ 'message' => 'Print only the basis in report.'
+ ),
+ 'c' => array(
+ 'type' => self::OPT_FLAG,
+ 'arg' => 'compress',
+ 'message' => 'Don\'t compress the action table.'
+ ),
+ 'D' => array(
+ 'type' => self::OPT_FSTR,
+ 'arg' => 'handleDOption',
+ 'message' => 'Define an %ifdef macro.'
+ ),
+ 'g' => array(
+ 'type' => self::OPT_FLAG,
+ 'arg' => 'rpflag',
+ 'message' => 'Print grammar without actions.'
+ ),
+ 'm' => array(
+ 'type' => self::OPT_FLAG,
+ 'arg' => 'mhflag',
+ 'message' => 'Output a makeheaders compatible file'
+ ),
+ 'q' => array(
+ 'type' => self::OPT_FLAG,
+ 'arg' => 'quiet',
+ 'message' => '(Quiet) Don\'t print the report file.'
+ ),
+ 's' => array(
+ 'type' => self::OPT_FLAG,
+ 'arg' => 'statistics',
+ 'message' => 'Print parser stats to standard output.'
+ ),
+ 'x' => array(
+ 'type' => self::OPT_FLAG,
+ 'arg' => 'version',
+ 'message' => 'Print the version number.'
+ ),
+ 'T' => array(
+ 'type' => self::OPT_STR,
+ 'arg' => 'parser_template',
+ 'message' => 'Use different parser template file.'
+ )
+ );
+
+ private $_basisflag = 0;
+ private $_compress = 0;
+ private $_rpflag = 0;
+ private $_mhflag = 0;
+ private $_quiet = 0;
+ private $_statistics = 0;
+ private $_version = 0;
+ private $_size;
+ private $_parser_template = "";
+
+ /**
+ * Process a flag command line argument.
+ *
+ * @param int $i
+ * @param array $argv
+ *
+ * @return int
+ */
+ function handleflags($i, $argv)
+ {
+ if (!isset($argv[1]) || !isset(self::$_options[$argv[$i][1]])) {
+ throw new Exception('Command line syntax error: undefined option "' . $argv[$i] . '"');
+ }
+ $v = self::$_options[$argv[$i][1]] == '-';
+ if (self::$_options[$argv[$i][1]]['type'] == self::OPT_FLAG) {
+ $this->{self::$_options[$argv[$i][1]]['arg']} = 1;
+ } elseif (self::$_options[$argv[$i][1]]['type'] == self::OPT_FFLAG) {
+ $this->{self::$_options[$argv[$i][1]]['arg']}($v);
+ } elseif (self::$_options[$argv[$i][1]]['type'] == self::OPT_FSTR) {
+ $this->{self::$_options[$argv[$i][1]]['arg']}(substr($v, 2));
+ } else {
+ throw new Exception('Command line syntax error: missing argument on switch: "' . $argv[$i] . '"');
+ }
+ return 0;
+ }
+
+ /**
+ * Process a command line switch which has an argument.
+ *
+ * @param int $i
+ * @param array $argv
+ *
+ * @return int
+ */
+ function handleswitch($i, $argv)
+ {
+ $lv = 0;
+ $dv = 0.0;
+ $sv = $end = $cp = '';
+ $j; // int
+ $errcnt = 0;
+ $cp = strstr($argv[$i], '=');
+ if (!$cp) {
+ throw new Exception('INTERNAL ERROR: handleswitch passed bad argument, no "=" in arg');
+ }
+ $argv[$i] = substr($argv[$i], 0, strlen($argv[$i]) - strlen($cp));
+ if (!isset(self::$_options[$argv[$i]])) {
+ throw new Exception('Command line syntax error: undefined option "' . $argv[$i] .
+ $cp . '"');
+ }
+ $cp = substr($cp, 1);
+ switch (self::$_options[$argv[$i]]['type']) {
+ case self::OPT_FLAG:
+ case self::OPT_FFLAG:
+ throw new Exception('Command line syntax error: option requires an argument "' .
+ $argv[$i] . '=' . $cp . '"');
+ case self::OPT_DBL:
+ case self::OPT_FDBL:
+ $dv = (double) $cp;
+ break;
+ case self::OPT_INT:
+ case self::OPT_FINT:
+ $lv = (int) $cp;
+ break;
+ case self::OPT_STR:
+ case self::OPT_FSTR:
+ $sv = $cp;
+ break;
+ }
+ switch(self::$_options[$argv[$i]]['type']) {
+ case self::OPT_FLAG:
+ case self::OPT_FFLAG:
+ break;
+ case self::OPT_DBL:
+ $this->{self::$_options[$argv[$i]]['arg']} = $dv;
+ break;
+ case self::OPT_FDBL:
+ $this->{self::$_options[$argv[$i]]['arg']}($dv);
+ break;
+ case self::OPT_INT:
+ $this->{self::$_options[$argv[$i]]['arg']} = $lv;
+ break;
+ case self::OPT_FINT:
+ $this->{self::$_options[$argv[$i]]['arg']}($lv);
+ break;
+ case self::OPT_STR:
+ $this->{self::$_options[$argv[$i]]['arg']} = $sv;
+ break;
+ case self::OPT_FSTR:
+ $this->{self::$_options[$argv[$i]]['arg']}($sv);
+ break;
+ }
+ return 0;
+ }
+
+ /**
+ * OptInit
+ *
+ * @param array $a Arguments
+ *
+ * @return int
+ */
+ function OptInit($a)
+ {
+ $errcnt = 0;
+ $argv = $a;
+ try {
+ if (is_array($argv) && count($argv) && self::$_options) {
+ for ($i = 1; $i < count($argv); $i++) {
+ if ($argv[$i][0] == '+' || $argv[$i][0] == '-') {
+ $errcnt += $this->handleflags($i, $argv);
+ } elseif (strstr($argv[$i], '=')) {
+ $errcnt += $this->handleswitch($i, $argv);
+ }
+ }
+ }
+ } catch (Exception $e) {
+ $this->OptPrint();
+ echo $e->getMessage()."\n";
+ exit(1);
+ }
+ return 0;
+ }
+
+ /**
+ * Return the index of the N-th non-switch argument. Return -1
+ * if N is out of range.
+ *
+ * @param int $n
+ * @param int $a
+ *
+ * @return int
+ */
+ private function _argindex($n, $a)
+ {
+ $dashdash = 0;
+ if (!is_array($a) || !count($a)) {
+ return -1;
+ }
+ for ($i=1; $i < count($a); $i++) {
+ if ($dashdash || !($a[$i][0] == '-' || $a[$i][0] == '+' || strchr($a[$i], '='))) {
+ if ($n == 0) {
+ return $i;
+ }
+ $n--;
+ }
+ if ($_SERVER['argv'][$i] == '--') {
+ $dashdash = 1;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Return the value of the non-option argument as indexed by $i
+ *
+ * @param int $i
+ * @param array $a the value of $argv
+ *
+ * @return 0|string
+ */
+ private function _optArg($i, $a)
+ {
+ if (-1 == ($ind = $this->_argindex($i, $a))) {
+ return 0;
+ }
+ return $a[$ind];
+ }
+
+ /**
+ * @param array $a
+ *
+ * @return int number of arguments
+ */
+ function OptNArgs($a)
+ {
+ $cnt = $dashdash = 0;
+ if (is_array($a) && count($a)) {
+ for ($i = 1; $i < count($a); $i++) {
+ if ($dashdash
+ || !($a[$i][0] == '-' || $a[$i][0] == '+' || strchr($a[$i], '='))
+ ) {
+ $cnt++;
+ }
+ if ($a[$i] == "--") {
+ $dashdash = 1;
+ }
+ }
+ }
+ return $cnt;
+ }
+
+ /**
+ * Print out command-line options
+ *
+ * @return void
+ */
+ function OptPrint()
+ {
+ $max = 0;
+ foreach (self::$_options as $label => $info) {
+ $len = strlen($label) + 1;
+ switch ($info['type']) {
+ case self::OPT_FLAG:
+ case self::OPT_FFLAG:
+ break;
+ case self::OPT_INT:
+ case self::OPT_FINT:
+ $len += 9; /* length of "" */
+ break;
+ case self::OPT_DBL:
+ case self::OPT_FDBL:
+ $len += 6; /* length of "" */
+ break;
+ case self::OPT_STR:
+ case self::OPT_FSTR:
+ $len += 8; /* length of "" */
+ break;
+ }
+ if ($len > $max) {
+ $max = $len;
+ }
+ }
+ foreach (self::$_options as $label => $info) {
+ switch ($info['type']) {
+ case self::OPT_FLAG:
+ case self::OPT_FFLAG:
+ echo " -$label";
+ echo str_repeat(' ', $max - strlen($label));
+ echo " $info[message]\n";
+ break;
+ case self::OPT_INT:
+ case self::OPT_FINT:
+ echo " $label=" . str_repeat(' ', $max - strlen($label) - 9);
+ echo " $info[message]\n";
+ break;
+ case self::OPT_DBL:
+ case self::OPT_FDBL:
+ echo " $label=" . str_repeat(' ', $max - strlen($label) - 6);
+ echo " $info[message]\n";
+ break;
+ case self::OPT_STR:
+ case self::OPT_FSTR:
+ echo " $label=" . str_repeat(' ', $max - strlen($label) - 8);
+ echo " $info[message]\n";
+ break;
+ }
+ }
+ }
+
+ /**
+ * This routine is called with the argument to each -D command-line option.
+ * Add the macro defined to the azDefine array.
+ *
+ * @param string $z
+ *
+ * @return void
+ */
+ private function _handleDOption($z)
+ {
+ if ($a = strstr($z, '=')) {
+ $z = substr($a, 1); // strip first =
+ }
+ $this->azDefine[] = $z;
+ }
+
+ /**************** From the file "main.c" ************************************/
+ /*
+ ** Main program file for the LEMON parser generator.
+ */
+
+
+ /**
+ * The main program. Parse the command line and do it...
+ *
+ * @return int Number of error and conflicts
+ */
+ function main()
+ {
+ $lem = new PHP_ParserGenerator_Data;
+
+ $this->OptInit($_SERVER['argv']);
+ if ($this->_version) {
+ echo "Lemon version 1.0/PHP_ParserGenerator port version @package_version@\n";
+ exit(0);
+ }
+ if ($this->OptNArgs($_SERVER['argv']) != 1) {
+ echo "Exactly one filename argument is required.\n";
+ exit(1);
+ }
+ $lem->errorcnt = 0;
+ $lem->parser_template = $this->_parser_template;
+
+ /* Initialize the machine */
+ $lem->argv0 = $_SERVER['argv'][0];
+ $lem->filename = $this->_optArg(0, $_SERVER['argv']);
+ $a = pathinfo($lem->filename);
+ if (isset($a['extension'])) {
+ $ext = '.' . $a['extension'];
+ $lem->filenosuffix = substr($lem->filename, 0, strlen($lem->filename) - strlen($ext));
+ } else {
+ $lem->filenosuffix = $lem->filename;
+ }
+ $lem->basisflag = $this->_basisflag;
+ $lem->has_fallback = 0;
+ $lem->nconflict = 0;
+ $lem->name = $lem->include_code = $lem->include_classcode = $lem->arg = $lem->tokentype = $lem->start = 0;
+ $lem->vartype = 0;
+ $lem->stacksize = 0;
+ $lem->error = $lem->overflow = $lem->failure = $lem->accept = $lem->tokendest = $lem->tokenprefix = $lem->outname = $lem->extracode = 0;
+ $lem->vardest = 0;
+ $lem->tablesize = 0;
+ PHP_ParserGenerator_Symbol::Symbol_new("$");
+ $lem->errsym = PHP_ParserGenerator_Symbol::Symbol_new("error");
+
+ /* Parse the input file */
+ $parser = new PHP_ParserGenerator_Parser($this);
+ $parser->Parse($lem);
+ if ($lem->errorcnt) {
+ exit($lem->errorcnt);
+ }
+ if ($lem->rule === 0) {
+ printf("Empty grammar.\n");
+ exit(1);
+ }
+
+ /* Count and index the symbols of the grammar */
+ $lem->nsymbol = PHP_ParserGenerator_Symbol::Symbol_count();
+ PHP_ParserGenerator_Symbol::Symbol_new("{default}");
+ $lem->symbols = PHP_ParserGenerator_Symbol::Symbol_arrayof();
+ for ($i = 0; $i <= $lem->nsymbol; $i++) {
+ $lem->symbols[$i]->index = $i;
+ }
+ usort($lem->symbols, array('PHP_ParserGenerator_Symbol', 'sortSymbols'));
+ for ($i = 0; $i <= $lem->nsymbol; $i++) {
+ $lem->symbols[$i]->index = $i;
+ }
+ // find the first lower-case symbol
+ for ($i = 1; ord($lem->symbols[$i]->name[0]) <= ord('Z'); $i++);
+ $lem->nterminal = $i;
+
+ /* Generate a reprint of the grammar, if requested on the command line */
+ if ($this->_rpflag) {
+ $this->Reprint();
+ } else {
+ /* Initialize the size for all follow and first sets */
+ $this->SetSize($lem->nterminal);
+
+ /* Find the precedence for every production rule (that has one) */
+ $lem->FindRulePrecedences();
+
+ /* Compute the lambda-nonterminals and the first-sets for every
+ ** nonterminal */
+ $lem->FindFirstSets();
+
+ /* Compute all LR(0) states. Also record follow-set propagation
+ ** links so that the follow-set can be computed later */
+ $lem->nstate = 0;
+ $lem->FindStates();
+ $lem->sorted = PHP_ParserGenerator_State::State_arrayof();
+
+ /* Tie up loose ends on the propagation links */
+ $lem->FindLinks();
+
+ /* Compute the follow set of every reducible configuration */
+ $lem->FindFollowSets();
+
+ /* Compute the action tables */
+ $lem->FindActions();
+
+ /* Compress the action tables */
+ if ($this->_compress===0) {
+ $lem->CompressTables();
+ }
+
+ /* Reorder and renumber the states so that states with fewer choices
+ ** occur at the end. */
+ $lem->ResortStates();
+
+ /* Generate a report of the parser generated. (the "y.output" file) */
+ if (!$this->_quiet) {
+ $lem->ReportOutput();
+ }
+
+ /* Generate the source code for the parser */
+ $lem->ReportTable($this->_mhflag);
+
+ /* Produce a header file for use by the scanner. (This step is
+ ** omitted if the "-m" option is used because makeheaders will
+ ** generate the file for us.) */
+ //if (!$this->_mhflag) {
+ // $this->ReportHeader();
+ //}
+ }
+ if ($this->_statistics) {
+ printf(
+ "Parser statistics: %d terminals, %d nonterminals, %d rules\n",
+ $lem->nterminal,
+ $lem->nsymbol - $lem->nterminal,
+ $lem->nrule
+ );
+ printf(
+ " %d states, %d parser table entries, %d conflicts\n",
+ $lem->nstate,
+ $lem->tablesize,
+ $lem->nconflict
+ );
+ }
+ if ($lem->nconflict) {
+ printf("%d parsing conflicts.\n", $lem->nconflict);
+ }
+ exit($lem->errorcnt + $lem->nconflict);
+ return ($lem->errorcnt + $lem->nconflict);
+ }
+
+ /**
+ * SetSize
+ *
+ * @param int $n
+ *
+ * @access public
+ * @return void
+ */
+ function SetSize($n)
+ {
+ $this->_size = $n + 1;
+ }
+
+ /**
+ * Merge in a merge sort for a linked list
+ *
+ * Side effects:
+ * The "next" pointers for elements in the lists a and b are
+ * changed.
+ *
+ * @param mixed $a A sorted, null-terminated linked list. (May be null).
+ * @param mixed $b A sorted, null-terminated linked list. (May be null).
+ * @param function $cmp A pointer to the comparison function.
+ * @param integer $offset Offset in the structure to the "next" field.
+ *
+ * @return mixed A pointer to the head of a sorted list containing the
+ * elements of both a and b.
+ */
+ static function merge($a, $b, $cmp, $offset)
+ {
+ if ($a === 0) {
+ $head = $b;
+ } elseif ($b === 0) {
+ $head = $a;
+ } else {
+ if (call_user_func($cmp, $a, $b) < 0) {
+ $ptr = $a;
+ $a = $a->$offset;
+ } else {
+ $ptr = $b;
+ $b = $b->$offset;
+ }
+ $head = $ptr;
+ while ($a && $b) {
+ if (call_user_func($cmp, $a, $b) < 0) {
+ $ptr->$offset = $a;
+ $ptr = $a;
+ $a = $a->$offset;
+ } else {
+ $ptr->$offset = $b;
+ $ptr = $b;
+ $b = $b->$offset;
+ }
+ }
+ if ($a !== 0) {
+ $ptr->$offset = $a;
+ } else {
+ $ptr->$offset = $b;
+ }
+ }
+ return $head;
+ }
+
+ #define LISTSIZE 30
+ /**
+ * Side effects:
+ * The "next" pointers for elements in list are changed.
+ *
+ * @param mixed $list Pointer to a singly-linked list of structures.
+ * @param mixed $next Pointer to pointer to the second element of the list.
+ * @param function $cmp A comparison function.
+ *
+ * @return mixed A pointer to the head of a sorted list containing the
+ * elements orginally in list.
+ */
+ static function msort($list, $next, $cmp)
+ {
+ if ($list === 0) {
+ return $list;
+ }
+ if ($list->$next === 0) {
+ return $list;
+ }
+ $set = array_fill(0, 30, 0);
+ while ($list) {
+ $ep = $list;
+ $list = $list->$next;
+ $ep->$next = 0;
+ for ($i = 0; $i < 29 && $set[$i] !== 0; $i++) {
+ $ep = self::merge($ep, $set[$i], $cmp, $next);
+ $set[$i] = 0;
+ }
+ $set[$i] = $ep;
+ }
+ $ep = 0;
+ for ($i = 0; $i < 30; $i++) {
+ if ($set[$i] !== 0) {
+ $ep = self::merge($ep, $set[$i], $cmp, $next);
+ }
+ }
+ return $ep;
+ }
+
+ /* Find a good place to break "msg" so that its length is at least "min"
+ ** but no more than "max". Make the point as close to max as possible.
+ */
+ static function findbreak($msg, $min, $max)
+ {
+ if ($min >= strlen($msg)) {
+ return strlen($msg);
+ }
+ for ($i = $spot = $min; $i <= $max && $i < strlen($msg); $i++) {
+ $c = $msg[$i];
+ if ($c == '-' && $i < $max - 1) {
+ $spot = $i + 1;
+ }
+ if ($c == ' ') {
+ $spot = $i;
+ }
+ }
+ return $spot;
+ }
+
+ static function ErrorMsg($filename, $lineno, $format)
+ {
+ /* Prepare a prefix to be prepended to every output line */
+ if ($lineno > 0) {
+ $prefix = sprintf("%20s:%d: ", $filename, $lineno);
+ } else {
+ $prefix = sprintf("%20s: ", $filename);
+ }
+ $prefixsize = strlen($prefix);
+ $availablewidth = 79 - $prefixsize;
+
+ /* Generate the error message */
+ $ap = func_get_args();
+ array_shift($ap); // $filename
+ array_shift($ap); // $lineno
+ array_shift($ap); // $format
+ $errmsg = vsprintf($format, $ap);
+ $linewidth = strlen($errmsg);
+ /* Remove trailing "\n"s from the error message. */
+ while ($linewidth > 0
+ && in_array($errmsg[$linewidth-1], array("\n", "\r"), true)
+ ) {
+ --$linewidth;
+ $errmsg = substr($errmsg, 0, strlen($errmsg) - 1);
+ }
+
+ /* Print the error message */
+ $base = 0;
+ $errmsg = str_replace(
+ array("\r", "\n", "\t"),
+ array(' ', ' ', ' '),
+ $errmsg
+ );
+ while (strlen($errmsg)) {
+ $end = $restart = self::findbreak($errmsg, 0, $availablewidth);
+ if (strlen($errmsg) <= 79 && $end < strlen($errmsg) && $end <= 79) {
+ $end = $restart = strlen($errmsg);
+ }
+ while (isset($errmsg[$restart]) && $errmsg[$restart] == ' ') {
+ $restart++;
+ }
+ printf("%s%.${end}s\n", $prefix, $errmsg);
+ $errmsg = substr($errmsg, $restart);
+ }
+ }
+
+ /**
+ * Duplicate the input file without comments and without actions
+ * on rules
+ *
+ * @return void
+ */
+ function Reprint()
+ {
+ printf("// Reprint of input file \"%s\".\n// Symbols:\n", $this->filename);
+ $maxlen = 10;
+ for ($i = 0; $i < $this->nsymbol; $i++) {
+ $sp = $this->symbols[$i];
+ $len = strlen($sp->name);
+ if ($len > $maxlen ) {
+ $maxlen = $len;
+ }
+ }
+ $ncolumns = 76 / ($maxlen + 5);
+ if ($ncolumns < 1) {
+ $ncolumns = 1;
+ }
+ $skip = ($this->nsymbol + $ncolumns - 1) / $ncolumns;
+ for ($i = 0; $i < $skip; $i++) {
+ print "//";
+ for ($j = $i; $j < $this->nsymbol; $j += $skip) {
+ $sp = $this->symbols[$j];
+ //assert( sp->index==j );
+ printf(" %3d %-${maxlen}.${maxlen}s", $j, $sp->name);
+ }
+ print "\n";
+ }
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ printf("%s", $rp->lhs->name);
+ /*if ($rp->lhsalias) {
+ printf("(%s)", $rp->lhsalias);
+ }*/
+ print " ::=";
+ for ($i = 0; $i < $rp->nrhs; $i++) {
+ $sp = $rp->rhs[$i];
+ printf(" %s", $sp->name);
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ for ($j = 1; $j < $sp->nsubsym; $j++) {
+ printf("|%s", $sp->subsym[$j]->name);
+ }
+ }
+ /*if ($rp->rhsalias[$i]) {
+ printf("(%s)", $rp->rhsalias[$i]);
+ }*/
+ }
+ print ".";
+ if ($rp->precsym) {
+ printf(" [%s]", $rp->precsym->name);
+ }
+ /*if ($rp->code) {
+ print "\n " . $rp->code);
+ }*/
+ print "\n";
+ }
+ }
+}
diff --git a/core/oql/build/PHP/ParserGenerator/Action.php b/core/oql/build/PHP/ParserGenerator/Action.php
new file mode 100644
index 000000000..e0108890e
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/Action.php
@@ -0,0 +1,257 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Action.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+
+/**
+ * Every shift or reduce operation is stored as one of the following objects.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+class PHP_ParserGenerator_Action
+{
+ const SHIFT = 1,
+ ACCEPT = 2,
+ REDUCE = 3,
+ ERROR = 4,
+ /**
+ * Was a reduce, but part of a conflict
+ */
+ CONFLICT = 5,
+ /**
+ * Was a shift. Precedence resolved conflict
+ */
+ SH_RESOLVED = 6,
+ /**
+ * Was a reduce. Precedence resolved conflict
+ */
+ RD_RESOLVED = 7,
+ /**
+ * Deleted by compression
+ * @see PHP_ParserGenerator::CompressTables()
+ */
+ NOT_USED = 8;
+ /**
+ * The look-ahead symbol that triggers this action
+ * @var PHP_ParserGenerator_Symbol
+ */
+ public $sp; /* The look-ahead symbol */
+ /**
+ * This defines the kind of action, and must be one
+ * of the class constants.
+ *
+ * - {@link PHP_ParserGenerator_Action::SHIFT}
+ * - {@link PHP_ParserGenerator_Action::ACCEPT}
+ * - {@link PHP_ParserGenerator_Action::REDUCE}
+ * - {@link PHP_ParserGenerator_Action::ERROR}
+ * - {@link PHP_ParserGenerator_Action::CONFLICT}
+ * - {@link PHP_ParserGenerator_Action::SH_RESOLVED}
+ * - {@link PHP_ParserGenerator_Action:: RD_RESOLVED}
+ * - {@link PHP_ParserGenerator_Action::NOT_USED}
+ */
+ public $type;
+ /**
+ * The new state, if this is a shift,
+ * the parser rule index, if this is a reduce.
+ *
+ * @var PHP_ParserGenerator_State|PHP_ParserGenerator_Rule
+ */
+ public $x;
+ /**
+ * The next action for this state.
+ * @var PHP_ParserGenerator_Action
+ */
+ public $next;
+
+ /**
+ * Compare two actions
+ *
+ * This is used by {@link Action_sort()} to compare actions
+ */
+ static function actioncmp(PHP_ParserGenerator_Action $ap1, PHP_ParserGenerator_Action $ap2)
+ {
+ $rc = $ap1->sp->index - $ap2->sp->index;
+ if ($rc === 0) {
+ $rc = $ap1->type - $ap2->type;
+ }
+ if ($rc === 0) {
+ if ($ap1->type == self::SHIFT) {
+ if ($ap1->x->statenum != $ap2->x->statenum) {
+ throw new Exception('Shift conflict: ' . $ap1->sp->name .
+ ' shifts both to state ' . $ap1->x->statenum . ' (rule ' .
+ $ap1->x->cfp->rp->lhs->name . ' on line ' .
+ $ap1->x->cfp->rp->ruleline . ') and to state ' .
+ $ap2->x->statenum . ' (rule ' .
+ $ap2->x->cfp->rp->lhs->name . ' on line ' .
+ $ap2->x->cfp->rp->ruleline . ')');
+ }
+ }
+ if ($ap1->type != self::REDUCE
+ && $ap1->type != self::RD_RESOLVED
+ && $ap1->type != self::CONFLICT
+ ) {
+ throw new Exception('action has not been processed: ' .
+ $ap1->sp->name . ' on line ' . $ap1->x->cfp->rp->ruleline .
+ ', rule ' . $ap1->x->cfp->rp->lhs->name);
+ }
+ if ($ap2->type != self::REDUCE
+ && $ap2->type != self::RD_RESOLVED
+ && $ap2->type != self::CONFLICT
+ ) {
+ throw new Exception('action has not been processed: ' .
+ $ap2->sp->name . ' on line ' . $ap2->x->cfp->rp->ruleline .
+ ', rule ' . $ap2->x->cfp->rp->lhs->name);
+ }
+ $rc = $ap1->x->index - $ap2->x->index;
+ }
+ return $rc;
+ }
+
+ function display($processed = false)
+ {
+ $map = array(
+ self::ACCEPT => 'ACCEPT',
+ self::CONFLICT => 'CONFLICT',
+ self::REDUCE => 'REDUCE',
+ self::SHIFT => 'SHIFT'
+ );
+ echo $map[$this->type] . ' for ' . $this->sp->name;
+ if ($this->type == self::REDUCE) {
+ echo ' - rule ' . $this->x->lhs->name . "\n";
+ } elseif ($this->type == self::SHIFT) {
+ echo ' - state ' . $this->x->statenum . ', basis ' . $this->x->cfp->rp->lhs->name . "\n";
+ } else {
+ echo "\n";
+ }
+ }
+
+ /**
+ * create linked list of PHP_ParserGenerator_Actions
+ *
+ * @param PHP_ParserGenerator_Action|null $app
+ * @param int $type one of the class constants from PHP_ParserGenerator_Action
+ * @param PHP_ParserGenerator_Symbol $sp
+ * @param PHP_ParserGenerator_State|PHP_ParserGenerator_Rule $arg
+ */
+ static function Action_add(&$app, $type, PHP_ParserGenerator_Symbol $sp, $arg)
+ {
+ $new = new PHP_ParserGenerator_Action;
+ $new->next = $app;
+ $app = $new;
+ $new->type = $type;
+ $new->sp = $sp;
+ $new->x = $arg;
+ echo ' Adding ';
+ $new->display();
+ }
+
+ /**
+ * Sort parser actions
+ *
+ * @param PHP_ParserGenerator_Action $ap a parser action
+ *
+ * @see PHP_ParserGenerator_Data::FindActions()
+ *
+ * @return PHP_ParserGenerator_Action
+ */
+ static function Action_sort(PHP_ParserGenerator_Action $ap)
+ {
+ $ap = PHP_ParserGenerator::msort($ap, 'next', array('PHP_ParserGenerator_Action', 'actioncmp'));
+ return $ap;
+ }
+
+ /**
+ * Print an action to the given file descriptor. Return FALSE if
+ * nothing was actually printed.
+ *
+ * @param resource $fp File descriptor to print on
+ * @param integer $indent Number of indents
+ *
+ * @see PHP_ParserGenerator_Data::ReportOutput()
+ *
+ * @return int|false
+ */
+ function PrintAction($fp, $indent)
+ {
+ if (!$fp) {
+ $fp = STDOUT;
+ }
+ $result = 1;
+ switch ($this->type)
+ {
+ case self::SHIFT:
+ fprintf($fp, "%${indent}s shift %d", $this->sp->name, $this->x->statenum);
+ break;
+ case self::REDUCE:
+ fprintf($fp, "%${indent}s reduce %d", $this->sp->name, $this->x->index);
+ break;
+ case self::ACCEPT:
+ fprintf($fp, "%${indent}s accept", $this->sp->name);
+ break;
+ case self::ERROR:
+ fprintf($fp, "%${indent}s error", $this->sp->name);
+ break;
+ case self::CONFLICT:
+ fprintf($fp, "%${indent}s reduce %-3d ** Parsing conflict **", $this->sp->name, $this->x->index);
+ break;
+ case self::SH_RESOLVED:
+ case self::RD_RESOLVED:
+ case self::NOT_USED:
+ $result = 0;
+ break;
+ }
+ return $result;
+ }
+}
+?>
diff --git a/core/oql/build/PHP/ParserGenerator/ActionTable.php b/core/oql/build/PHP/ParserGenerator/ActionTable.php
new file mode 100644
index 000000000..9e6c8ca3d
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/ActionTable.php
@@ -0,0 +1,299 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: ActionTable.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+/**
+ * The state of the yy_action table under construction is an instance of
+ * the following structure
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+class PHP_ParserGenerator_ActionTable
+{
+ /**
+ * Number of used slots in {@link $aAction}
+ * @var int
+ */
+ public $nAction = 0;
+ /**
+ * The $yy_action table under construction.
+ *
+ * Each entry is of format:
+ *
+ * array(
+ * 'lookahead' => -1, // Value of the lookahead token (symbol index)
+ * 'action' => -1 // Action to take on the given lookahead (action index)
+ * );
+ *
+ * @see PHP_ParserGenerator_Data::compute_action()
+ * @var array
+ */
+ public $aAction = array(
+ array(
+ 'lookahead' => -1,
+ 'action' => -1
+ )
+ );
+ /**
+ * A single new transaction set.
+ *
+ * @see $aAction format of the internal array is described here
+ * @var array
+ */
+ public $aLookahead = array(
+ array(
+ 'lookahead' => 0,
+ 'action' => 0
+ )
+ );
+ /**
+ * The smallest (minimum) value of any lookahead token in {@link $aLookahead}
+ *
+ * The lowest non-terminal is always introduced earlier in the parser file,
+ * and is therefore a more significant token.
+ * @var int
+ */
+ public $mnLookahead = 0;
+ /**
+ * The action associated with the smallest lookahead token.
+ * @see $mnLookahead
+ * @var int
+ */
+ public $mnAction = 0;
+ /**
+ * The largest (maximum) value of any lookahead token in {@link $aLookahead}
+ * @var int
+ */
+ public $mxLookahead = 0;
+ /**
+ * The number of slots used in {@link $aLookahead}.
+ *
+ * This is the same as count($aLookahead), but there was no pressing reason
+ * to change this when porting from C.
+ * @see $mnLookahead
+ * @var int
+ */
+ public $nLookahead = 0;
+
+ /**
+ * Add a new action to the current transaction set
+ *
+ * @param int $lookahead
+ * @param int $action
+ *
+ * @return void
+ */
+ function acttab_action($lookahead, $action)
+ {
+ if ($this->nLookahead === 0) {
+ $this->aLookahead = array();
+ $this->mxLookahead = $lookahead;
+ $this->mnLookahead = $lookahead;
+ $this->mnAction = $action;
+ } else {
+ if ($this->mxLookahead < $lookahead) {
+ $this->mxLookahead = $lookahead;
+ }
+ if ($this->mnLookahead > $lookahead) {
+ $this->mnLookahead = $lookahead;
+ $this->mnAction = $action;
+ }
+ }
+ $this->aLookahead[$this->nLookahead] = array(
+ 'lookahead' => $lookahead,
+ 'action' => $action);
+ $this->nLookahead++;
+ }
+
+ /**
+ * Add the transaction set built up with prior calls to acttab_action()
+ * into the current action table. Then reset the transaction set back
+ * to an empty set in preparation for a new round of acttab_action() calls.
+ *
+ * Return the offset into the action table of the new transaction.
+ *
+ * @return int Return the offset that should be added to the lookahead in
+ * order to get the index into $yy_action of the action. This will be used
+ * in generation of $yy_ofst tables (reduce and shift)
+ * @throws Exception
+ */
+ function acttab_insert()
+ {
+ if ($this->nLookahead <= 0) {
+ throw new Exception('nLookahead is not set up?');
+ }
+
+ /* Scan the existing action table looking for an offset where we can
+ ** insert the current transaction set. Fall out of the loop when that
+ ** offset is found. In the worst case, we fall out of the loop when
+ ** i reaches $this->nAction, which means we append the new transaction set.
+ **
+ ** i is the index in $this->aAction[] where $this->mnLookahead is inserted.
+ */
+ for ($i = 0; $i < $this->nAction + $this->mnLookahead; $i++) {
+ if (!isset($this->aAction[$i])) {
+ $this->aAction[$i] = array(
+ 'lookahead' => -1,
+ 'action' => -1,
+ );
+ }
+ if ($this->aAction[$i]['lookahead'] < 0) {
+ for ($j = 0; $j < $this->nLookahead; $j++) {
+ if (!isset($this->aLookahead[$j])) {
+ $this->aLookahead[$j] = array(
+ 'lookahead' => 0,
+ 'action' => 0,
+ );
+ }
+ $k = $this->aLookahead[$j]['lookahead'] -
+ $this->mnLookahead + $i;
+ if ($k < 0) {
+ break;
+ }
+ if (!isset($this->aAction[$k])) {
+ $this->aAction[$k] = array(
+ 'lookahead' => -1,
+ 'action' => -1,
+ );
+ }
+ if ($this->aAction[$k]['lookahead'] >= 0) {
+ break;
+ }
+ }
+ if ($j < $this->nLookahead ) {
+ continue;
+ }
+ for ($j = 0; $j < $this->nAction; $j++) {
+ if (!isset($this->aAction[$j])) {
+ $this->aAction[$j] = array(
+ 'lookahead' => -1,
+ 'action' => -1,
+ );
+ }
+ if ($this->aAction[$j]['lookahead'] == $j + $this->mnLookahead - $i) {
+ break;
+ }
+ }
+ if ($j == $this->nAction) {
+ break; /* Fits in empty slots */
+ }
+ } elseif ($this->aAction[$i]['lookahead'] == $this->mnLookahead) {
+ if ($this->aAction[$i]['action'] != $this->mnAction) {
+ continue;
+ }
+ for ($j = 0; $j < $this->nLookahead; $j++) {
+ $k = $this->aLookahead[$j]['lookahead'] -
+ $this->mnLookahead + $i;
+ if ($k < 0 || $k >= $this->nAction) {
+ break;
+ }
+ if (!isset($this->aAction[$k])) {
+ $this->aAction[$k] = array(
+ 'lookahead' => -1,
+ 'action' => -1,
+ );
+ }
+ if ($this->aLookahead[$j]['lookahead'] != $this->aAction[$k]['lookahead']) {
+ break;
+ }
+ if ($this->aLookahead[$j]['action'] != $this->aAction[$k]['action']) {
+ break;
+ }
+ }
+ if ($j < $this->nLookahead) {
+ continue;
+ }
+ $n = 0;
+ for ($j = 0; $j < $this->nAction; $j++) {
+ if (!isset($this->aAction[$j])) {
+ $this->aAction[$j] = array(
+ 'lookahead' => -1,
+ 'action' => -1,
+ );
+ }
+ if ($this->aAction[$j]['lookahead'] < 0) {
+ continue;
+ }
+ if ($this->aAction[$j]['lookahead'] == $j + $this->mnLookahead - $i) {
+ $n++;
+ }
+ }
+ if ($n == $this->nLookahead) {
+ break; /* Same as a prior transaction set */
+ }
+ }
+ }
+ /* Insert transaction set at index i. */
+ for ($j = 0; $j < $this->nLookahead; $j++) {
+ if (!isset($this->aLookahead[$j])) {
+ $this->aLookahead[$j] = array(
+ 'lookahead' => 0,
+ 'action' => 0,
+ );
+ }
+ $k = $this->aLookahead[$j]['lookahead'] - $this->mnLookahead + $i;
+ $this->aAction[$k] = $this->aLookahead[$j];
+ if ($k >= $this->nAction) {
+ $this->nAction = $k + 1;
+ }
+ }
+ $this->nLookahead = 0;
+ $this->aLookahead = array();
+
+ /* Return the offset that is added to the lookahead in order to get the
+ ** index into yy_action of the action */
+ return $i - $this->mnLookahead;
+ }
+}
+?>
diff --git a/core/oql/build/PHP/ParserGenerator/Config.php b/core/oql/build/PHP/ParserGenerator/Config.php
new file mode 100644
index 000000000..591fb03bc
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/Config.php
@@ -0,0 +1,574 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Config.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+/**
+/** A configuration is a production rule of the grammar together with
+ * a mark (dot) showing how much of that rule has been processed so far.
+ *
+ * Configurations also contain a follow-set which is a list of terminal
+ * symbols which are allowed to immediately follow the end of the rule.
+ * Every configuration is recorded as an instance of the following class.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+class PHP_ParserGenerator_Config
+{
+ const COMPLETE = 1;
+ const INCOMPLETE = 2;
+ /**
+ * The parser rule upon with the configuration is based.
+ *
+ * A parser rule is something like:
+ *
+ * blah ::= FOO bar.
+ *
+ * @var PHP_ParserGenerator_Rule
+ */
+ public $rp;
+ /**
+ * The parse point.
+ *
+ * This is the index into the right-hand side of a rule that is
+ * represented by this configuration. In other words, possible
+ * dots for this rule:
+ *
+ *
+ * blah ::= FOO bar.
+ *
+ *
+ * are (represented by "[here]"):
+ *
+ *
+ * blah ::= [here] FOO bar.
+ * blah ::= FOO [here] bar.
+ * blah ::= FOO bar [here].
+ *
+ * @var int
+ */
+ public $dot;
+ /**
+ * Follow-set for this configuration only
+ *
+ * This is the list of terminals and non-terminals that
+ * can follow this configuration.
+ * @var array
+ */
+ public $fws;
+ /**
+ * Follow-set forward propagation links.
+ * @var PHP_ParserGenerator_PropagationLink
+ */
+ public $fplp;
+ /**
+ * Follow-set backwards propagation links
+ * @var PHP_ParserGenerator_PropagationLink
+ */
+ public $bplp;
+ /**
+ * State that contains this configuration
+ * @var PHP_ParserGenerator_State
+ */
+ public $stp;
+ /* enum {
+ COMPLETE, /* The status is used during followset and
+ INCOMPLETE /* shift computations
+ } */
+ /**
+ * Status during followset and shift computations.
+ *
+ * One of PHP_ParserGenerator_Config::COMPLETE or
+ * PHP_ParserGenerator_Config::INCOMPLETE.
+ * @var int
+ */
+ public $status;
+ /**
+ * Next configuration in the state.
+ *
+ * Index of next PHP_ParserGenerator_Config object.
+ * @var int
+ */
+ public $next;
+ /**
+ * Index of the next basis configuration PHP_ParserGenerator_Config object
+ * @var int
+ */
+ public $bp;
+
+ /**
+ * Top of the list of configurations for the current state.
+ * @var PHP_ParserGenerator_Config
+ */
+ static public $current;
+ /**
+ * Last on the list of configurations for the current state.
+ * @var PHP_ParserGenerator_Config
+ */
+ static public $currentend;
+
+ /**
+ * Top of the list of basis configurations for the current state.
+ * @var PHP_ParserGenerator_Config
+ */
+ static public $basis;
+ /**
+ * Last on the list of basis configurations for the current state.
+ * @var PHP_ParserGenerator_Config
+ */
+ static public $basisend;
+
+ /**
+ * Associative array representation of the linked list of configurations
+ * found in {@link $current}
+ *
+ * @var array
+ */
+ static public $x4a = array();
+
+ /**
+ * Return a pointer to a new configuration
+ * @return PHP_ParserGenerator_Config
+ */
+ private static function newconfig()
+ {
+ return new PHP_ParserGenerator_Config;
+ }
+
+ /**
+ * Display the current configuration for the .out file
+ *
+ * @param PHP_ParserGenerator_Config $cfp
+ * @see PHP_ParserGenerator_Data::ReportOutput()
+ */
+ static function Configshow(PHP_ParserGenerator_Config $cfp)
+ {
+ $fp = fopen('php://output', 'w');
+ while ($cfp) {
+ if ($cfp->dot == $cfp->rp->nrhs) {
+ $buf = sprintf('(%d)', $cfp->rp->index);
+ fprintf($fp, ' %5s ', $buf);
+ } else {
+ fwrite($fp,' ');
+ }
+ $cfp->ConfigPrint($fp);
+ fwrite($fp, "\n");
+ if (0) {
+ //SetPrint(fp,cfp->fws,$this);
+ //PlinkPrint(fp,cfp->fplp,"To ");
+ //PlinkPrint(fp,cfp->bplp,"From");
+ }
+ $cfp = $cfp->next;
+ }
+ fwrite($fp, "\n");
+ fclose($fp);
+ }
+
+ /**
+ * Initialize the configuration list builder for a new state.
+ */
+ static function Configlist_init()
+ {
+ self::$current = 0;
+ self::$currentend = &self::$current;
+ self::$basis = 0;
+ self::$basisend = &self::$basis;
+ self::$x4a = array();
+ }
+
+ /**
+ * Remove all data from the table.
+ *
+ * Pass each data to the function $f as it is removed if
+ * $f is a valid callback.
+ * @param callback|null
+ * @see Configtable_clear()
+ */
+ static function Configtable_reset($f)
+ {
+ self::$current = 0;
+ self::$currentend = &self::$current;
+ self::$basis = 0;
+ self::$basisend = &self::$basis;
+ self::Configtable_clear(0);
+ }
+
+ /**
+ * Remove all data from the associative array representation
+ * of configurations.
+ *
+ * Pass each data to the function $f as it is removed if
+ * $f is a valid callback.
+ * @param callback|null
+ */
+ static function Configtable_clear($f)
+ {
+ if (!count(self::$x4a)) {
+ return;
+ }
+ if ($f) {
+ for ($i = 0; $i < count(self::$x4a); $i++) {
+ call_user_func($f, self::$x4a[$i]->data);
+ }
+ }
+ self::$x4a = array();
+ }
+
+ /**
+ * Reset the configuration list builder for a new state.
+ * @see Configtable_clear()
+ */
+ static function Configlist_reset()
+ {
+ self::Configtable_clear(0);
+ }
+
+ /**
+ * Add another configuration to the configuration list for this parser state.
+ * @param PHP_ParserGenerator_Rule the rule
+ * @param int Index into the right-hand side of the rule where the dot goes
+ * @return PHP_ParserGenerator_Config
+ */
+ static function Configlist_add($rp, $dot)
+ {
+ $model = new PHP_ParserGenerator_Config;
+ $model->rp = $rp;
+ $model->dot = $dot;
+ $cfp = self::Configtable_find($model);
+ if ($cfp === 0) {
+ $cfp = self::newconfig();
+ $cfp->rp = $rp;
+ $cfp->dot = $dot;
+ $cfp->fws = array();
+ $cfp->stp = 0;
+ $cfp->fplp = $cfp->bplp = 0;
+ $cfp->next = 0;
+ $cfp->bp = 0;
+ self::$currentend = $cfp;
+ self::$currentend = &$cfp->next;
+ self::Configtable_insert($cfp);
+ }
+ return $cfp;
+ }
+
+ /**
+ * Add a basis configuration to the configuration list for this parser state.
+ *
+ * Basis configurations are the root for a configuration. This method also
+ * inserts the configuration into the regular list of configurations for this
+ * reason.
+ * @param PHP_ParserGenerator_Rule the rule
+ * @param int Index into the right-hand side of the rule where the dot goes
+ * @return PHP_ParserGenerator_Config
+ */
+ static function Configlist_addbasis($rp, $dot)
+ {
+ $model = new PHP_ParserGenerator_Config;
+ $model->rp = $rp;
+ $model->dot = $dot;
+ $cfp = self::Configtable_find($model);
+ if ($cfp === 0) {
+ $cfp = self::newconfig();
+ $cfp->rp = $rp;
+ $cfp->dot = $dot;
+ $cfp->fws = array();
+ $cfp->stp = 0;
+ $cfp->fplp = $cfp->bplp = 0;
+ $cfp->next = 0;
+ $cfp->bp = 0;
+ self::$currentend = $cfp;
+ self::$currentend = &$cfp->next;
+ self::$basisend = $cfp;
+ self::$basisend = &$cfp->bp;
+ self::Configtable_insert($cfp);
+ }
+ return $cfp;
+ }
+
+ /**
+ * Compute the closure of the configuration list.
+ *
+ * This calculates all of the possible continuations of
+ * each configuration, ensuring that each state accounts
+ * for every configuration that could arrive at that state.
+ */
+ static function Configlist_closure(PHP_ParserGenerator_Data $lemp)
+ {
+ for ($cfp = self::$current; $cfp; $cfp = $cfp->next) {
+ $rp = $cfp->rp;
+ $dot = $cfp->dot;
+ if ($dot >= $rp->nrhs) {
+ continue;
+ }
+ $sp = $rp->rhs[$dot];
+ if ($sp->type == PHP_ParserGenerator_Symbol::NONTERMINAL) {
+ if ($sp->rule === 0 && $sp !== $lemp->errsym) {
+ PHP_ParserGenerator::ErrorMsg($lemp->filename, $rp->line,
+ "Nonterminal \"%s\" has no rules.", $sp->name);
+ $lemp->errorcnt++;
+ }
+ for ($newrp = $sp->rule; $newrp; $newrp = $newrp->nextlhs) {
+ $newcfp = self::Configlist_add($newrp, 0);
+ for ($i = $dot + 1; $i < $rp->nrhs; $i++) {
+ $xsp = $rp->rhs[$i];
+ if ($xsp->type == PHP_ParserGenerator_Symbol::TERMINAL) {
+ $newcfp->fws[$xsp->index] = 1;
+ break;
+ } elseif ($xsp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ for ($k = 0; $k < $xsp->nsubsym; $k++) {
+ $newcfp->fws[$xsp->subsym[$k]->index] = 1;
+ }
+ break;
+ } else {
+ $a = array_diff_key($xsp->firstset, $newcfp->fws);
+ $newcfp->fws += $a;
+ if ($xsp->lambda === false) {
+ break;
+ }
+ }
+ }
+ if ($i == $rp->nrhs) {
+ PHP_ParserGenerator_PropagationLink::Plink_add($cfp->fplp, $newcfp);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sort the configuration list
+ * @uses Configcmp()
+ */
+ static function Configlist_sort()
+ {
+ $a = 0;
+ //self::Configshow(self::$current);
+ self::$current = PHP_ParserGenerator::msort(self::$current,'next', array('PHP_ParserGenerator_Config', 'Configcmp'));
+ //self::Configshow(self::$current);
+ self::$currentend = &$a;
+ self::$currentend = 0;
+ }
+
+ /**
+ * Sort the configuration list
+ * @uses Configcmp
+ */
+ static function Configlist_sortbasis()
+ {
+ $a = 0;
+ self::$basis = PHP_ParserGenerator::msort(self::$current,'bp', array('PHP_ParserGenerator_Config', 'Configcmp'));
+ self::$basisend = &$a;
+ self::$basisend = 0;
+ }
+
+ /**
+ * Return a pointer to the head of the configuration list and
+ * reset the list
+ * @see $current
+ * @return PHP_ParserGenerator_Config
+ */
+ static function Configlist_return()
+ {
+ $old = self::$current;
+ self::$current = 0;
+ self::$currentend = &self::$current;
+ return $old;
+ }
+
+ /**
+ * Return a pointer to the head of the basis list and
+ * reset the list
+ * @see $basis
+ * @return PHP_ParserGenerator_Config
+ */
+ static function Configlist_basis()
+ {
+ $old = self::$basis;
+ self::$basis = 0;
+ self::$basisend = &self::$basis;
+ return $old;
+ }
+
+ /**
+ * Free all elements of the given configuration list
+ * @param PHP_ParserGenerator_Config
+ */
+ static function Configlist_eat($cfp)
+ {
+ for (; $cfp; $cfp = $nextcfp) {
+ $nextcfp = $cfp->next;
+ if ($cfp->fplp !=0) {
+ throw new Exception('fplp of configuration non-zero?');
+ }
+ if ($cfp->bplp !=0) {
+ throw new Exception('bplp of configuration non-zero?');
+ }
+ if ($cfp->fws) {
+ $cfp->fws = array();
+ }
+ }
+ }
+
+ /**
+ * Compare two configurations for sorting purposes.
+ *
+ * Configurations based on higher precedence rules
+ * (those earlier in the file) are chosen first. Two
+ * configurations that are the same rule are sorted by
+ * dot (see {@link $dot}), and those configurations
+ * with a dot closer to the left-hand side are chosen first.
+ * @param unknown_type $a
+ * @param unknown_type $b
+ * @return unknown
+ */
+ static function Configcmp($a, $b)
+ {
+ $x = $a->rp->index - $b->rp->index;
+ if (!$x) {
+ $x = $a->dot - $b->dot;
+ }
+ return $x;
+ }
+
+ /**
+ * Print out information on this configuration.
+ *
+ * @param resource $fp
+ * @see PHP_ParserGenerator_Data::ReportOutput()
+ */
+ function ConfigPrint($fp)
+ {
+ $rp = $this->rp;
+ fprintf($fp, "%s ::=", $rp->lhs->name);
+ for ($i = 0; $i <= $rp->nrhs; $i++) {
+ if ($i === $this->dot) {
+ fwrite($fp,' *');
+ }
+ if ($i === $rp->nrhs) {
+ break;
+ }
+ $sp = $rp->rhs[$i];
+ fprintf($fp,' %s', $sp->name);
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ for ($j = 1; $j < $sp->nsubsym; $j++) {
+ fprintf($fp, '|%s', $sp->subsym[$j]->name);
+ }
+ }
+ }
+ }
+
+ /**
+ * Hash a configuration for the associative array {@link $x4a}
+ */
+ private static function confighash(PHP_ParserGenerator_Config $a)
+ {
+ $h = 0;
+ $h = $h * 571 + $a->rp->index * 37 + $a->dot;
+ return $h;
+ }
+
+ /**
+ * Insert a new record into the array. Return TRUE if successful.
+ * Prior data with the same key is NOT overwritten
+ */
+ static function Configtable_insert(PHP_ParserGenerator_Config $data)
+ {
+ $h = self::confighash($data);
+ if (isset(self::$x4a[$h])) {
+ $np = self::$x4a[$h];
+ } else {
+ $np = 0;
+ }
+ while ($np) {
+ if (self::Configcmp($np->data, $data) == 0) {
+ /* An existing entry with the same key is found. */
+ /* Fail because overwrite is not allows. */
+ return 0;
+ }
+ $np = $np->next;
+ }
+ /* Insert the new data */
+ $np = array('data' => $data, 'next' => 0, 'from' => 0);
+ $np = new PHP_ParserGenerator_StateNode;
+ $np->data = $data;
+ if (isset(self::$x4a[$h])) {
+ self::$x4a[$h]->from = $np->next;
+ $np->next = self::$x4a[$h];
+ }
+ $np->from = $np;
+ self::$x4a[$h] = $np;
+ return 1;
+ }
+
+ /**
+ * Return a pointer to data assigned to the given key. Return NULL
+ * if no such key.
+ * @return PHP_ParserGenerator_Config|0
+ */
+ static function Configtable_find(PHP_ParserGenerator_Config $key)
+ {
+ $h = self::confighash($key);
+ if (!isset(self::$x4a[$h])) {
+ return 0;
+ }
+ $np = self::$x4a[$h];
+ while ($np) {
+ if (self::Configcmp($np->data, $key) == 0) {
+ break;
+ }
+ $np = $np->next;
+ }
+ return $np ? $np->data : 0;
+ }
+}
+?>
diff --git a/core/oql/build/PHP/ParserGenerator/Data.php b/core/oql/build/PHP/ParserGenerator/Data.php
new file mode 100644
index 000000000..39e62597c
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/Data.php
@@ -0,0 +1,1857 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category php
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Data.php 302209 2010-08-14 14:32:56Z jespino $
+ * @since File available since Release 0.1.0
+ */
+/**
+/**
+ * The state vector for the entire parser generator is recorded in
+ * this class.
+ *
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version @package_version@
+ * @since Class available since Release 0.1.0
+ */
+
+class PHP_ParserGenerator_Data
+{
+ /**
+ * Used for terminal and non-terminal offsets into the action table
+ * when their default should be used instead
+ */
+ const NO_OFFSET = -2147483647;
+ /**
+ * Table of states sorted by state number
+ * @var array array of {@link PHP_ParserGenerator_State} objects
+ */
+ public $sorted;
+ /**
+ * List of all rules
+ * @var PHP_ParserGenerator_Rule
+ */
+ public $rule;
+ /**
+ * Number of states
+ * @var int
+ */
+ public $nstate;
+ /**
+ * Number of rules
+ * @var int
+ */
+ public $nrule;
+ /**
+ * Number of terminal and nonterminal symbols
+ * @var int
+ */
+ public $nsymbol;
+ /**
+ * Number of terminal symbols (tokens)
+ * @var int
+ */
+ public $nterminal;
+ /**
+ * Sorted array of pointers to symbols
+ * @var array array of {@link PHP_ParserGenerator_Symbol} objects
+ */
+ public $symbols = array();
+ /**
+ * Number of errors
+ * @var int
+ */
+ public $errorcnt;
+ /**
+ * The error symbol
+ * @var PHP_ParserGenerator_Symbol
+ */
+ public $errsym;
+ /**
+ * Name of the generated parser
+ * @var string
+ */
+ public $name;
+ /**
+ * Unused relic from the C version
+ *
+ * Type of terminal symbols in the parser stack
+ * @var string
+ */
+ public $tokentype;
+ /**
+ * Unused relic from the C version
+ *
+ * The default type of non-terminal symbols
+ * @var string
+ */
+ public $vartype;
+ /**
+ * Name of the start symbol for the grammar
+ * @var string
+ */
+ public $start;
+ /**
+ * Size of the parser stack
+ *
+ * This is 100 by default, but is set with the %stack_size directive
+ * @var int
+ */
+ public $stacksize;
+ /**
+ * Code to put at the start of the parser file
+ *
+ * This is set by the %include directive
+ * @var string
+ */
+ public $include_code;
+ /**
+ * Line number for start of include code
+ * @var int
+ */
+ public $includeln;
+ /**
+ * Code to put in the parser class
+ *
+ * This is set by the %include_class directive
+ * @var string
+ */
+ public $include_classcode;
+ /**
+ * Line number for start of include code
+ * @var int
+ */
+ public $include_classln;
+ /**
+ * any extends/implements code
+ *
+ * This is set by the %declare_class directive
+ * @var string
+ */
+ /**
+ * Line number for class declaration code
+ * @var int
+ */
+ public $declare_classcode;
+ /**
+ * Line number for start of class declaration code
+ * @var int
+ */
+ public $declare_classln;
+ /**
+ * Code to execute when a syntax error is seen
+ *
+ * This is set by the %syntax_error directive
+ * @var string
+ */
+ public $error;
+ /**
+ * Line number for start of error code
+ * @var int
+ */
+ public $errorln;
+ /**
+ * Code to execute on a stack overflow
+ *
+ * This is set by the %stack_overflow directive
+ */
+ public $overflow;
+ /**
+ * Line number for start of overflow code
+ * @var int
+ */
+ public $overflowln;
+ /**
+ * Code to execute on parser failure
+ *
+ * This is set by the %parse_failure directive
+ * @var string
+ */
+ public $failure;
+ /**
+ * Line number for start of failure code
+ * @var int
+ */
+ public $failureln;
+ /**
+ * Code to execute when the parser acccepts (completes parsing)
+ *
+ * This is set by the %parse_accept directive
+ * @var string
+ */
+ public $accept;
+ /**
+ * Line number for the start of accept code
+ * @var int
+ */
+ public $acceptln;
+ /**
+ * Code appended to the generated file
+ *
+ * This is set by the %code directive
+ * @var string
+ */
+ public $extracode;
+ /**
+ * Line number for the start of the extra code
+ * @var int
+ */
+ public $extracodeln;
+ /**
+ * Code to execute to destroy token data
+ *
+ * This is set by the %token_destructor directive
+ * @var string
+ */
+ public $tokendest;
+ /**
+ * Line number for token destroyer code
+ * @var int
+ */
+ public $tokendestln;
+ /**
+ * Code for the default non-terminal destructor
+ *
+ * This is set by the %default_destructor directive
+ * @var string
+ */
+ public $vardest;
+ /**
+ * Line number for default non-terminal destructor code
+ * @var int
+ */
+ public $vardestln;
+ /**
+ * Name of the input file
+ * @var string
+ */
+ public $filename;
+ /**
+ * Name of the input file without its extension
+ * @var string
+ */
+ public $filenosuffix;
+ /**
+ * Name of the current output file
+ * @var string
+ */
+ public $outname;
+ /**
+ * A prefix added to token names
+ * @var string
+ */
+ public $tokenprefix;
+ /**
+ * Number of parsing conflicts
+ * @var int
+ */
+ public $nconflict;
+ /**
+ * Size of the parse tables
+ * @var int
+ */
+ public $tablesize;
+ /**
+ * Public only basis configurations
+ */
+ public $basisflag;
+ /**
+ * True if any %fallback is seen in the grammer
+ * @var boolean
+ */
+ public $has_fallback;
+ /**
+ * Name of the program
+ * @var string
+ */
+ public $argv0;
+
+ /**
+ * Alternate parser template file
+ * @var string
+ */
+ public $parser_template = "";
+
+ /* Find a precedence symbol of every rule in the grammar.
+ *
+ * Those rules which have a precedence symbol coded in the input
+ * grammar using the "[symbol]" construct will already have the
+ * $rp->precsym field filled. Other rules take as their precedence
+ * symbol the first RHS symbol with a defined precedence. If there
+ * are not RHS symbols with a defined precedence, the precedence
+ * symbol field is left blank.
+ */
+ function FindRulePrecedences()
+ {
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ if ($rp->precsym === 0) {
+ for ($i = 0; $i < $rp->nrhs && $rp->precsym === 0; $i++) {
+ $sp = $rp->rhs[$i];
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ for ($j = 0; $j < $sp->nsubsym; $j++) {
+ if ($sp->subsym[$j]->prec >= 0) {
+ $rp->precsym = $sp->subsym[$j];
+ break;
+ }
+ }
+ } elseif ($sp->prec >= 0) {
+ $rp->precsym = $rp->rhs[$i];
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Find all nonterminals which will generate the empty string.
+ * Then go back and compute the first sets of every nonterminal.
+ * The first set is the set of all terminal symbols which can begin
+ * a string generated by that nonterminal.
+ */
+ function FindFirstSets()
+ {
+ for ($i = 0; $i < $this->nsymbol; $i++) {
+ $this->symbols[$i]->lambda = false;
+ }
+ for($i = $this->nterminal; $i < $this->nsymbol; $i++) {
+ $this->symbols[$i]->firstset = array();
+ }
+
+ /* First compute all lambdas */
+ do{
+ $progress = 0;
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ if ($rp->lhs->lambda) {
+ continue;
+ }
+ for ($i = 0; $i < $rp->nrhs; $i++) {
+ $sp = $rp->rhs[$i];
+ if ($sp->type != PHP_ParserGenerator_Symbol::TERMINAL || $sp->lambda === false) {
+ break;
+ }
+ }
+ if ($i === $rp->nrhs) {
+ $rp->lhs->lambda = true;
+ $progress = 1;
+ }
+ }
+ } while ($progress);
+
+ /* Now compute all first sets */
+ do {
+ $progress = 0;
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ $s1 = $rp->lhs;
+ for ($i = 0; $i < $rp->nrhs; $i++) {
+ $s2 = $rp->rhs[$i];
+ if ($s2->type == PHP_ParserGenerator_Symbol::TERMINAL) {
+ //progress += SetAdd(s1->firstset,s2->index);
+ $progress += isset($s1->firstset[$s2->index]) ? 0 : 1;
+ $s1->firstset[$s2->index] = 1;
+ break;
+ } elseif ($s2->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ for ($j = 0; $j < $s2->nsubsym; $j++) {
+ //progress += SetAdd(s1->firstset,s2->subsym[j]->index);
+ $progress += isset($s1->firstset[$s2->subsym[$j]->index]) ? 0 : 1;
+ $s1->firstset[$s2->subsym[$j]->index] = 1;
+ }
+ break;
+ } elseif ($s1 === $s2) {
+ if ($s1->lambda === false) {
+ break;
+ }
+ } else {
+ //progress += SetUnion(s1->firstset,s2->firstset);
+ $test = array_diff_key($s2->firstset, $s1->firstset);
+ if (count($test)) {
+ $progress++;
+ $s1->firstset += $test;
+ }
+ if ($s2->lambda === false) {
+ break;
+ }
+ }
+ }
+ }
+ } while ($progress);
+ }
+
+ /**
+ * Compute all LR(0) states for the grammar. Links
+ * are added to between some states so that the LR(1) follow sets
+ * can be computed later.
+ */
+ function FindStates()
+ {
+ PHP_ParserGenerator_Config::Configlist_init();
+
+ /* Find the start symbol */
+ if ($this->start) {
+ $sp = PHP_ParserGenerator_Symbol::Symbol_find($this->start);
+ if ($sp == 0) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0,
+ "The specified start symbol \"%s\" is not " .
+ "in a nonterminal of the grammar. \"%s\" will be used as the start " .
+ "symbol instead.", $this->start, $this->rule->lhs->name);
+ $this->errorcnt++;
+ $sp = $this->rule->lhs;
+ }
+ } else {
+ $sp = $this->rule->lhs;
+ }
+
+ /* Make sure the start symbol doesn't occur on the right-hand side of
+ ** any rule. Report an error if it does. (YACC would generate a new
+ ** start symbol in this case.) */
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ for ($i = 0; $i < $rp->nrhs; $i++) {
+ if ($rp->rhs[$i]->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ foreach ($rp->rhs[$i]->subsym as $subsp) {
+ if ($subsp === $sp) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0,
+ "The start symbol \"%s\" occurs on the " .
+ "right-hand side of a rule. This will result in a parser which " .
+ "does not work properly.", $sp->name);
+ $this->errorcnt++;
+ }
+ }
+ } elseif ($rp->rhs[$i] === $sp) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0,
+ "The start symbol \"%s\" occurs on the " .
+ "right-hand side of a rule. This will result in a parser which " .
+ "does not work properly.", $sp->name);
+ $this->errorcnt++;
+ }
+ }
+ }
+
+ /* The basis configuration set for the first state
+ ** is all rules which have the start symbol as their
+ ** left-hand side */
+ for ($rp = $sp->rule; $rp; $rp = $rp->nextlhs) {
+ $newcfp = PHP_ParserGenerator_Config::Configlist_addbasis($rp, 0);
+ $newcfp->fws[0] = 1;
+ }
+
+ /* Compute the first state. All other states will be
+ ** computed automatically during the computation of the first one.
+ ** The returned pointer to the first state is not used. */
+ $newstp = array();
+ $newstp = $this->getstate();
+ if (is_array($newstp)) {
+ $this->buildshifts($newstp[0]); /* Recursively compute successor states */
+ }
+ }
+
+ /**
+ * @return PHP_ParserGenerator_State
+ */
+ private function getstate()
+ {
+ /* Extract the sorted basis of the new state. The basis was constructed
+ ** by prior calls to "Configlist_addbasis()". */
+ PHP_ParserGenerator_Config::Configlist_sortbasis();
+ $bp = PHP_ParserGenerator_Config::Configlist_basis();
+
+ /* Get a state with the same basis */
+ $stp = PHP_ParserGenerator_State::State_find($bp);
+ if ($stp) {
+ /* A state with the same basis already exists! Copy all the follow-set
+ ** propagation links from the state under construction into the
+ ** preexisting state, then return a pointer to the preexisting state */
+ for($x = $bp, $y = $stp->bp; $x && $y; $x = $x->bp, $y = $y->bp) {
+ PHP_ParserGenerator_PropagationLink::Plink_copy($y->bplp, $x->bplp);
+ PHP_ParserGenerator_PropagationLink::Plink_delete($x->fplp);
+ $x->fplp = $x->bplp = 0;
+ }
+ $cfp = PHP_ParserGenerator_Config::Configlist_return();
+ PHP_ParserGenerator_Config::Configlist_eat($cfp);
+ } else {
+ /* This really is a new state. Construct all the details */
+ PHP_ParserGenerator_Config::Configlist_closure($this); /* Compute the configuration closure */
+ PHP_ParserGenerator_Config::Configlist_sort(); /* Sort the configuration closure */
+ $cfp = PHP_ParserGenerator_Config::Configlist_return(); /* Get a pointer to the config list */
+ $stp = new PHP_ParserGenerator_State; /* A new state structure */
+ $stp->bp = $bp; /* Remember the configuration basis */
+ $stp->cfp = $cfp; /* Remember the configuration closure */
+ $stp->statenum = $this->nstate++; /* Every state gets a sequence number */
+ $stp->ap = 0; /* No actions, yet. */
+ PHP_ParserGenerator_State::State_insert($stp, $stp->bp); /* Add to the state table */
+ // this can't work, recursion is too deep, move it into FindStates()
+ //$this->buildshifts($stp); /* Recursively compute successor states */
+ return array($stp);
+ }
+ return $stp;
+ }
+
+ /**
+ * Construct all successor states to the given state. A "successor"
+ * state is any state which can be reached by a shift action.
+ * @param PHP_ParserGenerator_Data
+ * @param PHP_ParserGenerator_State The state from which successors are computed
+ */
+ private function buildshifts(PHP_ParserGenerator_State $stp)
+ {
+// struct config *cfp; /* For looping thru the config closure of "stp" */
+// struct config *bcfp; /* For the inner loop on config closure of "stp" */
+// struct config *new; /* */
+// struct symbol *sp; /* Symbol following the dot in configuration "cfp" */
+// struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */
+// struct state *newstp; /* A pointer to a successor state */
+
+ /* Each configuration becomes complete after it contibutes to a successor
+ ** state. Initially, all configurations are incomplete */
+ $cfp = $stp->cfp;
+ for ($cfp = $stp->cfp; $cfp; $cfp = $cfp->next) {
+ $cfp->status = PHP_ParserGenerator_Config::INCOMPLETE;
+ }
+
+ /* Loop through all configurations of the state "stp" */
+ for ($cfp = $stp->cfp; $cfp; $cfp = $cfp->next) {
+ if ($cfp->status == PHP_ParserGenerator_Config::COMPLETE) {
+ continue; /* Already used by inner loop */
+ }
+ if ($cfp->dot >= $cfp->rp->nrhs) {
+ continue; /* Can't shift this config */
+ }
+ PHP_ParserGenerator_Config::Configlist_reset(); /* Reset the new config set */
+ $sp = $cfp->rp->rhs[$cfp->dot]; /* Symbol after the dot */
+
+ /* For every configuration in the state "stp" which has the symbol "sp"
+ ** following its dot, add the same configuration to the basis set under
+ ** construction but with the dot shifted one symbol to the right. */
+ $bcfp = $cfp;
+ for ($bcfp = $cfp; $bcfp; $bcfp = $bcfp->next) {
+ if ($bcfp->status == PHP_ParserGenerator_Config::COMPLETE) {
+ continue; /* Already used */
+ }
+ if ($bcfp->dot >= $bcfp->rp->nrhs) {
+ continue; /* Can't shift this one */
+ }
+ $bsp = $bcfp->rp->rhs[$bcfp->dot]; /* Get symbol after dot */
+ if (!PHP_ParserGenerator_Symbol::same_symbol($bsp, $sp)) {
+ continue; /* Must be same as for "cfp" */
+ }
+ $bcfp->status = PHP_ParserGenerator_Config::COMPLETE; /* Mark this config as used */
+ $new = PHP_ParserGenerator_Config::Configlist_addbasis($bcfp->rp, $bcfp->dot + 1);
+ PHP_ParserGenerator_PropagationLink::Plink_add($new->bplp, $bcfp);
+ }
+
+ /* Get a pointer to the state described by the basis configuration set
+ ** constructed in the preceding loop */
+ $newstp = $this->getstate();
+ if (is_array($newstp)) {
+ $this->buildshifts($newstp[0]); /* Recursively compute successor states */
+ $newstp = $newstp[0];
+ }
+
+ /* The state "newstp" is reached from the state "stp" by a shift action
+ ** on the symbol "sp" */
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ for($i = 0; $i < $sp->nsubsym; $i++) {
+ PHP_ParserGenerator_Action::Action_add($stp->ap, PHP_ParserGenerator_Action::SHIFT, $sp->subsym[$i],
+ $newstp);
+ }
+ } else {
+ PHP_ParserGenerator_Action::Action_add($stp->ap, PHP_ParserGenerator_Action::SHIFT, $sp, $newstp);
+ }
+ }
+ }
+
+ /**
+ * Construct the propagation links
+ */
+ function FindLinks()
+ {
+ /* Housekeeping detail:
+ ** Add to every propagate link a pointer back to the state to
+ ** which the link is attached. */
+ foreach ($this->sorted as $info) {
+ $info->key->stp = $info->data;
+ }
+
+ /* Convert all backlinks into forward links. Only the forward
+ ** links are used in the follow-set computation. */
+ for ($i = 0; $i < $this->nstate; $i++) {
+ $stp = $this->sorted[$i];
+ for ($cfp = $stp->data->cfp; $cfp; $cfp = $cfp->next) {
+ for ($plp = $cfp->bplp; $plp; $plp = $plp->next) {
+ $other = $plp->cfp;
+ PHP_ParserGenerator_PropagationLink::Plink_add($other->fplp, $cfp);
+ }
+ }
+ }
+ }
+
+ /**
+ * Compute the reduce actions, and resolve conflicts.
+ */
+ function FindActions()
+ {
+ /* Add all of the reduce actions
+ ** A reduce action is added for each element of the followset of
+ ** a configuration which has its dot at the extreme right.
+ */
+ for ($i = 0; $i < $this->nstate; $i++) { /* Loop over all states */
+ $stp = $this->sorted[$i]->data;
+ for ($cfp = $stp->cfp; $cfp; $cfp = $cfp->next) {
+ /* Loop over all configurations */
+ if ($cfp->rp->nrhs == $cfp->dot) { /* Is dot at extreme right? */
+ for ($j = 0; $j < $this->nterminal; $j++) {
+ if (isset($cfp->fws[$j])) {
+ /* Add a reduce action to the state "stp" which will reduce by the
+ ** rule "cfp->rp" if the lookahead symbol is "$this->symbols[j]" */
+ PHP_ParserGenerator_Action::Action_add($stp->ap, PHP_ParserGenerator_Action::REDUCE,
+ $this->symbols[$j], $cfp->rp);
+ }
+ }
+ }
+ }
+ }
+
+ /* Add the accepting token */
+ if ($this->start instanceof PHP_ParserGenerator_Symbol) {
+ $sp = PHP_ParserGenerator_Symbol::Symbol_find($this->start);
+ if ($sp === 0) {
+ $sp = $this->rule->lhs;
+ }
+ } else {
+ $sp = $this->rule->lhs;
+ }
+ /* Add to the first state (which is always the starting state of the
+ ** finite state machine) an action to ACCEPT if the lookahead is the
+ ** start nonterminal. */
+ PHP_ParserGenerator_Action::Action_add($this->sorted[0]->data->ap, PHP_ParserGenerator_Action::ACCEPT, $sp, 0);
+
+ /* Resolve conflicts */
+ for ($i = 0; $i < $this->nstate; $i++) {
+ // struct action *ap, *nap;
+ // struct state *stp;
+ $stp = $this->sorted[$i]->data;
+ if (!$stp->ap) {
+ throw new Exception('state has no actions associated');
+ }
+ echo 'processing state ' . $stp->statenum . " actions:\n";
+ for ($ap = $stp->ap; $ap !== 0 && $ap->next !== 0; $ap = $ap->next) {
+ echo ' Action ';
+ $ap->display(true);
+ }
+ $stp->ap = PHP_ParserGenerator_Action::Action_sort($stp->ap);
+ for ($ap = $stp->ap; $ap !== 0 && $ap->next !== 0; $ap = $ap->next) {
+ for ($nap = $ap->next; $nap !== 0 && $nap->sp === $ap->sp ; $nap = $nap->next) {
+ /* The two actions "ap" and "nap" have the same lookahead.
+ ** Figure out which one should be used */
+ $this->nconflict += $this->resolve_conflict($ap, $nap, $this->errsym);
+ }
+ }
+ }
+
+ /* Report an error for each rule that can never be reduced. */
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ $rp->canReduce = false;
+ }
+ for ($i = 0; $i < $this->nstate; $i++) {
+ for ($ap = $this->sorted[$i]->data->ap; $ap !== 0; $ap = $ap->next) {
+ if ($ap->type == PHP_ParserGenerator_Action::REDUCE) {
+ $ap->x->canReduce = true;
+ }
+ }
+ }
+ for ($rp = $this->rule; $rp !== 0; $rp = $rp->next) {
+ if ($rp->canReduce) {
+ continue;
+ }
+ PHP_ParserGenerator::ErrorMsg($this->filename, $rp->ruleline, "This rule can not be reduced (is not connected to the start symbol).\n");
+ $this->errorcnt++;
+ }
+ }
+
+ /** Resolve a conflict between the two given actions. If the
+ * conflict can't be resolve, return non-zero.
+ *
+ * NO LONGER TRUE:
+ * To resolve a conflict, first look to see if either action
+ * is on an error rule. In that case, take the action which
+ * is not associated with the error rule. If neither or both
+ * actions are associated with an error rule, then try to
+ * use precedence to resolve the conflict.
+ *
+ * If either action is a SHIFT, then it must be apx. This
+ * function won't work if apx->type==REDUCE and apy->type==SHIFT.
+ * @param PHP_ParserGenerator_Action
+ * @param PHP_ParserGenerator_Action
+ * @param PHP_ParserGenerator_Symbol|null The error symbol (if defined. NULL otherwise)
+ */
+ function resolve_conflict($apx, $apy, $errsym)
+ {
+ $errcnt = 0;
+ if ($apx->sp !== $apy->sp) {
+ throw new Exception('no conflict but resolve_conflict called');
+ }
+ if ($apx->type == PHP_ParserGenerator_Action::SHIFT && $apy->type == PHP_ParserGenerator_Action::REDUCE) {
+ $spx = $apx->sp;
+ $spy = $apy->x->precsym;
+ if ($spy === 0 || $spx->prec < 0 || $spy->prec < 0) {
+ /* Not enough precedence information. */
+ $apy->type = PHP_ParserGenerator_Action::CONFLICT;
+ $errcnt++;
+ } elseif ($spx->prec > $spy->prec) { /* Lower precedence wins */
+ $apy->type = PHP_ParserGenerator_Action::RD_RESOLVED;
+ } elseif ($spx->prec < $spy->prec) {
+ $apx->type = PHP_ParserGenerator_Action::SH_RESOLVED;
+ } elseif ($spx->prec === $spy->prec && $spx->assoc == PHP_ParserGenerator_Symbol::RIGHT) {
+ /* Use operator */
+ $apy->type = PHP_ParserGenerator_Action::RD_RESOLVED; /* associativity */
+ } elseif ($spx->prec === $spy->prec && $spx->assoc == PHP_ParserGenerator_Symbol::LEFT) {
+ /* to break tie */
+ $apx->type = PHP_ParserGenerator_Action::SH_RESOLVED;
+ } else {
+ if ($spx->prec !== $spy->prec || $spx->assoc !== PHP_ParserGenerator_Symbol::NONE) {
+ throw new Exception('$spx->prec !== $spy->prec || $spx->assoc !== PHP_ParserGenerator_Symbol::NONE');
+ }
+ $apy->type = PHP_ParserGenerator_Action::CONFLICT;
+ $errcnt++;
+ }
+ } elseif ($apx->type == PHP_ParserGenerator_Action::REDUCE && $apy->type == PHP_ParserGenerator_Action::REDUCE) {
+ $spx = $apx->x->precsym;
+ $spy = $apy->x->precsym;
+ if ($spx === 0 || $spy === 0 || $spx->prec < 0 ||
+ $spy->prec < 0 || $spx->prec === $spy->prec) {
+ $apy->type = PHP_ParserGenerator_Action::CONFLICT;
+ $errcnt++;
+ } elseif ($spx->prec > $spy->prec) {
+ $apy->type = PHP_ParserGenerator_Action::RD_RESOLVED;
+ } elseif ($spx->prec < $spy->prec) {
+ $apx->type = PHP_ParserGenerator_Action::RD_RESOLVED;
+ }
+ } else {
+ if ($apx->type!== PHP_ParserGenerator_Action::SH_RESOLVED &&
+ $apx->type!== PHP_ParserGenerator_Action::RD_RESOLVED &&
+ $apx->type!== PHP_ParserGenerator_Action::CONFLICT &&
+ $apy->type!== PHP_ParserGenerator_Action::SH_RESOLVED &&
+ $apy->type!== PHP_ParserGenerator_Action::RD_RESOLVED &&
+ $apy->type!== PHP_ParserGenerator_Action::CONFLICT) {
+ throw new Exception('$apx->type!== PHP_ParserGenerator_Action::SH_RESOLVED &&
+ $apx->type!== PHP_ParserGenerator_Action::RD_RESOLVED &&
+ $apx->type!== PHP_ParserGenerator_Action::CONFLICT &&
+ $apy->type!== PHP_ParserGenerator_Action::SH_RESOLVED &&
+ $apy->type!== PHP_ParserGenerator_Action::RD_RESOLVED &&
+ $apy->type!== PHP_ParserGenerator_Action::CONFLICT');
+ }
+ /* The REDUCE/SHIFT case cannot happen because SHIFTs come before
+ ** REDUCEs on the list. If we reach this point it must be because
+ ** the parser conflict had already been resolved. */
+ }
+ return $errcnt;
+ }
+
+ /**
+ * Reduce the size of the action tables, if possible, by making use
+ * of defaults.
+ *
+ * In this version, we take the most frequent REDUCE action and make
+ * it the default.
+ */
+ function CompressTables()
+ {
+ for ($i = 0; $i < $this->nstate; $i++) {
+ $stp = $this->sorted[$i]->data;
+ $nbest = 0;
+ $rbest = 0;
+
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
+ if ($ap->type != PHP_ParserGenerator_Action::REDUCE) {
+ continue;
+ }
+ $rp = $ap->x;
+ if ($rp === $rbest) {
+ continue;
+ }
+ $n = 1;
+ for ($ap2 = $ap->next; $ap2; $ap2 = $ap2->next) {
+ if ($ap2->type != PHP_ParserGenerator_Action::REDUCE) {
+ continue;
+ }
+ $rp2 = $ap2->x;
+ if ($rp2 === $rbest) {
+ continue;
+ }
+ if ($rp2 === $rp) {
+ $n++;
+ }
+ }
+ if ($n > $nbest) {
+ $nbest = $n;
+ $rbest = $rp;
+ }
+ }
+
+ /* Do not make a default if the number of rules to default
+ ** is not at least 1 */
+ if ($nbest < 1) {
+ continue;
+ }
+
+
+ /* Combine matching REDUCE actions into a single default */
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
+ if ($ap->type == PHP_ParserGenerator_Action::REDUCE && $ap->x === $rbest) {
+ break;
+ }
+ }
+ if ($ap === 0) {
+ throw new Exception('$ap is not an object');
+ }
+ $ap->sp = PHP_ParserGenerator_Symbol::Symbol_new("{default}");
+ for ($ap = $ap->next; $ap; $ap = $ap->next) {
+ if ($ap->type == PHP_ParserGenerator_Action::REDUCE && $ap->x === $rbest) {
+ $ap->type = PHP_ParserGenerator_Action::NOT_USED;
+ }
+ }
+ $stp->ap = PHP_ParserGenerator_Action::Action_sort($stp->ap);
+ }
+ }
+
+ /**
+ * Renumber and resort states so that states with fewer choices
+ * occur at the end. Except, keep state 0 as the first state.
+ */
+ function ResortStates()
+ {
+ for ($i = 0; $i < $this->nstate; $i++) {
+ $stp = $this->sorted[$i]->data;
+ $stp->nTknAct = $stp->nNtAct = 0;
+ $stp->iDflt = $this->nstate + $this->nrule;
+ $stp->iTknOfst = PHP_ParserGenerator_Data::NO_OFFSET;
+ $stp->iNtOfst = PHP_ParserGenerator_Data::NO_OFFSET;
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
+ if ($this->compute_action($ap) >= 0) {
+ if ($ap->sp->index < $this->nterminal) {
+ $stp->nTknAct++;
+ } elseif ($ap->sp->index < $this->nsymbol) {
+ $stp->nNtAct++;
+ } else {
+ $stp->iDflt = $this->compute_action($ap);
+ }
+ }
+ }
+ $this->sorted[$i] = $stp;
+ }
+ $save = $this->sorted[0];
+ unset($this->sorted[0]);
+ usort($this->sorted, array('PHP_ParserGenerator_State', 'stateResortCompare'));
+ array_unshift($this->sorted, $save);
+ for($i = 0; $i < $this->nstate; $i++) {
+ $this->sorted[$i]->statenum = $i;
+ }
+ }
+
+ /**
+ * Given an action, compute the integer value for that action
+ * which is to be put in the action table of the generated machine.
+ * Return negative if no action should be generated.
+ * @param PHP_ParserGenerator_Action
+ */
+ function compute_action($ap)
+ {
+ switch ($ap->type) {
+ case PHP_ParserGenerator_Action::SHIFT:
+ $act = $ap->x->statenum;
+ break;
+ case PHP_ParserGenerator_Action::REDUCE:
+ $act = $ap->x->index + $this->nstate;
+ break;
+ case PHP_ParserGenerator_Action::ERROR:
+ $act = $this->nstate + $this->nrule;
+ break;
+ case PHP_ParserGenerator_Action::ACCEPT:
+ $act = $this->nstate + $this->nrule + 1;
+ break;
+ default:
+ $act = -1;
+ break;
+ }
+ return $act;
+ }
+
+ /**
+ * Generate the "Parse.out" log file
+ */
+ function ReportOutput()
+ {
+ $fp = fopen($this->filenosuffix . ".out", "wb");
+ if (!$fp) {
+ return;
+ }
+ for ($i = 0; $i < $this->nstate; $i++) {
+ $stp = $this->sorted[$i];
+ fprintf($fp, "State %d:\n", $stp->statenum);
+ if ($this->basisflag) {
+ $cfp = $stp->bp;
+ } else {
+ $cfp = $stp->cfp;
+ }
+ while ($cfp) {
+ if ($cfp->dot == $cfp->rp->nrhs) {
+ $buf = sprintf('(%d)', $cfp->rp->index);
+ fprintf($fp, ' %5s ', $buf);
+ } else {
+ fwrite($fp,' ');
+ }
+ $cfp->ConfigPrint($fp);
+ fwrite($fp, "\n");
+ if (0) {
+ //SetPrint(fp,cfp->fws,$this);
+ //PlinkPrint(fp,cfp->fplp,"To ");
+ //PlinkPrint(fp,cfp->bplp,"From");
+ }
+ if ($this->basisflag) {
+ $cfp = $cfp->bp;
+ } else {
+ $cfp = $cfp->next;
+ }
+ }
+ fwrite($fp, "\n");
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
+ if ($ap->PrintAction($fp, 30)) {
+ fprintf($fp,"\n");
+ }
+ }
+ fwrite($fp,"\n");
+ }
+ fclose($fp);
+ }
+
+ /**
+ * The next function finds the template file and opens it, returning
+ * a pointer to the opened file.
+ * @return resource
+ */
+ private function tplt_open()
+ {
+ $templatename = $this->parser_template ? $this->parser_template : dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "Lempar.php";
+
+ $buf = $this->filenosuffix . '.lt';
+ if (file_exists($buf) && is_readable($buf)) {
+ $tpltname = $buf;
+ } elseif (file_exists($templatename) && is_readable($templatename)) {
+ $tpltname = $templatename;
+ } elseif ($fp = @fopen($templatename, 'rb', true)) {
+ return $fp;
+ }
+ if (!isset($tpltname)) {
+ echo "Can't find the parser driver template file \"%s\".\n",
+ $templatename;
+ $this->errorcnt++;
+ return 0;
+ }
+ $in = @fopen($tpltname,"rb");
+ if (!$in) {
+ printf("Can't open the template file \"%s\".\n", $tpltname);
+ $this->errorcnt++;
+ return 0;
+ }
+ return $in;
+ }
+
+#define LINESIZE 1000
+ /**#@+
+ * The next cluster of routines are for reading the template file
+ * and writing the results to the generated parser
+ */
+ /**
+ * The first function transfers data from "in" to "out" until
+ * a line is seen which begins with "%%". The line number is
+ * tracked.
+ *
+ * if name!=0, then any word that begin with "Parse" is changed to
+ * begin with *name instead.
+ */
+ private function tplt_xfer($name, $in, $out, &$lineno)
+ {
+ while (($line = fgets($in, 1024)) && ($line[0] != '%' || $line[1] != '%')) {
+ $lineno++;
+ $iStart = 0;
+ if ($name) {
+ for ($i = 0; $i < strlen($line); $i++) {
+ if ($line[$i] == 'P' && substr($line, $i, 5) == "Parse"
+ && ($i === 0 || preg_match('/[^a-zA-Z]/', $line[$i - 1]))) {
+ if ($i > $iStart) {
+ fwrite($out, substr($line, $iStart, $i - $iStart));
+ }
+ fwrite($out, $name);
+ $i += 4;
+ $iStart = $i + 1;
+ }
+ }
+ }
+ fwrite($out, substr($line, $iStart));
+ }
+ }
+
+ /**
+ * Print a #line directive line to the output file.
+ */
+ private function tplt_linedir($out, $lineno, $filename)
+ {
+ fwrite($out, '#line ' . $lineno . ' "' . $filename . "\"\n");
+ }
+
+ /**
+ * Print a string to the file and keep the linenumber up to date
+ */
+ private function tplt_print($out, $str, $strln, &$lineno)
+ {
+ if ($str == '') {
+ return;
+ }
+ $this->tplt_linedir($out, $strln, $this->filename);
+ $lineno++;
+ fwrite($out, $str);
+ $lineno += count(explode("\n", $str)) - 1;
+ $this->tplt_linedir($out, $lineno + 2, $this->outname);
+ $lineno += 2;
+ }
+ /**#@-*/
+
+ /**
+ * Compute all followsets.
+ *
+ * A followset is the set of all symbols which can come immediately
+ * after a configuration.
+ */
+ function FindFollowSets()
+ {
+ for ($i = 0; $i < $this->nstate; $i++) {
+ for ($cfp = $this->sorted[$i]->data->cfp; $cfp; $cfp = $cfp->next) {
+ $cfp->status = PHP_ParserGenerator_Config::INCOMPLETE;
+ }
+ }
+
+ do {
+ $progress = 0;
+ for ($i = 0; $i < $this->nstate; $i++) {
+ for ($cfp = $this->sorted[$i]->data->cfp; $cfp; $cfp = $cfp->next) {
+ if ($cfp->status == PHP_ParserGenerator_Config::COMPLETE) {
+ continue;
+ }
+ for ($plp = $cfp->fplp; $plp; $plp = $plp->next) {
+ $a = array_diff_key($cfp->fws, $plp->cfp->fws);
+ if (count($a)) {
+ $plp->cfp->fws += $a;
+ $plp->cfp->status = PHP_ParserGenerator_Config::INCOMPLETE;
+ $progress = 1;
+ }
+ }
+ $cfp->status = PHP_ParserGenerator_Config::COMPLETE;
+ }
+ }
+ } while ($progress);
+ }
+
+ /**
+ * Generate C source code for the parser
+ * @param int Output in makeheaders format if true
+ */
+ function ReportTable($mhflag)
+ {
+// FILE *out, *in;
+// char line[LINESIZE];
+// int lineno;
+// struct state *stp;
+// struct action *ap;
+// struct rule *rp;
+// struct acttab *pActtab;
+// int i, j, n;
+// char *name;
+// int mnTknOfst, mxTknOfst;
+// int mnNtOfst, mxNtOfst;
+// struct axset *ax;
+
+ $in = $this->tplt_open();
+ if (!$in) {
+ return;
+ }
+ $out = fopen($this->filenosuffix . ".php", "wb");
+ if (!$out) {
+ fclose($in);
+ return;
+ }
+ $this->outname = $this->filenosuffix . ".php";
+ $lineno = 1;
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate the include code, if any */
+ $this->tplt_print($out, $this->include_code, $this->includeln, $lineno);
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate the class declaration code */
+ $this->tplt_print($out, $this->declare_classcode, $this->declare_classln,
+ $lineno);
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate the internal parser class include code, if any */
+ $this->tplt_print($out, $this->include_classcode, $this->include_classln,
+ $lineno);
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate #defines for all tokens */
+ //if ($mhflag) {
+ //fprintf($out, "#if INTERFACE\n");
+ $lineno++;
+ if ($this->tokenprefix) {
+ $prefix = $this->tokenprefix;
+ } else {
+ $prefix = '';
+ }
+ for ($i = 1; $i < $this->nterminal; $i++) {
+ fprintf($out, " const %s%-30s = %2d;\n", $prefix, $this->symbols[$i]->name, $i);
+ $lineno++;
+ }
+ //fwrite($out, "#endif\n");
+ $lineno++;
+ //}
+ fwrite($out, " const YY_NO_ACTION = " .
+ ($this->nstate + $this->nrule + 2) . ";\n");
+ $lineno++;
+ fwrite($out, " const YY_ACCEPT_ACTION = " .
+ ($this->nstate + $this->nrule + 1) . ";\n");
+ $lineno++;
+ fwrite($out, " const YY_ERROR_ACTION = " .
+ ($this->nstate + $this->nrule) . ";\n");
+ $lineno++;
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate the action table and its associates:
+ **
+ ** yy_action[] A single table containing all actions.
+ ** yy_lookahead[] A table containing the lookahead for each entry in
+ ** yy_action. Used to detect hash collisions.
+ ** yy_shift_ofst[] For each state, the offset into yy_action for
+ ** shifting terminals.
+ ** yy_reduce_ofst[] For each state, the offset into yy_action for
+ ** shifting non-terminals after a reduce.
+ ** yy_default[] Default action for each state.
+ */
+
+ /* Compute the actions on all states and count them up */
+
+ $ax = array();
+ for ($i = 0; $i < $this->nstate; $i++) {
+ $stp = $this->sorted[$i];
+ $ax[$i * 2] = array();
+ $ax[$i * 2]['stp'] = $stp;
+ $ax[$i * 2]['isTkn'] = 1;
+ $ax[$i * 2]['nAction'] = $stp->nTknAct;
+ $ax[$i * 2 + 1] = array();
+ $ax[$i * 2 + 1]['stp'] = $stp;
+ $ax[$i * 2 + 1]['isTkn'] = 0;
+ $ax[$i * 2 + 1]['nAction'] = $stp->nNtAct;
+ }
+ $mxTknOfst = $mnTknOfst = 0;
+ $mxNtOfst = $mnNtOfst = 0;
+
+ /* Compute the action table. In order to try to keep the size of the
+ ** action table to a minimum, the heuristic of placing the largest action
+ ** sets first is used.
+ */
+
+ usort($ax, array('PHP_ParserGenerator_Data', 'axset_compare'));
+ $pActtab = new PHP_ParserGenerator_ActionTable;
+ for ($i = 0; $i < $this->nstate * 2 && $ax[$i]['nAction'] > 0; $i++) {
+ $stp = $ax[$i]['stp'];
+ if ($ax[$i]['isTkn']) {
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
+ if ($ap->sp->index >= $this->nterminal) {
+ continue;
+ }
+ $action = $this->compute_action($ap);
+ if ($action < 0) {
+ continue;
+ }
+ $pActtab->acttab_action($ap->sp->index, $action);
+ }
+ $stp->iTknOfst = $pActtab->acttab_insert();
+ if ($stp->iTknOfst < $mnTknOfst) {
+ $mnTknOfst = $stp->iTknOfst;
+ }
+ if ($stp->iTknOfst > $mxTknOfst) {
+ $mxTknOfst = $stp->iTknOfst;
+ }
+ } else {
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
+ if ($ap->sp->index < $this->nterminal) {
+ continue;
+ }
+ if ($ap->sp->index == $this->nsymbol) {
+ continue;
+ }
+ $action = $this->compute_action($ap);
+ if ($action < 0) {
+ continue;
+ }
+ $pActtab->acttab_action($ap->sp->index, $action);
+ }
+ $stp->iNtOfst = $pActtab->acttab_insert();
+ if ($stp->iNtOfst < $mnNtOfst) {
+ $mnNtOfst = $stp->iNtOfst;
+ }
+ if ($stp->iNtOfst > $mxNtOfst) {
+ $mxNtOfst = $stp->iNtOfst;
+ }
+ }
+ }
+ /* Output the yy_action table */
+
+ fprintf($out, " const YY_SZ_ACTTAB = %d;\n", $pActtab->nAction);
+ $lineno++;
+ fwrite($out, "static public \$yy_action = array(\n");
+ $lineno++;
+ $n = $pActtab->nAction;
+ for($i = $j = 0; $i < $n; $i++) {
+ $action = $pActtab->aAction[$i]['action'];
+ if ($action < 0) {
+ $action = $this->nsymbol + $this->nrule + 2;
+ }
+ // change next line
+ if ($j === 0) {
+ fprintf($out, " /* %5d */ ", $i);
+ }
+ fprintf($out, " %4d,", $action);
+ if ($j == 9 || $i == $n - 1) {
+ fwrite($out, "\n");
+ $lineno++;
+ $j = 0;
+ } else {
+ $j++;
+ }
+ }
+ fwrite($out, " );\n"); $lineno++;
+
+ /* Output the yy_lookahead table */
+
+ fwrite($out, " static public \$yy_lookahead = array(\n");
+ $lineno++;
+ for ($i = $j = 0; $i < $n; $i++) {
+ $la = $pActtab->aAction[$i]['lookahead'];
+ if ($la < 0) {
+ $la = $this->nsymbol;
+ }
+ // change next line
+ if ($j === 0) {
+ fprintf($out, " /* %5d */ ", $i);
+ }
+ fprintf($out, " %4d,", $la);
+ if ($j == 9 || $i == $n - 1) {
+ fwrite($out, "\n");
+ $lineno++;
+ $j = 0;
+ } else {
+ $j++;
+ }
+ }
+ fwrite($out, ");\n");
+ $lineno++;
+
+ /* Output the yy_shift_ofst[] table */
+ fprintf($out, " const YY_SHIFT_USE_DFLT = %d;\n", $mnTknOfst - 1);
+ $lineno++;
+ $n = $this->nstate;
+ while ($n > 0 && $this->sorted[$n - 1]->iTknOfst == PHP_ParserGenerator_Data::NO_OFFSET) {
+ $n--;
+ }
+ fprintf($out, " const YY_SHIFT_MAX = %d;\n", $n - 1);
+ $lineno++;
+ fwrite($out, " static public \$yy_shift_ofst = array(\n");
+ $lineno++;
+ for ($i = $j = 0; $i < $n; $i++) {
+ $stp = $this->sorted[$i];
+ $ofst = $stp->iTknOfst;
+ if ($ofst === PHP_ParserGenerator_Data::NO_OFFSET) {
+ $ofst = $mnTknOfst - 1;
+ }
+ // change next line
+ if ($j === 0) {
+ fprintf($out, " /* %5d */ ", $i);
+ }
+ fprintf($out, " %4d,", $ofst);
+ if ($j == 9 || $i == $n - 1) {
+ fwrite($out, "\n");
+ $lineno++;
+ $j = 0;
+ } else {
+ $j++;
+ }
+ }
+ fwrite($out, ");\n");
+ $lineno++;
+
+
+ /* Output the yy_reduce_ofst[] table */
+
+ fprintf($out, " const YY_REDUCE_USE_DFLT = %d;\n", $mnNtOfst - 1);
+ $lineno++;
+ $n = $this->nstate;
+ while ($n > 0 && $this->sorted[$n - 1]->iNtOfst == PHP_ParserGenerator_Data::NO_OFFSET) {
+ $n--;
+ }
+ fprintf($out, " const YY_REDUCE_MAX = %d;\n", $n - 1);
+ $lineno++;
+ fwrite($out, " static public \$yy_reduce_ofst = array(\n");
+ $lineno++;
+ for ($i = $j = 0; $i < $n; $i++) {
+ $stp = $this->sorted[$i];
+ $ofst = $stp->iNtOfst;
+ if ($ofst == PHP_ParserGenerator_Data::NO_OFFSET) {
+ $ofst = $mnNtOfst - 1;
+ }
+ // change next line
+ if ($j == 0) {
+ fprintf($out, " /* %5d */ ", $i);
+ }
+ fprintf($out, " %4d,", $ofst);
+ if ($j == 9 || $i == $n - 1) {
+ fwrite($out, "\n");
+ $lineno++;
+ $j = 0;
+ } else {
+ $j++;
+ }
+ }
+ fwrite($out, ");\n");
+ $lineno++;
+
+ /* Output the expected tokens table */
+
+ fwrite($out, " static public \$yyExpectedTokens = array(\n");
+ $lineno++;
+ for ($i = 0; $i < $this->nstate; $i++) {
+ $stp = $this->sorted[$i];
+ fwrite($out, " /* $i */ array(");
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
+ if ($ap->sp->index < $this->nterminal) {
+ if ($ap->type == PHP_ParserGenerator_Action::SHIFT ||
+ $ap->type == PHP_ParserGenerator_Action::REDUCE) {
+ fwrite($out, $ap->sp->index . ', ');
+ }
+ }
+ }
+ fwrite($out, "),\n");
+ $lineno++;
+ }
+ fwrite($out, ");\n");
+ $lineno++;
+
+ /* Output the default action table */
+
+ fwrite($out, " static public \$yy_default = array(\n");
+ $lineno++;
+ $n = $this->nstate;
+ for ($i = $j = 0; $i < $n; $i++) {
+ $stp = $this->sorted[$i];
+ // change next line
+ if ($j == 0) {
+ fprintf($out, " /* %5d */ ", $i);
+ }
+ fprintf($out, " %4d,", $stp->iDflt);
+ if ($j == 9 || $i == $n - 1) {
+ fprintf($out, "\n"); $lineno++;
+ $j = 0;
+ } else {
+ $j++;
+ }
+ }
+ fwrite($out, ");\n");
+ $lineno++;
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate the defines */
+ fprintf($out, " const YYNOCODE = %d;\n", $this->nsymbol + 1);
+ $lineno++;
+ if ($this->stacksize) {
+ if($this->stacksize <= 0) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0,
+ "Illegal stack size: [%s]. The stack size should be an integer constant.",
+ $this->stacksize);
+ $this->errorcnt++;
+ $this->stacksize = "100";
+ }
+ fprintf($out, " const YYSTACKDEPTH = %s;\n", $this->stacksize);
+ $lineno++;
+ } else {
+ fwrite($out," const YYSTACKDEPTH = 100;\n");
+ $lineno++;
+ }
+ fprintf($out, " const YYNSTATE = %d;\n", $this->nstate);
+ $lineno++;
+ fprintf($out, " const YYNRULE = %d;\n", $this->nrule);
+ $lineno++;
+ fprintf($out, " const YYERRORSYMBOL = %d;\n", $this->errsym->index);
+ $lineno++;
+ fprintf($out, " const YYERRSYMDT = 'yy%d';\n", $this->errsym->dtnum);
+ $lineno++;
+ if ($this->has_fallback) {
+ fwrite($out, " const YYFALLBACK = 1;\n");
+ } else {
+ fwrite($out, " const YYFALLBACK = 0;\n");
+ }
+ $lineno++;
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate the table of fallback tokens.
+ */
+
+ if ($this->has_fallback) {
+ for ($i = 0; $i < $this->nterminal; $i++) {
+ $p = $this->symbols[$i];
+ if ($p->fallback === 0) {
+ // change next line
+ fprintf($out, " 0, /* %10s => nothing */\n", $p->name);
+ } else {
+ // change next line
+ fprintf($out, " %3d, /* %10s => %s */\n",
+ $p->fallback->index, $p->name, $p->fallback->name);
+ }
+ $lineno++;
+ }
+ }
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+
+ /* Generate a table containing the symbolic name of every symbol
+ ($yyTokenName)
+ */
+
+ for ($i = 0; $i < $this->nsymbol; $i++) {
+ fprintf($out," %-15s", "'" . $this->symbols[$i]->name . "',");
+ if (($i & 3) == 3) {
+ fwrite($out,"\n");
+ $lineno++;
+ }
+ }
+ if (($i & 3) != 0) {
+ fwrite($out, "\n");
+ $lineno++;
+ }
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate a table containing a text string that describes every
+ ** rule in the rule set of the grammer. This information is used
+ ** when tracing REDUCE actions.
+ */
+
+ for ($i = 0, $rp = $this->rule; $rp; $rp = $rp->next, $i++) {
+ if ($rp->index !== $i) {
+ throw new Exception('rp->index != i and should be');
+ }
+ // change next line
+ fprintf($out, " /* %3d */ \"%s ::=", $i, $rp->lhs->name);
+ for ($j = 0; $j < $rp->nrhs; $j++) {
+ $sp = $rp->rhs[$j];
+ fwrite($out,' ' . $sp->name);
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ for($k = 1; $k < $sp->nsubsym; $k++) {
+ fwrite($out, '|' . $sp->subsym[$k]->name);
+ }
+ }
+ }
+ fwrite($out, "\",\n");
+ $lineno++;
+ }
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate code which executes every time a symbol is popped from
+ ** the stack while processing errors or while destroying the parser.
+ ** (In other words, generate the %destructor actions)
+ */
+
+ if ($this->tokendest) {
+ for ($i = 0; $i < $this->nsymbol; $i++) {
+ $sp = $this->symbols[$i];
+ if ($sp === 0 || $sp->type != PHP_ParserGenerator_Symbol::TERMINAL) {
+ continue;
+ }
+ fprintf($out, " case %d:\n", $sp->index);
+ $lineno++;
+ }
+ for ($i = 0; $i < $this->nsymbol &&
+ $this->symbols[$i]->type != PHP_ParserGenerator_Symbol::TERMINAL; $i++);
+ if ($i < $this->nsymbol) {
+ $this->emit_destructor_code($out, $this->symbols[$i], $lineno);
+ fprintf($out, " break;\n");
+ $lineno++;
+ }
+ }
+ if ($this->vardest) {
+ $dflt_sp = 0;
+ for ($i = 0; $i < $this->nsymbol; $i++) {
+ $sp = $this->symbols[$i];
+ if ($sp === 0 || $sp->type == PHP_ParserGenerator_Symbol::TERMINAL ||
+ $sp->index <= 0 || $sp->destructor != 0) {
+ continue;
+ }
+ fprintf($out, " case %d:\n", $sp->index);
+ $lineno++;
+ $dflt_sp = $sp;
+ }
+ if ($dflt_sp != 0) {
+ $this->emit_destructor_code($out, $dflt_sp, $lineno);
+ fwrite($out, " break;\n");
+ $lineno++;
+ }
+ }
+ for ($i = 0; $i < $this->nsymbol; $i++) {
+ $sp = $this->symbols[$i];
+ if ($sp === 0 || $sp->type == PHP_ParserGenerator_Symbol::TERMINAL ||
+ $sp->destructor === 0) {
+ continue;
+ }
+ fprintf($out, " case %d:\n", $sp->index);
+ $lineno++;
+
+ /* Combine duplicate destructors into a single case */
+
+ for ($j = $i + 1; $j < $this->nsymbol; $j++) {
+ $sp2 = $this->symbols[$j];
+ if ($sp2 && $sp2->type != PHP_ParserGenerator_Symbol::TERMINAL && $sp2->destructor
+ && $sp2->dtnum == $sp->dtnum
+ && $sp->destructor == $sp2->destructor) {
+ fprintf($out, " case %d:\n", $sp2->index);
+ $lineno++;
+ $sp2->destructor = 0;
+ }
+ }
+
+ $this->emit_destructor_code($out, $this->symbols[$i], $lineno);
+ fprintf($out, " break;\n");
+ $lineno++;
+ }
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate code which executes whenever the parser stack overflows */
+
+ $this->tplt_print($out, $this->overflow, $this->overflowln, $lineno);
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate the table of rule information
+ **
+ ** Note: This code depends on the fact that rules are number
+ ** sequentually beginning with 0.
+ */
+
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ fprintf($out, " array( 'lhs' => %d, 'rhs' => %d ),\n",
+ $rp->lhs->index, $rp->nrhs);
+ $lineno++;
+ }
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+
+ /* Generate code which executes during each REDUCE action */
+
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ if ($rp->code) {
+ $this->translate_code($rp);
+ }
+ }
+
+ /* Generate the method map for each REDUCE action */
+
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ if ($rp->code === 0) {
+ continue;
+ }
+ fwrite($out, ' ' . $rp->index . ' => ' . $rp->index . ",\n");
+ $lineno++;
+ for ($rp2 = $rp->next; $rp2; $rp2 = $rp2->next) {
+ if ($rp2->code === $rp->code) {
+ fwrite($out, ' ' . $rp2->index . ' => ' .
+ $rp->index . ",\n");
+ $lineno++;
+ $rp2->code = 0;
+ }
+ }
+ }
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
+ if ($rp->code === 0) {
+ continue;
+ }
+ $this->emit_code($out, $rp, $lineno);
+ }
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+
+ /* Generate code which executes if a parse fails */
+
+ $this->tplt_print($out, $this->failure, $this->failureln, $lineno);
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate code which executes when a syntax error occurs */
+
+ $this->tplt_print($out, $this->error, $this->errorln, $lineno);
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Generate code which executes when the parser accepts its input */
+
+ $this->tplt_print($out, $this->accept, $this->acceptln, $lineno);
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
+
+ /* Append any addition code the user desires */
+
+ $this->tplt_print($out, $this->extracode, $this->extracodeln, $lineno);
+
+ fclose($in);
+ fclose($out);
+ }
+
+ /**
+ * Generate code which executes when the rule "rp" is reduced. Write
+ * the code to "out". Make sure lineno stays up-to-date.
+ */
+ function emit_code($out, PHP_ParserGenerator_Rule $rp, &$lineno)
+ {
+ $linecnt = 0;
+
+ /* Generate code to do the reduce action */
+ if ($rp->code) {
+ $this->tplt_linedir($out, $rp->line, $this->filename);
+ fwrite($out, " function yy_r$rp->index(){" . $rp->code);
+ $linecnt += count(explode("\n", $rp->code)) - 1;
+ $lineno += 3 + $linecnt;
+ fwrite($out, " }\n");
+ $this->tplt_linedir($out, $lineno, $this->outname);
+ } /* End if( rp->code ) */
+ }
+
+ /**
+ * Append text to a dynamically allocated string. If zText is 0 then
+ * reset the string to be empty again. Always return the complete text
+ * of the string (which is overwritten with each call).
+ *
+ * n bytes of zText are stored. If n==0 then all of zText is stored.
+ *
+ * If n==-1, then the previous character is overwritten.
+ * @param string
+ * @param int
+ */
+ function append_str($zText, $n)
+ {
+ static $z = '';
+ $zInt = '';
+
+ if ($zText === '') {
+ $ret = $z;
+ $z = '';
+ return $ret;
+ }
+ if ($n <= 0) {
+ if ($n < 0) {
+ if (!strlen($z)) {
+ throw new Exception('z is zero-length');
+ }
+ $z = substr($z, 0, strlen($z) - 1);
+ if (!$z) {
+ $z = '';
+ }
+ }
+ $n = strlen($zText);
+ }
+ $i = 0;
+ $z .= substr($zText, 0, $n);
+ return $z;
+ }
+
+ /**
+ * zCode is a string that is the action associated with a rule. Expand
+ * the symbols in this string so that the refer to elements of the parser
+ * stack.
+ */
+ function translate_code(PHP_ParserGenerator_Rule $rp)
+ {
+ $lhsused = 0; /* True if the LHS element has been used */
+ $used = array(); /* True for each RHS element which is used */
+
+ $this->append_str('', 0);
+ for ($i = 0; $i < strlen($rp->code); $i++) {
+ $cp = $rp->code[$i];
+ if (preg_match('/[A-Za-z]/', $cp) &&
+ ($i === 0 || (!preg_match('/[A-Za-z0-9_]/', $rp->code[$i - 1])))) {
+ //*xp = 0;
+ // previous line is in essence a temporary substr, so
+ // we will simulate it
+ $test = substr($rp->code, $i);
+ preg_match('/[A-Za-z0-9_]+/', $test, $matches);
+ $tempcp = $matches[0];
+ $j = strlen($tempcp) + $i;
+ if ($rp->lhsalias && $tempcp == $rp->lhsalias) {
+ $this->append_str("\$this->_retvalue", 0);
+ $cp = $rp->code[$j];
+ $i = $j;
+ $lhsused = 1;
+ } else {
+ for ($ii = 0; $ii < $rp->nrhs; $ii++) {
+ if ($rp->rhsalias[$ii] && $tempcp == $rp->rhsalias[$ii]) {
+ if ($rp->code[0] == '@') {
+ /* If the argument is of the form @X then substitute
+ ** the token number of X, not the value of X */
+ $this->append_str("\$this->yystack[\$this->yyidx + " .
+ ($ii - $rp->nrhs + 1) . "]->major", -1);
+ } else {
+ $sp = $rp->rhs[$ii];
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ $dtnum = $sp->subsym[0]->dtnum;
+ } else {
+ $dtnum = $sp->dtnum;
+ }
+ $this->append_str("\$this->yystack[\$this->yyidx + " .
+ ($ii - $rp->nrhs + 1) . "]->minor", 0);
+ }
+ $cp = $rp->code[$j];
+ $i = $j;
+ $used[$ii] = 1;
+ break;
+ }
+ }
+ }
+ }
+ $this->append_str($cp, 1);
+ } /* End loop */
+
+ /* Check to make sure the LHS has been used */
+ if ($rp->lhsalias && !$lhsused) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $rp->ruleline,
+ "Label \"%s\" for \"%s(%s)\" is never used.",
+ $rp->lhsalias, $rp->lhs->name, $rp->lhsalias);
+ $this->errorcnt++;
+ }
+
+ /* Generate destructor code for RHS symbols which are not used in the
+ ** reduce code */
+ for($i = 0; $i < $rp->nrhs; $i++) {
+ if ($rp->rhsalias[$i] && !isset($used[$i])) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $rp->ruleline,
+ "Label %s for \"%s(%s)\" is never used.",
+ $rp->rhsalias[$i], $rp->rhs[$i]->name, $rp->rhsalias[$i]);
+ $this->errorcnt++;
+ } elseif ($rp->rhsalias[$i] == 0) {
+ if ($rp->rhs[$i]->type == PHP_ParserGenerator_Symbol::TERMINAL) {
+ $hasdestructor = $this->tokendest != 0;
+ }else{
+ $hasdestructor = $this->vardest !== 0 || $rp->rhs[$i]->destructor !== 0;
+ }
+ if ($hasdestructor) {
+ $this->append_str(" \$this->yy_destructor(" .
+ ($rp->rhs[$i]->index) . ", \$this->yystack[\$this->yyidx + " .
+ ($i - $rp->nrhs + 1) . "]->minor);\n", 0);
+ } else {
+ /* No destructor defined for this term */
+ }
+ }
+ }
+ $cp = $this->append_str('', 0);
+ $rp->code = $cp;
+ }
+
+ /**
+ * The following routine emits code for the destructor for the
+ * symbol sp
+ */
+ function emit_destructor_code($out, PHP_ParserGenerator_Symbol $sp, &$lineno)
+// FILE *out;
+// struct symbol *sp;
+// struct lemon *lemp;
+// int *lineno;
+ {
+ $cp = 0;
+
+ $linecnt = 0;
+ if ($sp->type == PHP_ParserGenerator_Symbol::TERMINAL) {
+ $cp = $this->tokendest;
+ if ($cp === 0) {
+ return;
+ }
+ $this->tplt_linedir($out, $this->tokendestln, $this->filename);
+ fwrite($out, "{");
+ } elseif ($sp->destructor) {
+ $cp = $sp->destructor;
+ $this->tplt_linedir($out, $sp->destructorln, $this->filename);
+ fwrite($out, "{");
+ } elseif ($this->vardest) {
+ $cp = $this->vardest;
+ if ($cp === 0) {
+ return;
+ }
+ $this->tplt_linedir($out, $this->vardestln, $this->filename);
+ fwrite($out, "{");
+ } else {
+ throw new Exception('emit_destructor'); /* Cannot happen */
+ }
+ for ($i = 0; $i < strlen($cp); $i++) {
+ if ($cp[$i]=='$' && $cp[$i + 1]=='$' ) {
+ fprintf($out, "(yypminor->yy%d)", $sp->dtnum);
+ $i++;
+ continue;
+ }
+ if ($cp[$i] == "\n") {
+ $linecnt++;
+ }
+ fwrite($out, $cp[$i]);
+ }
+ $lineno += 3 + $linecnt;
+ fwrite($out, "}\n");
+ $this->tplt_linedir($out, $lineno, $this->outname);
+ }
+
+ /**
+ * Compare to axset structures for sorting purposes
+ */
+ static function axset_compare($a, $b)
+ {
+ return $b['nAction'] - $a['nAction'];
+ }
+}
diff --git a/core/oql/build/PHP/ParserGenerator/Parser.php b/core/oql/build/PHP/ParserGenerator/Parser.php
new file mode 100644
index 000000000..c777aad88
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/Parser.php
@@ -0,0 +1,851 @@
+
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id: Parser.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+/**
+ * The grammar parser for lemon grammar files.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+class PHP_ParserGenerator_Parser
+{
+ const INITIALIZE = 1;
+ const WAITING_FOR_DECL_OR_RULE = 2;
+ const WAITING_FOR_DECL_KEYWORD = 3;
+ const WAITING_FOR_DECL_ARG = 4;
+ const WAITING_FOR_PRECEDENCE_SYMBOL = 5;
+ const WAITING_FOR_ARROW = 6;
+ const IN_RHS = 7;
+ const LHS_ALIAS_1 = 8;
+ const LHS_ALIAS_2 = 9;
+ const LHS_ALIAS_3 = 10;
+ const RHS_ALIAS_1 = 11;
+ const RHS_ALIAS_2 = 12;
+ const PRECEDENCE_MARK_1 = 13;
+ const PRECEDENCE_MARK_2 = 14;
+ const RESYNC_AFTER_RULE_ERROR = 15;
+ const RESYNC_AFTER_DECL_ERROR = 16;
+ const WAITING_FOR_DESTRUCTOR_SYMBOL = 17;
+ const WAITING_FOR_DATATYPE_SYMBOL = 18;
+ const WAITING_FOR_FALLBACK_ID = 19;
+
+ /**
+ * Name of the input file
+ *
+ * @var string
+ */
+ public $filename;
+ /**
+ * Linenumber at which current token starts
+ * @var int
+ */
+ public $tokenlineno;
+ /**
+ * Number of parsing errors so far
+ * @var int
+ */
+ public $errorcnt;
+ /**
+ * Index of current token within the input string
+ * @var int
+ */
+ public $tokenstart;
+ /**
+ * Global state vector
+ * @var PHP_ParserGenerator_Data
+ */
+ public $gp;
+ /**
+ * Parser state (one of the class constants for this class)
+ *
+ * - PHP_ParserGenerator_Parser::INITIALIZE,
+ * - PHP_ParserGenerator_Parser::WAITING_FOR_DECL_OR_RULE,
+ * - PHP_ParserGenerator_Parser::WAITING_FOR_DECL_KEYWORD,
+ * - PHP_ParserGenerator_Parser::WAITING_FOR_DECL_ARG,
+ * - PHP_ParserGenerator_Parser::WAITING_FOR_PRECEDENCE_SYMBOL,
+ * - PHP_ParserGenerator_Parser::WAITING_FOR_ARROW,
+ * - PHP_ParserGenerator_Parser::IN_RHS,
+ * - PHP_ParserGenerator_Parser::LHS_ALIAS_1,
+ * - PHP_ParserGenerator_Parser::LHS_ALIAS_2,
+ * - PHP_ParserGenerator_Parser::LHS_ALIAS_3,
+ * - PHP_ParserGenerator_Parser::RHS_ALIAS_1,
+ * - PHP_ParserGenerator_Parser::RHS_ALIAS_2,
+ * - PHP_ParserGenerator_Parser::PRECEDENCE_MARK_1,
+ * - PHP_ParserGenerator_Parser::PRECEDENCE_MARK_2,
+ * - PHP_ParserGenerator_Parser::RESYNC_AFTER_RULE_ERROR,
+ * - PHP_ParserGenerator_Parser::RESYNC_AFTER_DECL_ERROR,
+ * - PHP_ParserGenerator_Parser::WAITING_FOR_DESTRUCTOR_SYMBOL,
+ * - PHP_ParserGenerator_Parser::WAITING_FOR_DATATYPE_SYMBOL,
+ * - PHP_ParserGenerator_Parser::WAITING_FOR_FALLBACK_ID
+ * @var int
+ */
+ public $state;
+ /**
+ * The fallback token
+ * @var PHP_ParserGenerator_Symbol
+ */
+ public $fallback;
+ /**
+ * Left-hand side of the current rule
+ * @var PHP_ParserGenerator_Symbol
+ */
+ public $lhs;
+ /**
+ * Alias for the LHS
+ * @var string
+ */
+ public $lhsalias;
+ /**
+ * Number of right-hand side symbols seen
+ * @var int
+ */
+ public $nrhs;
+ /**
+ * Right-hand side symbols
+ * @var array array of {@link PHP_ParserGenerator_Symbol} objects
+ */
+ public $rhs = array();
+ /**
+ * Aliases for each RHS symbol name (or NULL)
+ * @var array array of strings
+ */
+ public $alias = array();
+ /**
+ * Previous rule parsed
+ * @var PHP_ParserGenerator_Rule
+ */
+ public $prevrule;
+ /**
+ * Keyword of a declaration
+ *
+ * This is one of the %keyword keywords in the grammar file
+ * @var string
+ */
+ public $declkeyword;
+ /**
+ * Where the declaration argument should be put
+ *
+ * This is assigned as a reference to an internal variable
+ * @var mixed
+ */
+ public $declargslot = array();
+ /**
+ * Where the declaration linenumber is put
+ *
+ * This is assigned as a reference to an internal variable
+ * @var mixed
+ */
+ public $decllnslot;
+ /*enum e_assoc*/
+ public $declassoc; /* Assign this association to decl arguments */
+ public $preccounter; /* Assign this precedence to decl arguments */
+ /**
+ * @var PHP_ParserGenerator_Rule
+ */
+ public $firstrule; /* Pointer to first rule in the grammar */
+ /**
+ * @var PHP_ParserGenerator_Rule
+ */
+ public $lastrule; /* Pointer to the most recently parsed rule */
+
+ /**
+ * @var PHP_ParserGenerator
+ */
+ private $lemon;
+
+ function __construct(PHP_ParserGenerator $lem)
+ {
+ $this->lemon = $lem;
+ }
+
+ /**
+ * Run the preprocessor over the input file text. The Lemon variable
+ * $azDefine contains the names of all defined
+ * macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and
+ * comments them out. Text in between is also commented out as appropriate.
+ * @param string
+ */
+ private function preprocess_input(&$z)
+ {
+ $lineno = $exclude = 0;
+ for ($i=0; $i < strlen($z); $i++) {
+ if ($z[$i] == "\n") {
+ $lineno++;
+ }
+ if ($z[$i] != '%' || ($i > 0 && $z[$i-1] != "\n")) {
+ continue;
+ }
+ if (substr($z, $i, 6) === "%endif" && trim($z[$i+6]) === '') {
+ if ($exclude) {
+ $exclude--;
+ if ($exclude === 0) {
+ for ($j = $start; $j < $i; $j++) {
+ if ($z[$j] != "\n") $z[$j] = ' ';
+ }
+ }
+ }
+ for ($j = $i; $j < strlen($z) && $z[$j] != "\n"; $j++) {
+ $z[$j] = ' ';
+ }
+ } elseif (substr($z, $i, 6) === "%ifdef" && trim($z[$i+6]) === '' ||
+ substr($z, $i, 7) === "%ifndef" && trim($z[$i+7]) === '') {
+ if ($exclude) {
+ $exclude++;
+ } else {
+ $j = $i;
+ $n = strtok(substr($z, $j), " \t");
+ $exclude = 1;
+ if (isset($this->lemon->azDefine[$n])) {
+ $exclude = 0;
+ }
+ if ($z[$i + 3]=='n') {
+ // this is a rather obtuse way of checking whether this is %ifndef
+ $exclude = !$exclude;
+ }
+ if ($exclude) {
+ $start = $i;
+ $start_lineno = $lineno;
+ }
+ }
+ //for ($j = $i; $j < strlen($z) && $z[$j] != "\n"; $j++) $z[$j] = ' ';
+ $j = strpos(substr($z, $i), "\n");
+ if ($j === false) {
+ $z = substr($z, 0, $i); // remove instead of adding ' '
+ } else {
+ $z = substr($z, 0, $i) . substr($z, $i + $j); // remove instead of adding ' '
+ }
+ }
+ }
+ if ($exclude) {
+ throw new Exception("unterminated %ifdef starting on line $start_lineno\n");
+ }
+ }
+
+ /**
+ * In spite of its name, this function is really a scanner.
+ *
+ * It reads in the entire input file (all at once) then tokenizes it.
+ * Each token is passed to the function "parseonetoken" which builds all
+ * the appropriate data structures in the global state vector "gp".
+ * @param PHP_ParserGenerator_Data
+ */
+ function Parse(PHP_ParserGenerator_Data $gp)
+ {
+ $startline = 0;
+
+ $this->gp = $gp;
+ $this->filename = $gp->filename;
+ $this->errorcnt = 0;
+ $this->state = self::INITIALIZE;
+
+ /* Begin by reading the input file */
+ $filebuf = file_get_contents($this->filename);
+ if (!$filebuf) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0, "Can't open this file for reading.");
+ $gp->errorcnt++;
+ return;
+ }
+ if (filesize($this->filename) != strlen($filebuf)) {
+ ErrorMsg($this->filename, 0, "Can't read in all %d bytes of this file.",
+ filesize($this->filename));
+ $gp->errorcnt++;
+ return;
+ }
+
+ /* Make an initial pass through the file to handle %ifdef and %ifndef */
+ $this->preprocess_input($filebuf);
+
+ /* Now scan the text of the input file */
+ $lineno = 1;
+ for ($cp = 0, $c = $filebuf[0]; $cp < strlen($filebuf); $cp++) {
+ $c = $filebuf[$cp];
+ if ($c == "\n") $lineno++; /* Keep track of the line number */
+ if (trim($c) === '') {
+ continue;
+ } /* Skip all white space */
+ if ($filebuf[$cp] == '/' && ($cp + 1 < strlen($filebuf)) && $filebuf[$cp + 1] == '/') {
+ /* Skip C++ style comments */
+ $cp += 2;
+ $z = strpos(substr($filebuf, $cp), "\n");
+ if ($z === false) {
+ $cp = strlen($filebuf);
+ break;
+ }
+ $lineno++;
+ $cp += $z;
+ continue;
+ }
+ if ($filebuf[$cp] == '/' && ($cp + 1 < strlen($filebuf)) && $filebuf[$cp + 1] == '*') {
+ /* Skip C style comments */
+ $cp += 2;
+ $z = strpos(substr($filebuf, $cp), '*/');
+ if ($z !== false) {
+ $lineno += count(explode("\n", substr($filebuf, $cp, $z))) - 1;
+ }
+ $cp += $z + 1;
+ continue;
+ }
+ $this->tokenstart = $cp; /* Mark the beginning of the token */
+ $this->tokenlineno = $lineno; /* Linenumber on which token begins */
+ if ($filebuf[$cp] == '"') { /* String literals */
+ $cp++;
+ $oldcp = $cp;
+ $test = strpos(substr($filebuf, $cp), '"');
+ if ($test === false) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $startline,
+ "String starting on this line is not terminated before the end of the file.");
+ $this->errorcnt++;
+ $nextcp = $cp = strlen($filebuf);
+ } else {
+ $cp += $test;
+ $nextcp = $cp + 1;
+ }
+ $lineno += count(explode("\n", substr($filebuf, $oldcp, $cp - $oldcp))) - 1;
+ } elseif ($filebuf[$cp] == '{') { /* A block of C code */
+ $cp++;
+ if ($filebuf[$cp]=="}") {
+ $filebuf = substr($filebuf, 0, $cp)." ".substr($filebuf, $cp);
+ }
+
+ for ($level = 1; $cp < strlen($filebuf) && ($level > 1 || $filebuf[$cp] != '}'); $cp++) {
+ if ($filebuf[$cp] == "\n") {
+ $lineno++;
+ } elseif ($filebuf[$cp] == '{') {
+ $level++;
+ } elseif ($filebuf[$cp] == '}') {
+ $level--;
+ } elseif ($filebuf[$cp] == '/' && $filebuf[$cp + 1] == '*') {
+ /* Skip comments */
+ $cp += 2;
+ $z = strpos(substr($filebuf, $cp), '*/');
+ if ($z !== false) {
+ $lineno += count(explode("\n", substr($filebuf, $cp, $z))) - 1;
+ }
+ $cp += $z + 2;
+ } elseif ($filebuf[$cp] == '/' && $filebuf[$cp + 1] == '/') {
+ /* Skip C++ style comments too */
+ $cp += 2;
+ $z = strpos(substr($filebuf, $cp), "\n");
+ if ($z === false) {
+ $cp = strlen($filebuf);
+ break;
+ } else {
+ $lineno++;
+ }
+ $cp += $z;
+ } elseif ($filebuf[$cp] == "'" || $filebuf[$cp] == '"') {
+ /* String a character literals */
+ $startchar = $filebuf[$cp];
+ $prevc = 0;
+ for ($cp++; $cp < strlen($filebuf) && ($filebuf[$cp] != $startchar || $prevc === '\\'); $cp++) {
+ if ($filebuf[$cp] == "\n") {
+ $lineno++;
+ }
+ if ($prevc === '\\') {
+ $prevc = 0;
+ } else {
+ $prevc = $filebuf[$cp];
+ }
+ }
+ }
+ }
+ if ($cp >= strlen($filebuf)) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "PHP code starting on this line is not terminated before the end of the file.");
+ $this->errorcnt++;
+ $nextcp = $cp;
+ } else {
+ $nextcp = $cp + 1;
+ }
+ } elseif (preg_match('/[a-zA-Z0-9]/', $filebuf[$cp])) {
+ /* Identifiers */
+ preg_match('/[a-zA-Z0-9_]+/', substr($filebuf, $cp), $preg_results);
+ $cp += strlen($preg_results[0]);
+ $nextcp = $cp;
+ } elseif ($filebuf[$cp] == ':' && $filebuf[$cp + 1] == ':' &&
+ $filebuf[$cp + 2] == '=') {
+ /* The operator "::=" */
+ $cp += 3;
+ $nextcp = $cp;
+ } elseif (($filebuf[$cp] == '/' || $filebuf[$cp] == '|') &&
+ preg_match('/[a-zA-Z]/', $filebuf[$cp + 1])) {
+ $cp += 2;
+ preg_match('/[a-zA-Z0-9_]+/', substr($filebuf, $cp), $preg_results);
+ $cp += strlen($preg_results[0]);
+ $nextcp = $cp;
+ } else {
+ /* All other (one character) operators */
+ $cp ++;
+ $nextcp = $cp;
+ }
+ $this->parseonetoken(substr($filebuf, $this->tokenstart,
+ $cp - $this->tokenstart)); /* Parse the token */
+ $cp = $nextcp - 1;
+ }
+ $gp->rule = $this->firstrule;
+ $gp->errorcnt = $this->errorcnt;
+ }
+
+ /**
+ * Parse a single token
+ * @param string token
+ */
+ function parseonetoken($token)
+ {
+ $x = $token;
+ $this->a = 0; // for referencing in WAITING_FOR_DECL_KEYWORD
+ if (PHP_ParserGenerator::DEBUG) {
+ printf("%s:%d: Token=[%s] state=%d\n",
+ $this->filename, $this->tokenlineno, $token, $this->state);
+ }
+ switch ($this->state) {
+ case self::INITIALIZE:
+ $this->prevrule = 0;
+ $this->preccounter = 0;
+ $this->firstrule = $this->lastrule = 0;
+ $this->gp->nrule = 0;
+ /* Fall thru to next case */
+ case self::WAITING_FOR_DECL_OR_RULE:
+ if ($x[0] == '%') {
+ $this->state = self::WAITING_FOR_DECL_KEYWORD;
+ } elseif (preg_match('/[a-z]/', $x[0])) {
+ $this->lhs = PHP_ParserGenerator_Symbol::Symbol_new($x);
+ $this->nrhs = 0;
+ $this->lhsalias = 0;
+ $this->state = self::WAITING_FOR_ARROW;
+ } elseif ($x[0] == '{') {
+ if ($this->prevrule === 0) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "There is no prior rule opon which to attach the code
+ fragment which begins on this line.");
+ $this->errorcnt++;
+ } elseif ($this->prevrule->code != 0) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Code fragment beginning on this line is not the first \
+ to follow the previous rule.");
+ $this->errorcnt++;
+ } else {
+ $this->prevrule->line = $this->tokenlineno;
+ $this->prevrule->code = substr($x, 1);
+ }
+ } elseif ($x[0] == '[') {
+ $this->state = self::PRECEDENCE_MARK_1;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Token \"%s\" should be either \"%%\" or a nonterminal name.",
+ $x);
+ $this->errorcnt++;
+ }
+ break;
+ case self::PRECEDENCE_MARK_1:
+ if (!preg_match('/[A-Z]/', $x[0])) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "The precedence symbol must be a terminal.");
+ $this->errorcnt++;
+ } elseif ($this->prevrule === 0) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "There is no prior rule to assign precedence \"[%s]\".", $x);
+ $this->errorcnt++;
+ } elseif ($this->prevrule->precsym != 0) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Precedence mark on this line is not the first to follow the previous rule.");
+ $this->errorcnt++;
+ } else {
+ $this->prevrule->precsym = PHP_ParserGenerator_Symbol::Symbol_new($x);
+ }
+ $this->state = self::PRECEDENCE_MARK_2;
+ break;
+ case self::PRECEDENCE_MARK_2:
+ if ($x[0] != ']') {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Missing \"]\" on precedence mark.");
+ $this->errorcnt++;
+ }
+ $this->state = self::WAITING_FOR_DECL_OR_RULE;
+ break;
+ case self::WAITING_FOR_ARROW:
+ if ($x[0] == ':' && $x[1] == ':' && $x[2] == '=') {
+ $this->state = self::IN_RHS;
+ } elseif ($x[0] == '(') {
+ $this->state = self::LHS_ALIAS_1;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Expected to see a \":\" following the LHS symbol \"%s\".",
+ $this->lhs->name);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_RULE_ERROR;
+ }
+ break;
+ case self::LHS_ALIAS_1:
+ if (preg_match('/[A-Za-z]/', $x[0])) {
+ $this->lhsalias = $x;
+ $this->state = self::LHS_ALIAS_2;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "\"%s\" is not a valid alias for the LHS \"%s\"\n",
+ $x, $this->lhs->name);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_RULE_ERROR;
+ }
+ break;
+ case self::LHS_ALIAS_2:
+ if ($x[0] == ')') {
+ $this->state = self::LHS_ALIAS_3;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Missing \")\" following LHS alias name \"%s\".",$this->lhsalias);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_RULE_ERROR;
+ }
+ break;
+ case self::LHS_ALIAS_3:
+ if ($x == '::=') {
+ $this->state = self::IN_RHS;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Missing \"->\" following: \"%s(%s)\".",
+ $this->lhs->name, $this->lhsalias);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_RULE_ERROR;
+ }
+ break;
+ case self::IN_RHS:
+ if ($x[0] == '.') {
+ $rp = new PHP_ParserGenerator_Rule;
+ $rp->ruleline = $this->tokenlineno;
+ for ($i = 0; $i < $this->nrhs; $i++) {
+ $rp->rhs[$i] = $this->rhs[$i];
+ $rp->rhsalias[$i] = $this->alias[$i];
+ }
+ if (count(array_unique($rp->rhsalias)) != count($rp->rhsalias)) {
+ $used = array();
+ foreach ($rp->rhsalias as $i => $symbol) {
+ if (!is_string($symbol)) {
+ continue;
+ }
+ if (isset($used[$symbol])) {
+ PHP_ParserGenerator::ErrorMsg($this->filename,
+ $this->tokenlineno,
+ "RHS symbol \"%s\" used multiple times.",
+ $symbol);
+ $this->errorcnt++;
+ } else {
+ $used[$symbol] = $i;
+ }
+ }
+ }
+ $rp->lhs = $this->lhs;
+ $rp->lhsalias = $this->lhsalias;
+ $rp->nrhs = $this->nrhs;
+ $rp->code = 0;
+ $rp->precsym = 0;
+ $rp->index = $this->gp->nrule++;
+ $rp->nextlhs = $rp->lhs->rule;
+ $rp->lhs->rule = $rp;
+ $rp->next = 0;
+ if ($this->firstrule === 0) {
+ $this->firstrule = $this->lastrule = $rp;
+ } else {
+ $this->lastrule->next = $rp;
+ $this->lastrule = $rp;
+ }
+ $this->prevrule = $rp;
+ $this->state = self::WAITING_FOR_DECL_OR_RULE;
+ } elseif (preg_match('/[a-zA-Z]/', $x[0])) {
+ if ($this->nrhs >= PHP_ParserGenerator::MAXRHS) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Too many symbols on RHS or rule beginning at \"%s\".",
+ $x);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_RULE_ERROR;
+ } else {
+ if (isset($this->rhs[$this->nrhs - 1])) {
+ $msp = $this->rhs[$this->nrhs - 1];
+ if ($msp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ $inf = array_reduce($msp->subsym,
+ array($this, '_printmulti'), '');
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ 'WARNING: symbol ' . $x . ' will not' .
+ ' be part of previous multiterminal %s',
+ substr($inf, 0, strlen($inf) - 1)
+ );
+ }
+ }
+ $this->rhs[$this->nrhs] = PHP_ParserGenerator_Symbol::Symbol_new($x);
+ $this->alias[$this->nrhs] = 0;
+ $this->nrhs++;
+ }
+ } elseif (($x[0] == '|' || $x[0] == '/') && $this->nrhs > 0) {
+ $msp = $this->rhs[$this->nrhs - 1];
+ if ($msp->type != PHP_ParserGenerator_Symbol::MULTITERMINAL) {
+ $origsp = $msp;
+ $msp = new PHP_ParserGenerator_Symbol;
+ $msp->type = PHP_ParserGenerator_Symbol::MULTITERMINAL;
+ $msp->nsubsym = 1;
+ $msp->subsym = array($origsp);
+ $msp->name = $origsp->name;
+ $this->rhs[$this->nrhs - 1] = $msp;
+ }
+ $msp->nsubsym++;
+ $msp->subsym[$msp->nsubsym - 1] = PHP_ParserGenerator_Symbol::Symbol_new(substr($x, 1));
+ if (preg_match('/[a-z]/', $x[1]) ||
+ preg_match('/[a-z]/', $msp->subsym[0]->name[0])) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Cannot form a compound containing a non-terminal");
+ $this->errorcnt++;
+ }
+ } elseif ($x[0] == '(' && $this->nrhs > 0) {
+ $this->state = self::RHS_ALIAS_1;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Illegal character on RHS of rule: \"%s\".", $x);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_RULE_ERROR;
+ }
+ break;
+ case self::RHS_ALIAS_1:
+ if (preg_match('/[A-Za-z]/', $x[0])) {
+ $this->alias[$this->nrhs - 1] = $x;
+ $this->state = self::RHS_ALIAS_2;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "\"%s\" is not a valid alias for the RHS symbol \"%s\"\n",
+ $x, $this->rhs[$this->nrhs - 1]->name);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_RULE_ERROR;
+ }
+ break;
+ case self::RHS_ALIAS_2:
+ if ($x[0] == ')') {
+ $this->state = self::IN_RHS;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Missing \")\" following LHS alias name \"%s\".", $this->lhsalias);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_RULE_ERROR;
+ }
+ break;
+ case self::WAITING_FOR_DECL_KEYWORD:
+ if(preg_match('/[A-Za-z]/', $x[0])) {
+ $this->declkeyword = $x;
+ $this->declargslot = &$this->a;
+ $this->decllnslot = &$this->a;
+ $this->state = self::WAITING_FOR_DECL_ARG;
+ if ('name' == $x) {
+ $this->declargslot = &$this->gp->name;
+ } elseif ('include' == $x) {
+ $this->declargslot = &$this->gp->include_code;
+ $this->decllnslot = &$this->gp->includeln;
+ } elseif ('include_class' == $x) {
+ $this->declargslot = &$this->gp->include_classcode;
+ $this->decllnslot = &$this->gp->include_classln;
+ } elseif ('declare_class' == $x) {
+ $this->declargslot = &$this->gp->declare_classcode;
+ $this->decllnslot = &$this->gp->declare_classln;
+ } elseif ('code' == $x) {
+ $this->declargslot = &$this->gp->extracode;
+ $this->decllnslot = &$this->gp->extracodeln;
+ } elseif ('token_destructor' == $x) {
+ $this->declargslot = &$this->gp->tokendest;
+ $this->decllnslot = &$this->gp->tokendestln;
+ } elseif ('default_destructor' == $x) {
+ $this->declargslot = &$this->gp->vardest;
+ $this->decllnslot = &$this->gp->vardestln;
+ } elseif ('token_prefix' == $x) {
+ $this->declargslot = &$this->gp->tokenprefix;
+ } elseif ('syntax_error' == $x) {
+ $this->declargslot = &$this->gp->error;
+ $this->decllnslot = &$this->gp->errorln;
+ } elseif ('parse_accept' == $x) {
+ $this->declargslot = &$this->gp->accept;
+ $this->decllnslot = &$this->gp->acceptln;
+ } elseif ('parse_failure' == $x) {
+ $this->declargslot = &$this->gp->failure;
+ $this->decllnslot = &$this->gp->failureln;
+ } elseif ('stack_overflow' == $x) {
+ $this->declargslot = &$this->gp->overflow;
+ $this->decllnslot = &$this->gp->overflowln;
+ } elseif ('token_type' == $x) {
+ $this->declargslot = &$this->gp->tokentype;
+ } elseif ('default_type' == $x) {
+ $this->declargslot = &$this->gp->vartype;
+ } elseif ('stack_size' == $x) {
+ $this->declargslot = &$this->gp->stacksize;
+ } elseif ('start_symbol' == $x) {
+ $this->declargslot = &$this->gp->start;
+ } elseif ('left' == $x) {
+ $this->preccounter++;
+ $this->declassoc = PHP_ParserGenerator_Symbol::LEFT;
+ $this->state = self::WAITING_FOR_PRECEDENCE_SYMBOL;
+ } elseif ('right' == $x) {
+ $this->preccounter++;
+ $this->declassoc = PHP_ParserGenerator_Symbol::RIGHT;
+ $this->state = self::WAITING_FOR_PRECEDENCE_SYMBOL;
+ } elseif ('nonassoc' == $x) {
+ $this->preccounter++;
+ $this->declassoc = PHP_ParserGenerator_Symbol::NONE;
+ $this->state = self::WAITING_FOR_PRECEDENCE_SYMBOL;
+ } elseif ('destructor' == $x) {
+ $this->state = self::WAITING_FOR_DESTRUCTOR_SYMBOL;
+ } elseif ('type' == $x) {
+ $this->state = self::WAITING_FOR_DATATYPE_SYMBOL;
+ } elseif ('fallback' == $x) {
+ $this->fallback = 0;
+ $this->state = self::WAITING_FOR_FALLBACK_ID;
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Unknown declaration keyword: \"%%%s\".", $x);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_DECL_ERROR;
+ }
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Illegal declaration keyword: \"%s\".", $x);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_DECL_ERROR;
+ }
+ break;
+ case self::WAITING_FOR_DESTRUCTOR_SYMBOL:
+ if (!preg_match('/[A-Za-z]/', $x[0])) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Symbol name missing after %destructor keyword");
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_DECL_ERROR;
+ } else {
+ $sp = PHP_ParserGenerator_Symbol::Symbol_new($x);
+ $this->declargslot = &$sp->destructor;
+ $this->decllnslot = &$sp->destructorln;
+ $this->state = self::WAITING_FOR_DECL_ARG;
+ }
+ break;
+ case self::WAITING_FOR_DATATYPE_SYMBOL:
+ if (!preg_match('/[A-Za-z]/', $x[0])) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Symbol name missing after %destructor keyword");
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_DECL_ERROR;
+ } else {
+ $sp = PHP_ParserGenerator_Symbol::Symbol_new($x);
+ $this->declargslot = &$sp->datatype;
+ $this->state = self::WAITING_FOR_DECL_ARG;
+ }
+ break;
+ case self::WAITING_FOR_PRECEDENCE_SYMBOL:
+ if ($x[0] == '.') {
+ $this->state = self::WAITING_FOR_DECL_OR_RULE;
+ } elseif (preg_match('/[A-Z]/', $x[0])) {
+ $sp = PHP_ParserGenerator_Symbol::Symbol_new($x);
+ if ($sp->prec >= 0) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Symbol \"%s\" has already been given a precedence.", $x);
+ $this->errorcnt++;
+ } else {
+ $sp->prec = $this->preccounter;
+ $sp->assoc = $this->declassoc;
+ }
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Can't assign a precedence to \"%s\".", $x);
+ $this->errorcnt++;
+ }
+ break;
+ case self::WAITING_FOR_DECL_ARG:
+ if (preg_match('/[A-Za-z0-9{"]/', $x[0])) {
+ if ($this->declargslot != 0) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "The argument \"%s\" to declaration \"%%%s\" is not the first.",
+ $x[0] == '"' ? substr($x, 1) : $x, $this->declkeyword);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_DECL_ERROR;
+ } else {
+ $this->declargslot = ($x[0] == '"' || $x[0] == '{') ? substr($x, 1) : $x;
+ $this->a = 1;
+ if (!$this->decllnslot) {
+ $this->decllnslot = $this->tokenlineno;
+ }
+ $this->state = self::WAITING_FOR_DECL_OR_RULE;
+ }
+ } else {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "Illegal argument to %%%s: %s",$this->declkeyword, $x);
+ $this->errorcnt++;
+ $this->state = self::RESYNC_AFTER_DECL_ERROR;
+ }
+ break;
+ case self::WAITING_FOR_FALLBACK_ID:
+ if ($x[0] == '.') {
+ $this->state = self::WAITING_FOR_DECL_OR_RULE;
+ } elseif (!preg_match('/[A-Z]/', $x[0])) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "%%fallback argument \"%s\" should be a token", $x);
+ $this->errorcnt++;
+ } else {
+ $sp = PHP_ParserGenerator_Symbol::Symbol_new($x);
+ if ($this->fallback === 0) {
+ $this->fallback = $sp;
+ } elseif (is_object($sp->fallback)) {
+ PHP_ParserGenerator::ErrorMsg($this->filename, $this->tokenlineno,
+ "More than one fallback assigned to token %s", $x);
+ $this->errorcnt++;
+ } else {
+ $sp->fallback = $this->fallback;
+ $this->gp->has_fallback = 1;
+ }
+ }
+ break;
+ case self::RESYNC_AFTER_RULE_ERROR:
+ /* if ($x[0] == '.') $this->state = self::WAITING_FOR_DECL_OR_RULE;
+ ** break; */
+ case self::RESYNC_AFTER_DECL_ERROR:
+ if ($x[0] == '.') {
+ $this->state = self::WAITING_FOR_DECL_OR_RULE;
+ }
+ if ($x[0] == '%') {
+ $this->state = self::WAITING_FOR_DECL_KEYWORD;
+ }
+ break;
+ }
+ }
+
+ /**
+ * return a descriptive string for a multi-terminal token.
+ *
+ * @param string $a
+ * @param string $b
+ * @return string
+ */
+ private function _printmulti($a, $b)
+ {
+ if (!$a) {
+ $a = '';
+ }
+ $a .= $b->name . '|';
+ return $a;
+ }
+}
diff --git a/core/oql/build/PHP/ParserGenerator/PropagationLink.php b/core/oql/build/PHP/ParserGenerator/PropagationLink.php
new file mode 100644
index 000000000..d8802e0f9
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/PropagationLink.php
@@ -0,0 +1,126 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: PropagationLink.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+/**
+ * A followset propagation link indicates that the contents of one
+ * configuration followset should be propagated to another whenever
+ * the first changes.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+
+class PHP_ParserGenerator_PropagationLink
+{
+ /**
+ * The configuration that defines this propagation link
+ *
+ * @var PHP_ParserGenerator_Config
+ */
+ public $cfp;
+ /**
+ * The next propagation link
+ *
+ * @var PHP_ParserGenerator_PropagationLink|0
+ */
+ public $next = 0;
+
+ /**
+ * Add a propagation link to the current list
+ *
+ * This prepends the configuration passed in to the first parameter
+ * which is either 0 or a PHP_ParserGenerator_PropagationLink defining
+ * an existing list.
+ *
+ * @param PHP_ParserGenerator_PropagationLink|null
+ * @param PHP_ParserGenerator_Config
+ */
+ static function Plink_add(&$plpp, PHP_ParserGenerator_Config $cfp)
+ {
+ $new = new PHP_ParserGenerator_PropagationLink;
+ $new->next = $plpp;
+ $plpp = $new;
+ $new->cfp = $cfp;
+ }
+
+ /**
+ * Transfer every propagation link on the list "from" to the list "to"
+ */
+ static function Plink_copy(PHP_ParserGenerator_PropagationLink &$to, PHP_ParserGenerator_PropagationLink $from)
+ {
+ while ($from) {
+ $nextpl = $from->next;
+ $from->next = $to;
+ $to = $from;
+ $from = $nextpl;
+ }
+ }
+
+ /**
+ * Delete every propagation link on the list
+ *
+ * @param PHP_ParserGenerator_PropagationLink|0
+ *
+ * @return void
+ */
+ static function Plink_delete($plp)
+ {
+ while ($plp) {
+ $nextpl = $plp->next;
+ $plp->next = 0;
+ $plp = $nextpl;
+ }
+ }
+}
+
diff --git a/core/oql/build/PHP/ParserGenerator/Rule.php b/core/oql/build/PHP/ParserGenerator/Rule.php
new file mode 100644
index 000000000..a3523008e
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/Rule.php
@@ -0,0 +1,144 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Rule.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+/**
+ * Each production rule in the grammar is stored in this class
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+class PHP_ParserGenerator_Rule
+{
+ /**
+ * Left-hand side of the rule
+ * @var array an array of {@link PHP_ParserGenerator_Symbol} objects
+ */
+ public $lhs;
+ /**
+ * Alias for the LHS (NULL if none)
+ *
+ * @var array
+ */
+ public $lhsalias = array();
+ /**
+ * Line number for the rule
+ * @var int
+ */
+ public $ruleline;
+ /**
+ * Number of right-hand side symbols
+ */
+ public $nrhs;
+ /**
+ * The right-hand side symbols
+ * @var array an array of {@link PHP_ParserGenerator_Symbol} objects
+ */
+ public $rhs;
+ /**
+ * Aliases for each right-hand side symbol, or null if no alis.
+ *
+ * In this rule:
+ *
+ * foo ::= BAR(A) baz(B).
+ *
+ *
+ * The right-hand side aliases are A for BAR, and B for baz.
+ * @var array aliases are indexed by the right-hand side symbol index.
+ */
+ public $rhsalias = array();
+ /**
+ * Line number at which code begins
+ * @var int
+ */
+ public $line;
+ /**
+ * The code executed when this rule is reduced
+ *
+ *
+ * foo(R) ::= BAR(A) baz(B). {R = A + B;}
+ *
+ *
+ * In the rule above, the code is "R = A + B;"
+ * @var string|0
+ */
+ public $code;
+ /**
+ * Precedence symbol for this rule
+ * @var PHP_ParserGenerator_Symbol
+ */
+ public $precsym;
+ /**
+ * An index number for this rule
+ *
+ * Used in both naming of reduce functions and determining which rule code
+ * to use for reduce actions
+ * @var int
+ */
+ public $index;
+ /**
+ * True if this rule is ever reduced
+ * @var boolean
+ */
+ public $canReduce;
+ /**
+ * Next rule with the same left-hand side
+ * @var PHP_ParserGenerator_Rule|0
+ */
+ public $nextlhs;
+ /**
+ * Next rule in the global list
+ * @var PHP_ParserGenerator_Rule|0
+ */
+ public $next;
+}
diff --git a/core/oql/build/PHP/ParserGenerator/State.php b/core/oql/build/PHP/ParserGenerator/State.php
new file mode 100644
index 000000000..e48c9f589
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/State.php
@@ -0,0 +1,283 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: State.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+
+/**
+ * The structure used to represent a state in the associative array
+ * for a PHP_ParserGenerator_Config.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+class PHP_ParserGenerator_StateNode
+{
+ public $key;
+ public $data;
+ public $from = 0;
+ public $next = 0;
+}
+
+/**
+ * Each state of the generated parser's finite state machine
+ * is encoded as an instance of this class
+ *
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+class PHP_ParserGenerator_State
+{
+ /**
+ * The basis configurations for this state
+ * @var PHP_ParserGenerator_Config
+ */
+ public $bp;
+ /**
+ * All configurations in this state
+ * @var PHP_ParserGenerator_Config
+ */
+ public $cfp;
+ /**
+ * Sequential number for this state
+ *
+ * @var int
+ */
+ public $statenum;
+ /**
+ * Linked list of actions for this state.
+ * @var PHP_ParserGenerator_Action
+ */
+ public $ap;
+ /**
+ * Number of terminal (token) actions
+ *
+ * @var int
+ */
+ public $nTknAct,
+ /**
+ * Number of non-terminal actions
+ *
+ * @var int
+ */
+ $nNtAct;
+ /**
+ * The offset into the $yy_action table for terminal tokens.
+ *
+ * @var int
+ */
+ public $iTknOfst,
+ /**
+ * The offset into the $yy_action table for non-terminals.
+ *
+ * @var int
+ */
+ $iNtOfst;
+ /**
+ * Default action
+ *
+ * @var int
+ */
+ public $iDflt;
+ /**
+ * Associative array of PHP_ParserGenerator_State objects
+ *
+ * @var array
+ */
+ public static $x3a = array();
+ /**
+ * Array of PHP_ParserGenerator_State objects
+ *
+ * @var array
+ */
+ public static $states = array();
+
+ /**
+ * Compare two states for sorting purposes. The smaller state is the
+ * one with the most non-terminal actions. If they have the same number
+ * of non-terminal actions, then the smaller is the one with the most
+ * token actions.
+ */
+ static function stateResortCompare($a, $b)
+ {
+ $n = $b->nNtAct - $a->nNtAct;
+ if ($n === 0) {
+ $n = $b->nTknAct - $a->nTknAct;
+ }
+ return $n;
+ }
+
+ /**
+ * Compare two states based on their configurations
+ *
+ * @param PHP_ParserGenerator_Config|0 $a
+ * @param PHP_ParserGenerator_Config|0 $b
+ * @return int
+ */
+ static function statecmp($a, $b)
+ {
+ for ($rc = 0; $rc == 0 && $a && $b; $a = $a->bp, $b = $b->bp) {
+ $rc = $a->rp->index - $b->rp->index;
+ if ($rc === 0) {
+ $rc = $a->dot - $b->dot;
+ }
+ }
+ if ($rc == 0) {
+ if ($a) {
+ $rc = 1;
+ }
+ if ($b) {
+ $rc = -1;
+ }
+ }
+ return $rc;
+ }
+
+ /**
+ * Hash a state based on its configuration
+ *
+ * @return int
+ */
+ private static function statehash(PHP_ParserGenerator_Config $a)
+ {
+ $h = 0;
+ while ($a) {
+ $h = $h * 571 + $a->rp->index * 37 + $a->dot;
+ $a = $a->bp;
+ }
+ return (int) $h;
+ }
+
+ /**
+ * Return a pointer to data assigned to the given key. Return NULL
+ * if no such key.
+ * @param PHP_ParserGenerator_Config
+ * @return null|PHP_ParserGenerator_State
+ */
+ static function State_find(PHP_ParserGenerator_Config $key)
+ {
+ if (!count(self::$x3a)) {
+ return 0;
+ }
+ $h = self::statehash($key);
+ if (!isset(self::$x3a[$h])) {
+ return 0;
+ }
+ $np = self::$x3a[$h];
+ while ($np) {
+ if (self::statecmp($np->key, $key) == 0) {
+ break;
+ }
+ $np = $np->next;
+ }
+ return $np ? $np->data : 0;
+ }
+
+ /**
+ * Insert a new record into the array. Return TRUE if successful.
+ * Prior data with the same key is NOT overwritten
+ *
+ * @param PHP_ParserGenerator_State $state
+ * @param PHP_ParserGenerator_Config $key
+ * @return unknown
+ */
+ static function State_insert(PHP_ParserGenerator_State $state, PHP_ParserGenerator_Config $key)
+ {
+ $h = self::statehash($key);
+ if (isset(self::$x3a[$h])) {
+ $np = self::$x3a[$h];
+ } else {
+ $np = 0;
+ }
+ while ($np) {
+ if (self::statecmp($np->key, $key) == 0) {
+ /* An existing entry with the same key is found. */
+ /* Fail because overwrite is not allows. */
+ return 0;
+ }
+ $np = $np->next;
+ }
+ /* Insert the new data */
+ $np = new PHP_ParserGenerator_StateNode;
+ $np->key = $key;
+ $np->data = $state;
+ self::$states[] = $np;
+ // the original lemon code sets the from link always to itself
+ // setting up a faulty double-linked list
+ // however, the from links are never used, so I suspect a copy/paste
+ // error from a standard algorithm that was never caught
+ if (isset(self::$x3a[$h])) {
+ self::$x3a[$h]->from = $np; // lemon has $np->next here
+ } else {
+ self::$x3a[$h] = 0; // dummy to avoid notice
+ }
+ $np->next = self::$x3a[$h];
+ self::$x3a[$h] = $np;
+ $np->from = self::$x3a[$h];
+ return 1;
+ }
+
+ /**
+ * Get an array indexed by state number
+ *
+ * @return array
+ */
+ static function State_arrayof()
+ {
+ return self::$states;
+ }
+}
diff --git a/core/oql/build/PHP/ParserGenerator/Symbol.php b/core/oql/build/PHP/ParserGenerator/Symbol.php
new file mode 100644
index 000000000..d24a86fb4
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/Symbol.php
@@ -0,0 +1,288 @@
+
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id: Symbol.php 302382 2010-08-17 06:08:09Z jespino $
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since File available since Release 0.1.0
+ */
+/**
+ * Symbols (terminals and nonterminals) of the grammar are stored in this class
+ *
+ * @category PHP
+ * @package PHP_ParserGenerator
+ * @author Gregory Beaver
+ * @copyright 2006 Gregory Beaver
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/PHP_ParserGenerator
+ * @since Class available since Release 0.1.0
+ */
+class PHP_ParserGenerator_Symbol
+{
+ /**
+ * Symbols that start with a capital letter like FOO.
+ *
+ * These are tokens directly from the lexer
+ */
+ const TERMINAL = 1;
+ /**
+ * Symbols that start with a lower-case letter like foo.
+ *
+ * These are grammar rules like "foo ::= BLAH."
+ */
+ const NONTERMINAL = 2;
+ /**
+ * Multiple terminal symbols.
+ *
+ * These are a grammar rule that consists of several terminals like
+ * FOO|BAR|BAZ. Note that non-terminals cannot be in a multi-terminal,
+ * and a multi-terminal acts like a single terminal.
+ *
+ * "FOO|BAR FOO|BAZ" is actually two multi-terminals, FOO|BAR and FOO|BAZ.
+ */
+ const MULTITERMINAL = 3;
+
+ const LEFT = 1;
+ const RIGHT = 2;
+ const NONE = 3;
+ const UNK = 4;
+ /**
+ * Name of the symbol
+ *
+ * @var string
+ */
+ public $name;
+ /**
+ * Index of this symbol.
+ *
+ * This will ultimately end up representing the symbol in the generated
+ * parser
+ * @var int
+ */
+ public $index;
+ /**
+ * Symbol type
+ *
+ * One of PHP_ParserGenerator_Symbol::TERMINAL,
+ * PHP_ParserGenerator_Symbol::NONTERMINAL or
+ * PHP_ParserGenerator_Symbol::MULTITERMINAL
+ * @var int
+ */
+ public $type;
+ /**
+ * Linked list of rules that use this symbol, if it is a non-terminal.
+ * @var PHP_ParserGenerator_Rule
+ */
+ public $rule;
+ /**
+ * Fallback token in case this token doesn't parse
+ * @var PHP_ParserGenerator_Symbol
+ */
+ public $fallback;
+ /**
+ * Precendence, if defined.
+ *
+ * -1 if no unusual precedence
+ * @var int
+ */
+ public $prec = -1;
+ /**
+ * Associativity if precedence is defined.
+ *
+ * One of PHP_ParserGenerator_Symbol::LEFT,
+ * PHP_ParserGenerator_Symbol::RIGHT, PHP_ParserGenerator_Symbol::NONE
+ * or PHP_ParserGenerator_Symbol::UNK
+ * @var unknown_type
+ */
+ public $assoc;
+ /**
+ * First-set for all rules of this symbol
+ *
+ * @var array
+ */
+ public $firstset;
+ /**
+ * True if this symbol is a non-terminal and can generate an empty
+ * result.
+ *
+ * For instance "foo ::= ."
+ * @var boolean
+ */
+ public $lambda;
+ /**
+ * Code that executes whenever this symbol is popped from the stack during
+ * error processing.
+ *
+ * @var string|0
+ */
+ public $destructor = 0;
+ /**
+ * Line number of destructor code
+ * @var int
+ */
+ public $destructorln;
+ /**
+ * Unused relic of the C version of Lemon.
+ *
+ * The data type of information held by this object. Only used
+ * if this is a non-terminal
+ * @var string
+ */
+ public $datatype;
+ /**
+ * Unused relic of the C version of Lemon.
+ *
+ * The data type number. In the parser, the value
+ * stack is a union. The .yy%d element of this
+ * union is the correct data type for this object
+ * @var string
+ */
+ public $dtnum;
+ /**#@+
+ * The following fields are used by MULTITERMINALs only
+ */
+ /**
+ * Number of terminal symbols in the MULTITERMINAL
+ *
+ * This is of course the same as count($this->subsym)
+ * @var int
+ */
+ public $nsubsym;
+ /**
+ * Array of terminal symbols in the MULTITERMINAL
+ * @var array an array of {@link PHP_ParserGenerator_Symbol} objects
+ */
+ public $subsym = array();
+ /**#@-*/
+ /**
+ * Singleton storage of symbols
+ *
+ * @var array an array of PHP_ParserGenerator_Symbol objects
+ */
+ private static $_symbol_table = array();
+ /**
+ * Return a pointer to the (terminal or nonterminal) symbol "x".
+ * Create a new symbol if this is the first time "x" has been seen.
+ * (this is a singleton)
+ * @param string
+ * @return PHP_ParserGenerator_Symbol
+ */
+ public static function Symbol_new($x)
+ {
+ if (isset(self::$_symbol_table[$x])) {
+ return self::$_symbol_table[$x];
+ }
+ $sp = new PHP_ParserGenerator_Symbol;
+ $sp->name = $x;
+ $sp->type = preg_match('/[A-Z]/', $x[0]) ? self::TERMINAL : self::NONTERMINAL;
+ $sp->rule = 0;
+ $sp->fallback = 0;
+ $sp->prec = -1;
+ $sp->assoc = self::UNK;
+ $sp->firstset = array();
+ $sp->lambda = false;
+ $sp->destructor = 0;
+ $sp->datatype = 0;
+ self::$_symbol_table[$sp->name] = $sp;
+ return $sp;
+ }
+
+ /**
+ * Return the number of unique symbols
+ *
+ * @return int
+ */
+ public static function Symbol_count()
+ {
+ return count(self::$_symbol_table);
+ }
+
+ public static function Symbol_arrayof()
+ {
+ return array_values(self::$_symbol_table);
+ }
+
+ public static function Symbol_find($x)
+ {
+ if (isset(self::$_symbol_table[$x])) {
+ return self::$_symbol_table[$x];
+ }
+ return 0;
+ }
+
+ /**
+ * Sort function helper for symbols
+ *
+ * Symbols that begin with upper case letters (terminals or tokens)
+ * must sort before symbols that begin with lower case letters
+ * (non-terminals). Other than that, the order does not matter.
+ *
+ * We find experimentally that leaving the symbols in their original
+ * order (the order they appeared in the grammar file) gives the
+ * smallest parser tables in SQLite.
+ * @param PHP_ParserGenerator_Symbol
+ * @param PHP_ParserGenerator_Symbol
+ */
+ public static function sortSymbols($a, $b)
+ {
+ $i1 = $a->index + 10000000*(ord($a->name[0]) > ord('Z'));
+ $i2 = $b->index + 10000000*(ord($b->name[0]) > ord('Z'));
+ return $i1 - $i2;
+ }
+
+ /**
+ * Return true if two symbols are the same.
+ */
+ public static function same_symbol(PHP_ParserGenerator_Symbol $a, PHP_ParserGenerator_Symbol $b)
+ {
+ if ($a === $b) return 1;
+ if ($a->type != self::MULTITERMINAL) return 0;
+ if ($b->type != self::MULTITERMINAL) return 0;
+ if ($a->nsubsym != $b->nsubsym) return 0;
+ for ($i = 0; $i < $a->nsubsym; $i++) {
+ if ($a->subsym[$i] != $b->subsym[$i]) return 0;
+ }
+ return 1;
+ }
+}
diff --git a/core/oql/build/PHP/ParserGenerator/cli.php b/core/oql/build/PHP/ParserGenerator/cli.php
new file mode 100644
index 000000000..bb1113afb
--- /dev/null
+++ b/core/oql/build/PHP/ParserGenerator/cli.php
@@ -0,0 +1,5 @@
+main();
+?>
\ No newline at end of file
diff --git a/core/oql/build/build.bash b/core/oql/build/build.bash
new file mode 100644
index 000000000..eb3c1f6ab
--- /dev/null
+++ b/core/oql/build/build.bash
@@ -0,0 +1,4 @@
+#!/bin/bash
+php PHP/LexerGenerator/cli.php oql-lexer.plex
+php PHP/ParserGenerator/cli.php oql-parser.y
+
diff --git a/core/oql/build/build.cmd b/core/oql/build/build.cmd
new file mode 100644
index 000000000..df34ce8d6
--- /dev/null
+++ b/core/oql/build/build.cmd
@@ -0,0 +1,5 @@
+rem must be run with current directory = the directory of the batch
+rem PEAR is required to build
+php -d include_path=".;C:\iTop\PHP\PEAR" ".\PHP\LexerGenerator\cli.php" ..\oql-lexer.plex
+php ".\PHP\ParserGenerator\cli.php" ..\oql-parser.y
+pause
\ No newline at end of file
diff --git a/core/oql/exclude.txt b/core/oql/exclude.txt
index 126cbeac5..d0ed5567c 100644
--- a/core/oql/exclude.txt
+++ b/core/oql/exclude.txt
@@ -2,7 +2,6 @@
# The following source files are not re-distributed with the "build" of the application
# since they are used solely for constructing other files during the build process
#
-build.cmd
-build.bash
+build
oql-lexer.plex
-oql-parser.y
+oql-parser.y
\ No newline at end of file
diff --git a/core/oql/oql-parser.php b/core/oql/oql-parser.php
index 5b67cd205..f5587048e 100644
--- a/core/oql/oql-parser.php
+++ b/core/oql/oql-parser.php
@@ -96,8 +96,8 @@ class OQLParser_yyStackEntry
// code external to the class is included here
// declare_class is output here
-#line 24 "oql-parser.y"
-class OQLParserRaw#line 102 "oql-parser.php"
+#line 24 "..\oql-parser.y"
+class OQLParserRaw#line 102 "..\oql-parser.php"
{
/* First off, code is included which follows the "include_class" declaration
** in the input file. */
@@ -1422,139 +1422,139 @@ static public $yy_action = array(
** function yy_r0($yymsp){ ... } // User supplied code
** #line
*/
-#line 29 "oql-parser.y"
+#line 29 "..\oql-parser.y"
function yy_r0(){ $this->my_result = $this->yystack[$this->yyidx + 0]->minor; }
-#line 1431 "oql-parser.php"
-#line 32 "oql-parser.y"
+#line 1431 "..\oql-parser.php"
+#line 32 "..\oql-parser.y"
function yy_r2(){
$this->_retvalue = new OqlObjectQuery($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor, array($this->yystack[$this->yyidx + -2]->minor));
}
-#line 1436 "oql-parser.php"
-#line 35 "oql-parser.y"
+#line 1436 "..\oql-parser.php"
+#line 35 "..\oql-parser.y"
function yy_r3(){
$this->_retvalue = new OqlObjectQuery($this->yystack[$this->yyidx + -4]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor, array($this->yystack[$this->yyidx + -2]->minor));
}
-#line 1441 "oql-parser.php"
-#line 39 "oql-parser.y"
+#line 1441 "..\oql-parser.php"
+#line 39 "..\oql-parser.y"
function yy_r4(){
$this->_retvalue = new OqlObjectQuery($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + -4]->minor);
}
-#line 1446 "oql-parser.php"
-#line 42 "oql-parser.y"
+#line 1446 "..\oql-parser.php"
+#line 42 "..\oql-parser.y"
function yy_r5(){
$this->_retvalue = new OqlObjectQuery($this->yystack[$this->yyidx + -4]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + -6]->minor);
}
-#line 1451 "oql-parser.php"
-#line 47 "oql-parser.y"
+#line 1451 "..\oql-parser.php"
+#line 47 "..\oql-parser.y"
function yy_r6(){
$this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor);
}
-#line 1456 "oql-parser.php"
-#line 50 "oql-parser.y"
+#line 1456 "..\oql-parser.php"
+#line 50 "..\oql-parser.y"
function yy_r7(){
array_push($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor);
$this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
}
-#line 1462 "oql-parser.php"
-#line 55 "oql-parser.y"
+#line 1462 "..\oql-parser.php"
+#line 55 "..\oql-parser.y"
function yy_r8(){ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; }
-#line 1465 "oql-parser.php"
-#line 56 "oql-parser.y"
+#line 1465 "..\oql-parser.php"
+#line 56 "..\oql-parser.y"
function yy_r9(){ $this->_retvalue = null; }
-#line 1468 "oql-parser.php"
-#line 58 "oql-parser.y"
+#line 1468 "..\oql-parser.php"
+#line 58 "..\oql-parser.y"
function yy_r10(){
// insert the join statement on top of the existing list
array_unshift($this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor);
// and return the updated array
$this->_retvalue = $this->yystack[$this->yyidx + 0]->minor;
}
-#line 1476 "oql-parser.php"
-#line 64 "oql-parser.y"
+#line 1476 "..\oql-parser.php"
+#line 64 "..\oql-parser.y"
function yy_r11(){
$this->_retvalue = Array($this->yystack[$this->yyidx + 0]->minor);
}
-#line 1481 "oql-parser.php"
-#line 70 "oql-parser.y"
+#line 1481 "..\oql-parser.php"
+#line 70 "..\oql-parser.y"
function yy_r13(){
// create an array with one single item
$this->_retvalue = new OqlJoinSpec($this->yystack[$this->yyidx + -4]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor);
}
-#line 1487 "oql-parser.php"
-#line 75 "oql-parser.y"
+#line 1487 "..\oql-parser.php"
+#line 75 "..\oql-parser.y"
function yy_r14(){
// create an array with one single item
$this->_retvalue = new OqlJoinSpec($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor);
}
-#line 1493 "oql-parser.php"
-#line 80 "oql-parser.y"
+#line 1493 "..\oql-parser.php"
+#line 80 "..\oql-parser.y"
function yy_r15(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, '=', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1496 "oql-parser.php"
-#line 81 "oql-parser.y"
+#line 1496 "..\oql-parser.php"
+#line 81 "..\oql-parser.y"
function yy_r16(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, 'BELOW', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1499 "oql-parser.php"
-#line 82 "oql-parser.y"
+#line 1499 "..\oql-parser.php"
+#line 82 "..\oql-parser.y"
function yy_r17(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, 'BELOW_STRICT', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1502 "oql-parser.php"
-#line 83 "oql-parser.y"
+#line 1502 "..\oql-parser.php"
+#line 83 "..\oql-parser.y"
function yy_r18(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, 'NOT_BELOW', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1505 "oql-parser.php"
-#line 84 "oql-parser.y"
+#line 1505 "..\oql-parser.php"
+#line 84 "..\oql-parser.y"
function yy_r19(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, 'NOT_BELOW_STRICT', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1508 "oql-parser.php"
-#line 85 "oql-parser.y"
+#line 1508 "..\oql-parser.php"
+#line 85 "..\oql-parser.y"
function yy_r20(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, 'ABOVE', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1511 "oql-parser.php"
-#line 86 "oql-parser.y"
+#line 1511 "..\oql-parser.php"
+#line 86 "..\oql-parser.y"
function yy_r21(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, 'ABOVE_STRICT', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1514 "oql-parser.php"
-#line 87 "oql-parser.y"
+#line 1514 "..\oql-parser.php"
+#line 87 "..\oql-parser.y"
function yy_r22(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, 'NOT_ABOVE', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1517 "oql-parser.php"
-#line 88 "oql-parser.y"
+#line 1517 "..\oql-parser.php"
+#line 88 "..\oql-parser.y"
function yy_r23(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, 'NOT_ABOVE_STRICT', $this->yystack[$this->yyidx + 0]->minor); }
-#line 1520 "oql-parser.php"
-#line 90 "oql-parser.y"
+#line 1520 "..\oql-parser.php"
+#line 90 "..\oql-parser.y"
function yy_r24(){ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; }
-#line 1523 "oql-parser.php"
-#line 95 "oql-parser.y"
+#line 1523 "..\oql-parser.php"
+#line 95 "..\oql-parser.y"
function yy_r28(){ $this->_retvalue = new FunctionOqlExpression($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + -1]->minor); }
-#line 1526 "oql-parser.php"
-#line 96 "oql-parser.y"
+#line 1526 "..\oql-parser.php"
+#line 96 "..\oql-parser.y"
function yy_r29(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; }
-#line 1529 "oql-parser.php"
-#line 97 "oql-parser.y"
+#line 1529 "..\oql-parser.php"
+#line 97 "..\oql-parser.y"
function yy_r30(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor); }
-#line 1532 "oql-parser.php"
-#line 112 "oql-parser.y"
+#line 1532 "..\oql-parser.php"
+#line 112 "..\oql-parser.y"
function yy_r39(){
$this->_retvalue = new ListOqlExpression($this->yystack[$this->yyidx + -1]->minor);
}
-#line 1537 "oql-parser.php"
-#line 123 "oql-parser.y"
+#line 1537 "..\oql-parser.php"
+#line 123 "..\oql-parser.y"
function yy_r42(){
$this->_retvalue = array();
}
-#line 1542 "oql-parser.php"
-#line 134 "oql-parser.y"
+#line 1542 "..\oql-parser.php"
+#line 134 "..\oql-parser.y"
function yy_r46(){ $this->_retvalue = new IntervalOqlExpression($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor); }
-#line 1545 "oql-parser.php"
-#line 146 "oql-parser.y"
+#line 1545 "..\oql-parser.php"
+#line 146 "..\oql-parser.y"
function yy_r55(){ $this->_retvalue = new ScalarOqlExpression($this->yystack[$this->yyidx + 0]->minor); }
-#line 1548 "oql-parser.php"
-#line 149 "oql-parser.y"
+#line 1548 "..\oql-parser.php"
+#line 149 "..\oql-parser.y"
function yy_r57(){ $this->_retvalue = new FieldOqlExpression($this->yystack[$this->yyidx + 0]->minor); }
-#line 1551 "oql-parser.php"
-#line 150 "oql-parser.y"
+#line 1551 "..\oql-parser.php"
+#line 150 "..\oql-parser.y"
function yy_r58(){ $this->_retvalue = new FieldOqlExpression($this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -2]->minor); }
-#line 1554 "oql-parser.php"
-#line 151 "oql-parser.y"
+#line 1554 "..\oql-parser.php"
+#line 151 "..\oql-parser.y"
function yy_r59(){ $this->_retvalue=$this->yystack[$this->yyidx + 0]->minor; }
-#line 1557 "oql-parser.php"
-#line 154 "oql-parser.y"
+#line 1557 "..\oql-parser.php"
+#line 154 "..\oql-parser.y"
function yy_r60(){ $this->_retvalue = new VariableOqlExpression(substr($this->yystack[$this->yyidx + 0]->minor, 1)); }
-#line 1560 "oql-parser.php"
-#line 156 "oql-parser.y"
+#line 1560 "..\oql-parser.php"
+#line 156 "..\oql-parser.y"
function yy_r61(){
if ($this->yystack[$this->yyidx + 0]->minor[0] == '`')
{
@@ -1566,22 +1566,22 @@ static public $yy_action = array(
}
$this->_retvalue = new OqlName($name, $this->m_iColPrev);
}
-#line 1573 "oql-parser.php"
-#line 167 "oql-parser.y"
+#line 1573 "..\oql-parser.php"
+#line 167 "..\oql-parser.y"
function yy_r62(){$this->_retvalue=(int)$this->yystack[$this->yyidx + 0]->minor; }
-#line 1576 "oql-parser.php"
-#line 168 "oql-parser.y"
+#line 1576 "..\oql-parser.php"
+#line 168 "..\oql-parser.y"
function yy_r63(){$this->_retvalue=(int)-$this->yystack[$this->yyidx + 0]->minor; }
-#line 1579 "oql-parser.php"
-#line 169 "oql-parser.y"
+#line 1579 "..\oql-parser.php"
+#line 169 "..\oql-parser.y"
function yy_r64(){$this->_retvalue=new OqlHexValue($this->yystack[$this->yyidx + 0]->minor); }
-#line 1582 "oql-parser.php"
-#line 170 "oql-parser.y"
+#line 1582 "..\oql-parser.php"
+#line 170 "..\oql-parser.y"
function yy_r65(){$this->_retvalue=stripslashes(substr($this->yystack[$this->yyidx + 0]->minor, 1, strlen($this->yystack[$this->yyidx + 0]->minor) - 2)); }
-#line 1585 "oql-parser.php"
-#line 173 "oql-parser.y"
+#line 1585 "..\oql-parser.php"
+#line 173 "..\oql-parser.y"
function yy_r66(){$this->_retvalue=$this->yystack[$this->yyidx + 0]->minor; }
-#line 1588 "oql-parser.php"
+#line 1588 "..\oql-parser.php"
/**
* placeholder for the left hand side in a reduce operation.
@@ -1693,10 +1693,10 @@ static public $yy_action = array(
*/
function yy_syntax_error($yymajor, $TOKEN)
{
-#line 25 "oql-parser.y"
+#line 25 "..\oql-parser.y"
throw new OQLParserException($this->m_sSourceQuery, $this->m_iLine, $this->m_iCol, $this->tokenName($yymajor), $TOKEN);
-#line 1704 "oql-parser.php"
+#line 1704 "..\oql-parser.php"
}
/**
@@ -1863,7 +1863,7 @@ throw new OQLParserException($this->m_sSourceQuery, $this->m_iLine, $this->m_iCo
} while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
}
}
-#line 231 "oql-parser.y"
+#line 231 "..\oql-parser.y"
class OQLParserException extends OQLException
@@ -1928,4 +1928,4 @@ class OQLParser extends OQLParserRaw
}
}
-#line 1937 "oql-parser.php"
+#line 1937 "..\oql-parser.php"