Skip to content

Commit

Permalink
Fix bug with parsing multiple parentheses.
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Feb 12, 2024
1 parent d5c70cd commit d19ac70
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 18 deletions.
31 changes: 17 additions & 14 deletions src/searchatom.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,25 +78,11 @@ function is_complete() {
return !$this->op || count($this->child) > ($this->op->unary ? 0 : 1);
}

/** @return bool */
function is_paren() {
return $this->op && $this->op->type === "(";
}

/** @return bool */
function is_incomplete_paren() {
return $this->op && $this->op->type === "(" && empty($this->child);
}

/** @param int $pos */
function complete_paren($pos) {
assert($this->op && $this->op->type === "(");
$this->pos2 = $pos;
if (!$this->is_complete()) {
$this->child[] = self::make_simple("", $pos);
}
}

/** @param int $pos
* @return SearchAtom */
function complete($pos) {
Expand All @@ -113,6 +99,23 @@ function complete($pos) {
}
}

/** @param int $pos1
* @param int $pos2
* @return SearchAtom */
function complete_paren($pos1, $pos2) {
$a = $this;
$first = $a->op && $a->op->type === "(" && !empty($a->child);
while (!$a->op || $a->op->type !== "(" || $first) {
$a = $a->complete($pos1);
$first = false;
}
$a->pos2 = $pos2;
if (empty($a->child)) {
$a->child[] = self::make_simple("", $pos2);
}
return $a;
}

/** @return list<SearchAtom> */
function flattened_children() {
if (!$this->op || $this->op->unary) {
Expand Down
5 changes: 1 addition & 4 deletions src/searchsplitter.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,7 @@ function parse_expression($spaceop = "SPACE", $max_ops = 2048) {
if ($parens === 0) {
continue;
}
while (!$cura->is_paren()) {
$cura = $cura->complete($pos1);
}
$cura->complete_paren($pos2);
$cura = $cura->complete_paren($pos1, $pos2);
--$parens;
continue;
}
Expand Down
11 changes: 11 additions & 0 deletions test/t_search.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ function test_search_overflow() {
xassert_neqq(PaperSearch::canonical_query($s, "", "", "", $this->conf), $s);
}

/** @suppress PhanTypeArraySuspiciousNullable */
function test_search_splitter_parens() {
$s = "((a) XOR #whatever)";
$splitter = new SearchSplitter($s);
Expand All @@ -183,6 +184,16 @@ function test_search_splitter_parens() {
$splitter = new SearchSplitter($s);
$a = $splitter->parse_expression();
xassert_eqq(json_encode($a->unparse_json()), '{"op":"(","child":[{"op":"xor","child":[{"op":"(","child":[""]},"#whatever"]}]}');

$s = "((OveMer:>3 OveMer:<2) or (OveMer:>4 OveMer:<3)) #r2";
$splitter = new SearchSplitter($s);
$a = $splitter->parse_expression();
xassert_eqq($a->op->type, "space");
xassert_eqq($a->child[0]->op->type, "(");
xassert_eqq($a->child[0]->child[0]->op->type, "or");
xassert_eqq(json_encode($a->child[0]->child[0]->child[0]->unparse_json()), '{"op":"(","child":[{"op":"space","child":["OveMer:>3","OveMer:<2"]}]}');
xassert_eqq(json_encode($a->child[0]->child[0]->child[1]->unparse_json()), '{"op":"(","child":[{"op":"space","child":["OveMer:>4","OveMer:<3"]}]}');
xassert_eqq(json_encode($a->child[1]->unparse_json()), '"#r2"');
}

function test_equal_quote() {
Expand Down

0 comments on commit d19ac70

Please sign in to comment.