Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
f57801c6
Commit
f57801c6
authored
Dec 23, 2007
by
jepso
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
optimized scanner
parent
82379e6d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
58 additions
and
107 deletions
+58
-107
Parser.php
draft/Doctrine/Query/Parser.php
+5
-3
Scanner.php
draft/Doctrine/Query/Scanner.php
+49
-102
Token.php
draft/Doctrine/Query/Token.php
+4
-2
No files found.
draft/Doctrine/Query/Parser.php
View file @
f57801c6
...
...
@@ -91,7 +91,7 @@ class Doctrine_Query_Parser
if
(
$isMatch
)
{
//$this->_printer->println($this->lookahead['value']);
$this
->
lookahead
=
$this
->
_scanner
->
scan
();
$this
->
lookahead
=
$this
->
_scanner
->
next
();
$this
->
_errorDistance
++
;
}
else
{
$this
->
syntaxError
();
...
...
@@ -141,11 +141,13 @@ class Doctrine_Query_Parser
*/
public
function
parse
()
{
$this
->
lookahead
=
$this
->
_scanner
->
scan
();
$this
->
lookahead
=
$this
->
_scanner
->
next
();
$this
->
getProduction
(
'QueryLanguage'
)
->
execute
();
$this
->
match
(
Doctrine_Query_Token
::
T_EOS
);
if
(
$this
->
lookahead
!==
null
)
{
$this
->
_error
(
'End of string expected.'
);
}
if
(
count
(
$this
->
_errors
))
{
$msg
=
'Query string parsing failed ('
...
...
draft/Doctrine/Query/Scanner.php
View file @
f57801c6
<?php
class
Doctrine_Query_Scanner
class
Doctrine_Query_Scanner
2
{
/**
* The query string
*
* @var string
*/
protected
$_input
;
/**
* The length of the query string
*
* @var string
*/
protected
$_length
;
/**
* Array of tokens already peeked
* Array of scanned tokens
*
* @var array
*/
protected
$_tokens
=
array
();
/**
*
* @var int
*/
protected
$_peekPosition
=
0
;
protected
$_nextToken
=
0
;
protected
$_position
=
0
;
protected
$_line
=
1
;
protected
$_column
=
1
;
protected
$_peek
=
0
;
protected
static
$_regex
=
array
(
'identifier'
=>
'/^[a-z][a-z0-9_]*/i'
,
'numeric'
=>
'/^[+-]?([0-9]+([\.][0-9]+)?)(e[+-]?[0-9]+)?/i'
,
'string'
=>
"/^'([^']|'')*'/"
,
'input_parameter'
=>
'/^\?|:[a-z]+/'
);
/**
* Creates a new query scanner object.
...
...
@@ -46,8 +20,7 @@ class Doctrine_Query_Scanner
*/
public
function
__construct
(
$input
)
{
$this
->
_input
=
$input
;
$this
->
_length
=
strlen
(
$input
);
$this
->
_scan
(
$input
);
}
/**
...
...
@@ -69,105 +42,79 @@ class Doctrine_Query_Scanner
}
return
Doctrine_Query_Token
::
T_IDENTIFIER
;
}
}
/**
*
Returns the next token in the input string
.
*
Scans the input string for tokens
.
*
* The returned token is an associative array containing the following keys:
* 'type' : type of the token; @see Doctrine_Query_Token::T_* constants
* 'value' : string value of the token in the input string
* 'position' : start position of the token in the input string
* 'line' :
* 'column' :
*
* @return array the next token
* @param string $input a query string
*/
protected
function
_
nextToken
(
)
protected
function
_
scan
(
$input
)
{
// ignore whitespace
while
(
$this
->
_position
<
$this
->
_length
&&
ctype_space
(
$this
->
_input
[
$this
->
_position
]
))
{
if
(
$this
->
_input
[
$this
->
_position
]
===
"
\n
"
)
{
$this
->
_line
++
;
$this
->
_column
=
1
;
}
else
{
$this
->
_column
++
;
}
$
this
->
_position
++
;
static
$regex
;
if
(
!
isset
(
$regex
))
{
$patterns
=
array
(
'[a-z_][a-z0-9_]*'
,
'(?:[0-9]+(?:[\.][0-9]+)?)(?:e[+-]?[0-9]+)?'
,
"'(?:[^']|'')*'"
,
'\?|:[a-z]+'
);
$
regex
=
'/('
.
implode
(
')|('
,
$patterns
)
.
')|\s+|(.)/i'
;
}
if
(
$this
->
_position
<
$this
->
_length
)
{
$subject
=
substr
(
$this
->
_input
,
$this
->
_position
);
$flags
=
PREG_SPLIT_NO_EMPTY
|
PREG_SPLIT_DELIM_CAPTURE
|
PREG_SPLIT_OFFSET_CAPTURE
;
$matches
=
preg_split
(
$regex
,
$input
,
-
1
,
$flags
);
if
(
preg_match
(
self
::
$_regex
[
'identifier'
],
$subject
,
$matches
))
{
$value
=
$matches
[
0
];
$type
=
$this
->
_checkLiteral
(
$value
);
}
elseif
(
preg_match
(
self
::
$_regex
[
'numeric'
],
$subject
,
$matches
))
{
$value
=
$matches
[
0
];
foreach
(
$matches
as
$match
)
{
$value
=
$match
[
0
];
if
(
is_numeric
(
$value
))
{
$type
=
Doctrine_Query_Token
::
T_NUMERIC
;
}
elseif
(
preg_match
(
self
::
$_regex
[
'string'
],
$subject
,
$matches
))
{
$value
=
$matches
[
0
];
}
elseif
(
$value
[
0
]
===
"'"
&&
$value
[
strlen
(
$value
)
-
1
]
===
"'"
)
{
$type
=
Doctrine_Query_Token
::
T_STRING
;
}
elseif
(
preg_match
(
self
::
$_regex
[
'input_parameter'
],
$subject
,
$matches
))
{
$value
=
$matches
[
0
];
}
elseif
(
ctype_alpha
(
$value
[
0
])
||
$value
[
0
]
===
'_'
)
{
$type
=
$this
->
_checkLiteral
(
$value
);
}
elseif
(
$value
[
0
]
===
'?'
||
$value
[
0
]
===
':'
)
{
$type
=
Doctrine_Query_Token
::
T_INPUT_PARAMETER
;
}
else
{
$value
=
$subject
[
0
];
$type
=
Doctrine_Query_Token
::
T_NONE
;
}
}
else
{
$value
=
''
;
$type
=
Doctrine_Query_Token
::
T_EOS
;
}
$token
=
array
(
'type'
=>
$type
,
'value'
=>
$value
,
'position'
=>
$this
->
_position
,
'line'
=>
$this
->
_line
,
'column'
=>
$this
->
_column
);
$increment
=
strlen
(
$value
);
$this
->
_position
+=
$increment
;
$this
->
_column
+=
$increment
;
return
$token
;
$this
->
_tokens
[]
=
array
(
'value'
=>
$value
,
'type'
=>
$type
,
'position'
=>
$match
[
1
]
);
}
}
/**
* Returns the next token without removing it from the input string.
*
* @return array the next token
*/
public
function
peek
()
{
if
(
$this
->
_peekPosition
>=
count
(
$this
->
_tokens
))
{
$this
->
_tokens
[]
=
$this
->
_nextToken
();
}
return
$this
->
_tokens
[
$this
->
_peekPosition
++
];
return
$this
->
_tokens
[
$this
->
_nextToken
+
$this
->
_peek
++
];
}
public
function
resetPeek
()
{
$this
->
_peek
Position
=
0
;
$this
->
_peek
=
0
;
}
/**
* Returns the next token in the input string.
*
* @return array the next token
* A token is an associative array containing three items:
* - 'value' : the string value of the token in the input string
* - 'type' : the type of the token (identifier, numeric, string, input
* parameter, none)
* - 'position' : the position of the token in the input string
*
* @return array|null the next token; null if there is no more tokens left
*/
public
function
scan
()
public
function
next
()
{
if
(
count
(
$this
->
_tokens
)
>
0
)
{
$this
->
resetPeek
();
return
array_shift
(
$this
->
_tokens
);
}
else
{
return
$this
->
_nextToken
();
}
$this
->
_peek
=
0
;
return
$this
->
_tokens
[
$this
->
_nextToken
++
];
}
}
draft/Doctrine/Query/Token.php
View file @
f57801c6
<?php
class
Doctrine_Query_Token
final
class
Doctrine_Query_Token
{
const
T_EOS
=
0
;
const
T_NONE
=
1
;
const
T_IDENTIFIER
=
2
;
const
T_NUMERIC
=
3
;
const
T_STRING
=
4
;
const
T_INPUT_PARAMETER
=
5
;
const
T_ALL
=
101
;
const
T_AND
=
102
;
const
T_ANY
=
103
;
...
...
@@ -58,4 +58,6 @@ class Doctrine_Query_Token
const
T_TRIM
=
149
;
const
T_LOWER
=
150
;
const
T_UPPER
=
151
;
private
function
__construct
()
{}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment