Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
b12007c4
Commit
b12007c4
authored
Apr 01, 2010
by
Rob Pike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
testing/regexp: use recover.
R=rsc CC=golang-dev
https://golang.org/cl/816042
parent
9b04c9b1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
32 additions
and
61 deletions
+32
-61
regexp.go
src/pkg/regexp/regexp.go
+1
-3
regexp.go
src/pkg/testing/regexp.go
+31
-58
No files found.
src/pkg/regexp/regexp.go
View file @
b12007c4
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
...
...
@@ -264,8 +263,7 @@ type parser struct {
ch
int
}
func
(
p
*
parser
)
error
(
err
os
.
Error
)
{
p
.
re
=
nil
func
(
p
*
parser
)
error
(
err
Error
)
{
panic
(
err
)
}
...
...
src/pkg/testing/regexp.go
View file @
b12007c4
...
...
@@ -34,13 +34,13 @@ var debug = false
// Error codes returned by failures to parse an expression.
var
(
ErrInternal
=
"internal error"
ErrUnmatchedLpar
=
"unmatched ''"
ErrUnmatchedRpar
=
"unmatched ''"
ErrUnmatchedLpar
=
"unmatched '
(
'"
ErrUnmatchedRpar
=
"unmatched '
)
'"
ErrUnmatchedLbkt
=
"unmatched '['"
ErrUnmatchedRbkt
=
"unmatched ']'"
ErrBadRange
=
"bad range in character class"
ErrExtraneousBackslash
=
"extraneous backslash"
ErrBadClosure
=
"repeated closure
**, ++, etc.
"
ErrBadClosure
=
"repeated closure
(**, ++, etc.)
"
ErrBareClosure
=
"closure applies to nothing"
ErrBadBackslash
=
"illegal backslash escape"
)
...
...
@@ -267,12 +267,15 @@ func (re *Regexp) add(i instr) instr {
type
parser
struct
{
re
*
Regexp
error
string
nlpar
int
// number of unclosed lpars
pos
int
ch
int
}
func
(
p
*
parser
)
error
(
err
string
)
{
panic
(
err
)
}
const
endOfFile
=
-
1
func
(
p
*
parser
)
c
()
int
{
return
p
.
ch
}
...
...
@@ -326,8 +329,7 @@ func (p *parser) charClass() instr {
switch
c
:=
p
.
c
();
c
{
case
']'
,
endOfFile
:
if
left
>=
0
{
p
.
error
=
ErrBadRange
return
nil
p
.
error
(
ErrBadRange
)
}
// Is it [^\n]?
if
cc
.
negate
&&
len
(
cc
.
ranges
)
==
2
&&
...
...
@@ -339,21 +341,18 @@ func (p *parser) charClass() instr {
p
.
re
.
add
(
cc
)
return
cc
case
'-'
:
// do this before backslash processing
p
.
error
=
ErrBadRange
return
nil
p
.
error
(
ErrBadRange
)
case
'\\'
:
c
=
p
.
nextc
()
switch
{
case
c
==
endOfFile
:
p
.
error
=
ErrExtraneousBackslash
return
nil
p
.
error
(
ErrExtraneousBackslash
)
case
c
==
'n'
:
c
=
'\n'
case
specialcclass
(
c
)
:
// c is as delivered
default
:
p
.
error
=
ErrBadBackslash
return
nil
p
.
error
(
ErrBadBackslash
)
}
fallthrough
default
:
...
...
@@ -370,8 +369,7 @@ func (p *parser) charClass() instr {
cc
.
addRange
(
left
,
c
)
left
=
-
1
default
:
p
.
error
=
ErrBadRange
return
nil
p
.
error
(
ErrBadRange
)
}
}
}
...
...
@@ -379,28 +377,19 @@ func (p *parser) charClass() instr {
}
func
(
p
*
parser
)
term
()
(
start
,
end
instr
)
{
// term() is the leaf of the recursion, so it's sufficient to pick off the
// error state here for early exit.
// The other functions (closure(), concatenation() etc.) assume
// it's safe to recur to here.
if
p
.
error
!=
""
{
return
}
switch
c
:=
p
.
c
();
c
{
case
'|'
,
endOfFile
:
return
nil
,
nil
case
'*'
,
'+'
:
p
.
error
=
ErrBareClosure
p
.
error
(
ErrBareClosure
)
return
case
')'
:
if
p
.
nlpar
==
0
{
p
.
error
=
ErrUnmatchedRpar
return
p
.
error
(
ErrUnmatchedRpar
)
}
return
nil
,
nil
case
']'
:
p
.
error
=
ErrUnmatchedRbkt
return
p
.
error
(
ErrUnmatchedRbkt
)
case
'^'
:
p
.
nextc
()
start
=
p
.
re
.
add
(
new
(
_Bot
))
...
...
@@ -416,12 +405,8 @@ func (p *parser) term() (start, end instr) {
case
'['
:
p
.
nextc
()
start
=
p
.
charClass
()
if
p
.
error
!=
""
{
return
}
if
p
.
c
()
!=
']'
{
p
.
error
=
ErrUnmatchedLbkt
return
p
.
error
(
ErrUnmatchedLbkt
)
}
p
.
nextc
()
return
start
,
start
...
...
@@ -432,8 +417,7 @@ func (p *parser) term() (start, end instr) {
nbra
:=
p
.
re
.
nbra
start
,
end
=
p
.
regexp
()
if
p
.
c
()
!=
')'
{
p
.
error
=
ErrUnmatchedLpar
return
p
.
error
(
ErrUnmatchedLpar
)
}
p
.
nlpar
--
p
.
nextc
()
...
...
@@ -445,8 +429,7 @@ func (p *parser) term() (start, end instr) {
ebra
.
n
=
nbra
if
start
==
nil
{
if
end
==
nil
{
p
.
error
=
ErrInternal
return
p
.
error
(
ErrInternal
)
}
start
=
ebra
}
else
{
...
...
@@ -458,15 +441,14 @@ func (p *parser) term() (start, end instr) {
c
=
p
.
nextc
()
switch
{
case
c
==
endOfFile
:
p
.
error
=
ErrExtraneousBackslash
p
.
error
(
ErrExtraneousBackslash
)
return
case
c
==
'n'
:
c
=
'\n'
case
special
(
c
)
:
// c is as delivered
default
:
p
.
error
=
ErrBadBackslash
return
p
.
error
(
ErrBadBackslash
)
}
fallthrough
default
:
...
...
@@ -480,7 +462,7 @@ func (p *parser) term() (start, end instr) {
func
(
p
*
parser
)
closure
()
(
start
,
end
instr
)
{
start
,
end
=
p
.
term
()
if
start
==
nil
||
p
.
error
!=
""
{
if
start
==
nil
{
return
}
switch
p
.
c
()
{
...
...
@@ -515,7 +497,7 @@ func (p *parser) closure() (start, end instr) {
}
switch
p
.
nextc
()
{
case
'*'
,
'+'
,
'?'
:
p
.
error
=
ErrBadClosure
p
.
error
(
ErrBadClosure
)
}
return
}
...
...
@@ -523,9 +505,6 @@ func (p *parser) closure() (start, end instr) {
func
(
p
*
parser
)
concatenation
()
(
start
,
end
instr
)
{
for
{
nstart
,
nend
:=
p
.
closure
()
if
p
.
error
!=
""
{
return
}
switch
{
case
nstart
==
nil
:
// end of this concatenation
if
start
==
nil
{
// this is the empty string
...
...
@@ -545,9 +524,6 @@ func (p *parser) concatenation() (start, end instr) {
func
(
p
*
parser
)
regexp
()
(
start
,
end
instr
)
{
start
,
end
=
p
.
concatenation
()
if
p
.
error
!=
""
{
return
}
for
{
switch
p
.
c
()
{
default
:
...
...
@@ -555,9 +531,6 @@ func (p *parser) regexp() (start, end instr) {
case
'|'
:
p
.
nextc
()
nstart
,
nend
:=
p
.
concatenation
()
if
p
.
error
!=
""
{
return
}
alt
:=
new
(
_Alt
)
p
.
re
.
add
(
alt
)
alt
.
left
=
start
...
...
@@ -593,31 +566,31 @@ func (re *Regexp) eliminateNops() {
}
}
func
(
re
*
Regexp
)
doParse
()
string
{
func
(
re
*
Regexp
)
doParse
()
{
p
:=
newParser
(
re
)
start
:=
new
(
_Start
)
re
.
add
(
start
)
s
,
e
:=
p
.
regexp
()
if
p
.
error
!=
""
{
return
p
.
error
}
start
.
setNext
(
s
)
re
.
start
=
start
e
.
setNext
(
re
.
add
(
new
(
_End
)))
re
.
eliminateNops
()
return
p
.
error
}
// CompileRegexp parses a regular expression and returns, if successful, a Regexp
// object that can be used to match against text.
func
CompileRegexp
(
str
string
)
(
regexp
*
Regexp
,
error
string
)
{
regexp
=
new
(
Regexp
)
// doParse will panic if there is a parse error.
defer
func
()
{
if
e
:=
recover
();
e
!=
nil
{
regexp
=
nil
error
=
e
.
(
string
)
// Will re-panic if error was not a string, e.g. nil-pointer exception
}
}()
regexp
.
expr
=
str
regexp
.
inst
=
make
([]
instr
,
0
,
20
)
error
=
regexp
.
doParse
()
if
error
!=
""
{
regexp
=
nil
}
regexp
.
doParse
()
return
}
...
...
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