private function &CompileExpression($tree, $rule_name = '', $omit_override = null, $non_override = null) { $omit = $omit_override === null ? $tree->node(0, 0) !== false ? $tree->index(0, 0) == 1 : false : $omit_override; $non = $non_override === null ? $tree->node(0, 1) !== false ? $tree->index(0, 1) == 1 : false : $non_override; $expression_type = $tree->nodes[1]->index; if ($rule_name === '') { switch ($expression_type) { case 1: // any $object = new ParseAny($omit, $non); break; case 2: // end $object = new ParseEOS($omit, $non); break; case 3: // begin $object = new ParseBOS($omit, $non); break; case 4: // set $object = new ParseSet($omit, $non); break; case 5: // not $object = new ParseNot($omit, $non); break; case 6: // opt $object = new ParseOptional($omit, $non); break; case 7: // and $object = new ParseAnd($omit, $non); break; case 8: // or $object = new ParseOr($omit, $non); break; case 9: // list $object = new ParseList($omit, $non); break; case 10: // literal $object = new ParseText($omit, $non); break; } } else { $object =& $this->rules[$rule_name]; } switch ($expression_type) { case 1: // any break; case 2: // end break; case 3: // begin break; case 4: // set $case = $tree->index(1, 0, 1, 0) == 1; $literal_set = ''; foreach ($tree->node(1, 0, 1, 1, 0)->nodes as $char) { switch ($char->index) { case 1: $literal_set .= '|'; break; case 2: $literal_set .= chr($char->nodes[0]->text($this->stream)); break; case 3: $literal_set .= $char->nodes[0]->text($this->stream); break; } } $object->def($case, $literal_set); break; case 5: // not // not case 6: // opt $condition =& $this->CompileExpression($tree->node(1, 0)); $object->def($condition); break; case 7: // and // and case 8: // or $object->set = array(); foreach ($tree->node(1, 0, 1)->nodes as $node) { $object->set[] =& $this->CompileExpression($node); } $object->length = count($object->set); break; case 9: // list $object->condition =& $this->CompileExpression($tree->node(1, 0, 1)); if ($tree->index(1, 0, 2) == 1) { $object->delimiter =& $this->CompileExpression($tree->node(1, 0, 2, 0, 1)); } else { $object->delimiter = null; } if ($tree->index(1, 0, 3) == 1) { $object->terminator =& $this->CompileExpression($tree->node(1, 0, 3, 0, 1)); } else { $object->terminator = null; } $object->min = $tree->index(1, 0, 4) == 1 ? $tree->text($this->stream, 1, 0, 4, 0, 1) : 1; $object->max = $tree->index(1, 0, 5) == 1 ? $tree->text($this->stream, 1, 0, 5, 0, 1) : -1; break; case 10: // literal $case = $tree->index(1, 0, 0) == 1; $text = $tree->text($this->stream, 1, 0, 1, 0); $encoded_text = ''; foreach ($tree->node(1, 0, 1, 0)->nodes as $char) { switch ($char->index) { case 1: $encoded_text .= '|'; break; case 2: $encoded_text .= chr($char->nodes[0]->text($this->stream)); break; case 3: $encoded_text .= $char->nodes[0]->text($this->stream); break; } } switch ($tree->index(1, 0, 1)) { case 1: // escaped $object->def($case, $encoded_text); break; case 2: // non escaped if (array_key_exists($text, $this->rules)) { $object =& $this->rules[$text]; $o = $object->omit || $omit; $n = $object->non_consuming || $non; $object =& $this->rules[$text . '_' . ($o ? 'o' : '') . ($n ? 'n' : '')]; } else { $object->def($case, $encoded_text); } break; } break; } return $object; }
function __construct() { $and = new ParseText(false, false); $and->def(false, "and"); $or = new ParseText(false, false); $or->def(false, "or"); $set = new ParseText(false, false); $set->def(false, "set"); $not = new ParseText(false, false); $not->def(false, "not"); $opt = new ParseText(false, false); $opt->def(false, "opt"); $any = new ParseText(false, false); $any->def(false, "any"); $eos = new ParseText(false, false); $eos->def(false, "eos"); $list = new ParseText(false, false); $list->def(false, "list"); $min = new ParseText(false, false); $min->def(false, "min"); $max = new ParseText(false, false); $max->def(false, "max"); $del = new ParseText(false, false); $del->def(false, "del"); $until = new ParseText(false, false); $until->def(false, "until"); $non = new ParseText(false, false); $non->def(false, "non"); $omit = new ParseText(false, false); $omit->def(false, "omit"); $case = new ParseText(false, false); $case->def(false, "case"); $end = new ParseText(false, false); $end->def(false, "end"); $pipe = new ParseText(false, false); $pipe->def(false, "|"); $pipe_omit = new ParseText(true, false); $pipe_omit->def(false, "|"); $double_pipe = new ParseAnd(false, false); $double_pipe->def($pipe, $pipe_omit); $double_pipe_omit = new ParseAnd(true, false); $double_pipe_omit->def($pipe, $pipe); $space = new ParseSet(false, false); $space->def(false, " "); $ws = new ParseList(true, false); $ws->def($space, null, null, 0); $anychar = new ParseAny(false, false); $digit = new ParseSet(false, false); $digit->def(false, "0123456789"); $literal_char = new ParseOr(false, false); $literal_char->def($double_pipe, $anychar); $not_pipe = new ParseNot(false, false); $not_pipe->def($pipe); $single_pipe = new ParseAnd(true, false); $single_pipe->def($pipe, $not_pipe); $not_identifier_char = new ParseOr(true, true); $not_identifier_char->def($space, $single_pipe); $identifier = new ParseList(false, false); $identifier->def($literal_char, null, $not_identifier_char); $literal_text = new ParseList(false, false); $literal_text->def($literal_char, null, $single_pipe, 0); $literal = new ParseAnd(false, false); $literal->def($double_pipe_omit, $literal_text); $case_opt = new ParseOptional(false, false); $case_opt->def($case); $omit_opt = new ParseOptional(false, false); $omit_opt->def($omit); $non_opt = new ParseOptional(false, false); $non_opt->def($non); $omit_non = new ParseAnd(false, false); $omit_non->def($omit_opt, $ws, $non_opt, $ws); $text = new ParseOr(false, false); $text->def($literal, $identifier); $text_case = new ParseAnd(false, false); $text_case->def($case_opt, $ws, $text); $and_ommited_expression = new ParseAnd(false, false); $and_expression = new ParseAnd(false, false); $or_expression = new ParseAnd(false, false); $not_expression = new ParseAnd(false, false); $set_expression = new ParseAnd(false, false); $opt_expression = new ParseAnd(false, false); $list_expression = new ParseAnd(false, false); $expression = new ParseOr(false, false); $expression->def($any, $eos, $set_expression, $not_expression, $opt_expression, $and_expression, $or_expression, $list_expression, $text_case); $full_expression = new ParseAnd(false, false); $full_expression->def($omit_non, $expression); $expression_list = new ParseList(false, false); $expression_list->def($full_expression, $ws); $and_ommited_expression->def($expression_list, $ws, $pipe); $and_expression->def($and, $ws, $expression_list, $ws, $pipe); $or_expression->def($or, $ws, $expression_list, $ws, $pipe); $not_expression->def($not, $ws, $expression, $ws, $pipe); $set_expression->def($set, $ws, $text_case, $ws, $pipe); $opt_expression->def($opt, $ws, $expression, $ws, $pipe); $number = new ParseList(false, false); $number->def($digit); $delimit_clause = new ParseAnd(false, false); $delimit_clause->def($ws, $del, $ws, $full_expression); $until_clause = new ParseAnd(false, false); $until_clause->def($ws, $until, $ws, $full_expression); $min_clause = new ParseAnd(false, false); $min_clause->def($ws, $min, $ws, $number); $max_clause = new ParseAnd(false, false); $max_clause->def($ws, $max, $ws, $number); $delimit_opt = new ParseOptional(false, false); $delimit_opt->def($delimit_clause); $until_opt = new ParseOptional(false, false); $until_opt->def($until_clause); $min_opt = new ParseOptional(false, false); $min_opt->def($min_clause); $max_opt = new ParseOptional(false, false); $max_opt->def($max_clause); $list_expression->def($list, $ws, $full_expression, $delimit_opt, $until_opt, $min_opt, $max_opt, $ws, $pipe); $end = new ParseEOS(false, false); $rule = new ParseAnd(false, false); $rule->def($identifier, $ws, $full_expression, $ws, $pipe, $ws); $this->rules_parser = new ParseList(false, false); $this->rules_parser->def($rule, null); }