Skip to content

Commit 9478c9a

Browse files
committed
Added utilities for parsing errors.
1 parent 0bff48a commit 9478c9a

3 files changed

Lines changed: 129 additions & 1 deletion

File tree

src/Utils/Error.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
/**
4+
* Error related utilities.
5+
*
6+
* @package SqlParser
7+
* @subpackage Utils
8+
*/
9+
namespace SqlParser\Utils;
10+
11+
use SqlParser\Lexer;
12+
use SqlParser\Parser;
13+
14+
/**
15+
* Error related utilities.
16+
*
17+
* @category Exceptions
18+
* @package SqlParser
19+
* @subpackage Utils
20+
* @author Dan Ungureanu <udan1107@gmail.com>
21+
* @license http://opensource.org/licenses/GPL-2.0 GNU Public License
22+
*/
23+
class Error
24+
{
25+
26+
/**
27+
* Gets the errors of a lexer and a parser.
28+
*
29+
* @param array $objs
30+
*
31+
* @return array Each element of the array represents an error.
32+
* `$err[0]` holds the error message.
33+
* `$err[1]` holds the error code.
34+
* `$err[2]` holds the string that caused the issue.
35+
* `$err[3]` holds the position of the string.
36+
* (i.e. `array($msg, $code, $str, $pos)`)
37+
*/
38+
public static function get($objs)
39+
{
40+
$ret = array();
41+
42+
foreach ($objs as $obj) {
43+
if ($obj instanceof Lexer) {
44+
foreach ($obj->errors as $err) {
45+
$ret[] = array(
46+
$err->getMessage(),
47+
$err->getCode(),
48+
$err->ch,
49+
$err->pos
50+
);
51+
}
52+
} elseif ($obj instanceof Parser) {
53+
foreach ($obj->errors as $err) {
54+
$ret[] = array(
55+
$err->getMessage(),
56+
$err->getCode(),
57+
$err->token->token,
58+
$err->token->position
59+
);
60+
}
61+
}
62+
}
63+
64+
return $ret;
65+
}
66+
67+
/**
68+
* Formats the specified errors
69+
*
70+
* @param array $errors The errors to be formatted.
71+
* @param string $format The format of an error.
72+
* '$1$d' is replaced by the position of this error.
73+
* '$2$s' is replaced by the error message.
74+
* '$3$d' is replaced by the error code.
75+
* '$4$s' is replaced by the string that caused the
76+
* issue.
77+
* '$5$d' is replaced by the position of the string.
78+
* @return array
79+
*/
80+
public static function format(
81+
$errors, $format = '#%1$d: %2$s (near "%4$s" at position %5$d)'
82+
) {
83+
$ret = array();
84+
85+
$i = 0;
86+
foreach ($errors as $key => $err) {
87+
$ret[$key] = sprintf(
88+
$format, ++$i, $err[0], $err[1], $err[2], $err[3]
89+
);
90+
}
91+
92+
return $ret;
93+
}
94+
}

tests/Lexer/ContextTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function testLoad()
3030

3131
/**
3232
* @expectedException Exception
33-
* @expectedExceptionMessage Specified context ("\SqlParser\Contexts\ContextFoo") doesn't exist.
33+
* @expectedExceptionMessage Specified context ("\SqlParser\Contexts\ContextFoo") does not exist.
3434
*/
3535
public function testLoadError()
3636
{

tests/Utils/ErrorTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace SqlParser\Tests\Utils;
4+
5+
use SqlParser\Lexer;
6+
use SqlParser\Parser;
7+
use SqlParser\Utils\Error;
8+
9+
use SqlParser\Tests\TestCase;
10+
11+
class ErrorTest extends TestCase
12+
{
13+
14+
public function testGet()
15+
{
16+
$lexer = new Lexer('SELECT * FROM db..tbl $');
17+
$parser = new Parser($lexer->list);
18+
$this->assertEquals(
19+
array(
20+
array('Unexpected character.', 0, '$', 22),
21+
array('Unexpected dot.', 0, '.', 17),
22+
),
23+
Error::get(array($lexer, $parser))
24+
);
25+
}
26+
27+
public function testFormat()
28+
{
29+
$this->assertEquals(
30+
array('#1: error msg (near "token" at position 100)'),
31+
Error::format(array(array('error msg', 42, 'token', 100)))
32+
);
33+
}
34+
}

0 commit comments

Comments
 (0)