Skip to content

Commit 30c8212

Browse files
committed
Move multi-query parsing to WP_MySQL_Parser, improve naming and docs
1 parent e657ad0 commit 30c8212

4 files changed

Lines changed: 58 additions & 45 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,55 @@
11
<?php
22

33
class WP_MySQL_Parser extends WP_Parser {
4+
/**
5+
* The current query AST.
6+
*
7+
* @var WP_Parser_Node|null
8+
*/
9+
private $current_ast;
10+
11+
/**
12+
* Parse the next query from the input SQL string.
13+
*
14+
* This method reads tokens until a query is parsed, or the parsing fails.
15+
* It returns a boolean indicating whether a query was successfully parsed.
16+
*
17+
* Example:
18+
*
19+
* // Parse all queries in the input SQL string.
20+
* $parser = new WP_MySQL_Parser( $sql );
21+
* while ( $parser->next_query() ) {
22+
* $ast = $parser->get_query_ast();
23+
* if ( ! $ast ) {
24+
* // The parsing failed.
25+
* }
26+
* // The query was successfully parsed.
27+
* }
28+
*
29+
* @return bool Whether a query was successfully parsed.
30+
*/
31+
public function next_query(): bool {
32+
if ( $this->position >= count( $this->tokens ) ) {
33+
return false;
34+
}
35+
$this->current_ast = $this->parse();
36+
if ( ! $this->current_ast ) {
37+
return false;
38+
}
39+
return true;
40+
}
41+
42+
/**
43+
* Get the current query AST.
44+
*
45+
* When no query has been parsed yet, the parsing failed, or the end of the
46+
* input was reached, this method returns null.
47+
*
48+
* @see WP_MySQL_Parser::next_query() for usage example.
49+
*
50+
* @return WP_Parser_Node|null The current query AST, or null if no query was parsed.
51+
*/
52+
public function get_query_ast(): ?WP_Parser_Node {
53+
return $this->current_ast;
54+
}
455
}

wp-includes/parser/class-wp-parser-node.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ public function get_descendant_tokens( ?int $token_id = null ): array {
264264
}
265265

266266
/**
267-
* Get the byte offset in the input where the node begins.
267+
* Get the byte offset in the input SQL string where this node begins.
268268
*
269269
* @return int
270270
*/
@@ -273,7 +273,7 @@ public function get_start(): int {
273273
}
274274

275275
/**
276-
* Get the byte length of the node in the input.
276+
* Get the byte length of this node in the input SQL string.
277277
*
278278
* @return int
279279
*/

wp-includes/parser/class-wp-parser.php

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,9 @@
99
* satisfy in order to be supported by this parser (e.g., no left recursion).
1010
*/
1111
class WP_Parser {
12-
private $grammar;
13-
private $tokens;
14-
private $position;
15-
16-
/**
17-
* The current AST.
18-
*
19-
* @var WP_Parser_Node|null
20-
*/
21-
private $current_ast;
12+
protected $grammar;
13+
protected $tokens;
14+
protected $position;
2215

2316
public function __construct( WP_Parser_Grammar $grammar, array $tokens ) {
2417
$this->grammar = $grammar;
@@ -33,37 +26,6 @@ public function parse() {
3326
return false === $ast ? null : $ast;
3427
}
3528

36-
/**
37-
* Parse the next AST from the input tokens.
38-
*
39-
* This method reads tokens from the input until an AST is successfully parsed.
40-
* It starts from "$this->tokens[ $this->position ]", advances the number of
41-
* tokens read, and returns a boolean indicating whether an AST was successfully
42-
* parsed. When the end of the input is reached or a query could not be parsed,
43-
* the method returns false.
44-
*
45-
* @return bool Whether an AST was successfully parsed.
46-
*/
47-
public function next_ast(): bool {
48-
if ( $this->position >= count( $this->tokens ) ) {
49-
return false;
50-
}
51-
$this->current_ast = $this->parse();
52-
return true;
53-
}
54-
55-
/**
56-
* Get the current AST.
57-
*
58-
* When no AST has been parsed yet, the parsing failed, or the end of the
59-
* input was reached, this method returns null.
60-
*
61-
* @return WP_Parser_Node|null The current AST, or null if no AST was parsed.
62-
*/
63-
public function get_ast(): ?WP_Parser_Node {
64-
return $this->current_ast;
65-
}
66-
6729
private function parse_recursive( $rule_id ) {
6830
$is_terminal = $rule_id <= $this->grammar->highest_terminal_id;
6931
if ( $is_terminal ) {

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,8 +739,8 @@ public function parse_query( string $query ): Generator {
739739
$tokens = $lexer->remaining_tokens();
740740

741741
$parser = new WP_MySQL_Parser( self::$mysql_grammar, $tokens );
742-
while ( $parser->next_ast() ) {
743-
$ast = $parser->get_ast();
742+
while ( $parser->next_query() ) {
743+
$ast = $parser->get_query_ast();
744744
if ( null === $ast ) {
745745
throw $this->new_driver_exception( 'Failed to parse the MySQL query.' );
746746
}

0 commit comments

Comments
 (0)