Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
ion
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Enzo Cioppettini
ion
Commits
f6077ce4
Commit
f6077ce4
authored
7 years ago
by
Michael Aaron Murphy
Browse files
Options
Downloads
Patches
Plain Diff
ArgumentSplitter Optimization
parent
c6d76f81
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
.gitignore
+3
-0
3 additions, 0 deletions
.gitignore
src/parser/arguments.rs
+61
-38
61 additions, 38 deletions
src/parser/arguments.rs
src/parser/assignments/splitter.rs
+3
-1
3 additions, 1 deletion
src/parser/assignments/splitter.rs
with
67 additions
and
39 deletions
.gitignore
+
3
−
0
View file @
f6077ce4
.*
cachegrind.*
perf.*
target
target
manual/book
manual/book
This diff is collapsed.
Click to expand it.
src/parser/arguments.rs
+
61
−
38
View file @
f6077ce4
const
DOUBLE
:
u8
=
1
;
const
DOUBLE
:
u8
=
1
;
const
SINGLE
:
u8
=
2
;
const
COMM_1
:
u8
=
2
;
const
BACK
:
u8
=
4
;
const
COMM_2
:
u8
=
4
;
const
COMM_1
:
u8
=
8
;
const
VARIAB
:
u8
=
8
;
const
COMM_2
:
u8
=
16
;
const
ARRAY
:
u8
=
16
;
const
VARIAB
:
u8
=
32
;
const
METHOD
:
u8
=
32
;
const
ARRAY
:
u8
=
64
;
const
METHOD
:
u8
=
128
;
/// An efficient `Iterator` structure for splitting arguments
/// An efficient `Iterator` structure for splitting arguments
pub
(
crate
)
struct
ArgumentSplitter
<
'a
>
{
pub
(
crate
)
struct
ArgumentSplitter
<
'a
>
{
...
@@ -24,54 +22,79 @@ impl<'a> ArgumentSplitter<'a> {
...
@@ -24,54 +22,79 @@ impl<'a> ArgumentSplitter<'a> {
}
}
}
}
impl
<
'a
>
ArgumentSplitter
<
'a
>
{
fn
scan_singlequotes
<
B
:
Iterator
<
Item
=
u8
>>
(
&
mut
self
,
bytes
:
&
mut
B
)
{
while
let
Some
(
character
)
=
bytes
.next
()
{
match
character
{
b'\\'
=>
{
self
.read
+=
2
;
let
_
=
bytes
.next
();
continue
;
}
b'\''
=>
break
,
_
=>
(),
}
self
.read
+=
1
;
}
}
}
impl
<
'a
>
Iterator
for
ArgumentSplitter
<
'a
>
{
impl
<
'a
>
Iterator
for
ArgumentSplitter
<
'a
>
{
type
Item
=
&
'a
str
;
type
Item
=
&
'a
str
;
fn
next
(
&
mut
self
)
->
Option
<&
'a
str
>
{
fn
next
(
&
mut
self
)
->
Option
<&
'a
str
>
{
while
let
Some
(
&
b' '
)
=
self
.data
.as_bytes
()
.get
(
self
.read
)
{
let
data
=
self
.data
.as_bytes
();
while
let
Some
(
&
b' '
)
=
data
.get
(
self
.read
)
{
self
.read
+=
1
;
self
.read
+=
1
;
}
}
let
start
=
self
.read
;
let
start
=
self
.read
;
let
(
mut
level
,
mut
array_level
,
mut
array_process_level
)
=
(
0
,
0
,
0
);
let
(
mut
level
,
mut
alevel
)
=
(
0
,
0
);
for
character
in
self
.data
.bytes
()
.skip
(
self
.read
)
{
let
mut
bytes
=
data
.iter
()
.cloned
()
.skip
(
self
.read
);
while
let
Some
(
character
)
=
bytes
.next
()
{
match
character
{
match
character
{
_
if
self
.flags
&
BACK
!=
0
=>
self
.flags
^=
BACK
,
// Skip the next byte.
b'\\'
=>
self
.flags
^=
BACK
,
b'\\'
=>
{
b'@'
if
self
.flags
&
SINGLE
==
0
=>
{
self
.read
+=
2
;
self
.flags
&=
255
^
COMM_1
;
let
_
=
bytes
.next
();
self
.flags
|
=
COMM_2
+
ARRAY
;
self
.read
+=
1
;
continue
;
continue
;
}
}
b'$'
if
self
.flags
&
SINGLE
==
0
=>
{
// Disable COMM_1 and enable COMM_2 + ARRAY.
self
.flags
&=
255
^
COMM_2
;
b'@'
=>
{
self
.flags
|
=
COMM_1
+
V
AR
IAB
;
self
.flags
=
(
self
.flags
&
(
255
^
COMM_1
))
|
(
COMM_2
+
AR
RAY
)
;
self
.read
+=
1
;
self
.read
+=
1
;
continue
;
continue
;
}
}
b'['
if
self
.flags
&
SINGLE
==
0
&&
self
.flags
&
COMM_2
!=
0
=>
{
// Disable COMM_2 and enable COMM_1 + VARIAB.
array_process_level
+=
1
b'$'
=>
{
}
self
.flags
=
(
self
.flags
&
(
255
^
COMM_2
))
|
(
COMM_1
+
VARIAB
);
b'['
if
self
.flags
&
SINGLE
==
0
=>
array_level
+=
1
,
self
.read
+=
1
;
b']'
if
self
.flags
&
SINGLE
==
0
&&
array_level
!=
0
=>
array_level
-=
1
,
continue
;
b']'
if
self
.flags
&
SINGLE
==
0
=>
array_process_level
-=
1
,
b'('
if
self
.flags
&
SINGLE
==
0
&&
self
.flags
&
COMM_1
!=
0
=>
level
+=
1
,
b'('
if
self
.flags
&
SINGLE
==
0
&&
self
.flags
&
(
VARIAB
+
ARRAY
)
!=
0
=>
{
self
.flags
|
=
METHOD
;
self
.flags
&=
255
^
(
VARIAB
+
ARRAY
);
}
}
b')'
if
self
.flags
&
SINGLE
==
0
&&
self
.flags
&
METHOD
!=
0
=>
{
// Increment the array level
self
.flags
&=
255
^
METHOD
;
b'['
=>
alevel
+=
1
,
// Decrement the array level
b']'
=>
alevel
-=
1
,
// Increment the parenthesis level.
b'('
if
self
.flags
&
COMM_1
!=
0
=>
level
+=
1
,
// Disable VARIAB + ARRAY and enable METHOD.
b'('
if
self
.flags
&
(
VARIAB
+
ARRAY
)
!=
0
=>
{
self
.flags
=
(
self
.flags
&
(
255
^
(
VARIAB
+
ARRAY
)))
|
METHOD
;
}
}
b')'
if
self
.flags
&
SINGLE
==
0
=>
level
-=
1
,
// Disable METHOD if enabled.
b'"'
if
self
.flags
&
SINGLE
==
0
=>
self
.flags
^=
DOUBLE
,
b')'
if
self
.flags
&
METHOD
!=
0
=>
self
.flags
^=
METHOD
,
b'\''
if
self
.flags
&
DOUBLE
==
0
=>
self
.flags
^=
SINGLE
,
// Otherwise decrement the parenthesis level.
b' '
if
self
.flags
&
(
SINGLE
+
DOUBLE
+
METHOD
)
==
0
&&
level
==
0
b')'
=>
level
-=
1
,
&&
array_level
==
0
&&
array_process_level
==
0
=>
// Toggle double quote rules.
{
b'"'
=>
self
.flags
^=
DOUBLE
,
break
// Loop through characters until single quote rules are completed.
b'\''
if
self
.flags
&
DOUBLE
==
0
=>
{
self
.scan_singlequotes
(
&
mut
bytes
);
self
.read
+=
2
;
continue
;
}
}
// Break from the loop once a root-level space is found.
b' '
if
(
self
.flags
&
(
DOUBLE
+
METHOD
))
+
level
+
alevel
==
0
=>
break
,
_
=>
(),
_
=>
(),
}
}
self
.read
+=
1
;
self
.read
+=
1
;
...
...
This diff is collapsed.
Click to expand it.
src/parser/assignments/splitter.rs
+
3
−
1
View file @
f6077ce4
...
@@ -19,7 +19,7 @@ pub(crate) fn split_assignment<'a>(
...
@@ -19,7 +19,7 @@ pub(crate) fn split_assignment<'a>(
start
=
read
;
start
=
read
;
read
+=
1
;
read
+=
1
;
break
;
break
;
}
else
if
[
b'+'
,
b'-'
,
b'/'
,
b'*'
]
.contains
(
&
byte
)
{
}
else
if
is_operator
(
byte
)
{
start
=
read
;
start
=
read
;
read
+=
1
;
read
+=
1
;
while
let
Some
(
byte
)
=
bytes
.next
()
{
while
let
Some
(
byte
)
=
bytes
.next
()
{
...
@@ -48,6 +48,8 @@ pub(crate) fn split_assignment<'a>(
...
@@ -48,6 +48,8 @@ pub(crate) fn split_assignment<'a>(
(
Some
(
keys
),
Some
(
operator
),
Some
(
values
.trim
()))
(
Some
(
keys
),
Some
(
operator
),
Some
(
values
.trim
()))
}
}
fn
is_operator
(
byte
:
u8
)
->
bool
{
byte
==
b'+'
||
byte
==
b'-'
||
byte
==
b'*'
||
byte
==
b'/'
}
#[cfg(test)]
#[cfg(test)]
mod
tests
{
mod
tests
{
use
super
::
*
;
use
super
::
*
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment