Skip to content

Commit

Permalink
looks like prev commit was a mistake
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewcooke committed Mar 5, 2016
1 parent 56e526a commit 6f5ad06
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/Parsers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ export GML

include("gml/GML.jl")
include("dot/DOT.jl")
include("regex/Regex.jl")
#include("regex/Regex.jl")

end
90 changes: 47 additions & 43 deletions src/regex/Regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ end
end

@auto_hash_equals type Repeat <: Pattern
patterns::Vector{Pattern}
pattern::Pattern
lo::Int
hi::Int
end
Expand All @@ -30,7 +30,7 @@ end

Literal(s::AbstractString) = (@assert length(s) == 1; Range(s[1], s[1]))
Literal(c::Char) = Range(c, c)
Dot() = Range(typemin(Char), typemax(Char))
Wild() = Range(typemin(Char), typemax(Char))

@auto_hash_equals type Group <: Pattern
index::Int
Expand All @@ -39,50 +39,54 @@ end

function make_pattern()

# group numbering is tricky - we need to number fomr the left and
# avoid repetitions on backtracking. so push entries (keyed by
# iter) to a stack on entering the group, pop on leaving.
group_count = Dict{Any, Int}()
group_stack = []
group_popped = Dict{Any, Int}()
function pre_group(i, p)
if !haskey(group_count, i)
group_count[i] = length(group_count) + 1
push!(group_stack, group_count[i])
@with_names begin

# group numbering is tricky - we need to number fomr the left and
# avoid repetitions on backtracking. so push entries (keyed by
# iter) to a stack on entering the group, pop on leaving.
group_count = Dict{Any, Int}()
group_stack = []
group_popped = Dict{Any, Int}()
function pre_group(i, p)
if !haskey(group_count, i)
group_count[i] = length(group_count) + 1
push!(group_stack, group_count[i])
end
p
end
p
end
function post_group(i, p)
if !haskey(group_popped, i)
group_popped[i] = pop!(group_stack)
function post_group(i, p)
if !haskey(group_popped, i)
group_popped[i] = pop!(group_stack)
end
Group(group_popped[i], p)
end
Group(group_popped[i], p)

make_sequence(p) = length(p) == 1 ? p[1] : Sequence(p)
make_choice(p) = length(p) == 1 ? p[1] : Choice(p)


literal = p"[^[\].*+\\|(){}?]" > Literal
escaped = ~Equal("\\") + Dot() > Literal
wild = E"." > Wild
outseq = Delayed()

atom = literal | escaped | wild | outseq
plus = atom + E"+" > make_rpt(1)
star = atom + E"*" > make_rpt(0)
opt = atom + E"?" > make_rpt(0, 1)
once = atom + !(E"*"|E"+"|E"?")

inseq = Plus(plus | star | opt | once) |> make_sequence
choice = PlusList(inseq, E"|") |> make_choice

open = ITransform(E"("+ !(e"?") , pre_group)
gchoice = IApp(open + choice + E")", post_group)
nchoice = E"(?:" + choice + E")"

outseq.matcher = Plus(gchoice | nchoice) |> make_sequence

return choice + Eos()
end

make_sequence(p) = length(p) == 1 ? p[1] : Sequence(p)
make_choice(p) = length(p) == 1 ? p[1] : Choice(p)


literal = p"[^[\].*+\\|(){}?]" > Literal
any = E"." > Dot
outseq = Delayed()

atom = literal | any | outseq
plus = atom + E"+" > make_rpt(1)
star = atom + E"*" > make_rpt(0)
opt = atom + E"?" > make_rpt(0, 1)
once = atom + !(E"*"|E"+"|E"?")

inseq = Plus(plus | star | opt | once) |> make_sequence
choice = PlusList(inseq, E"|") |> make_choice

open = ITransform(E"("+ !(e"?") , pre_group)
gchoice = IApp(open + choice + E")", post_group)
nchoice = E"(?:" + choice + E")"

outseq.matcher = Plus(gchoice | nchoice | literal) |> make_sequence

return choice + Eos()
end

end
23 changes: 19 additions & 4 deletions test/regex/pattern.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@

using ParserCombinator.Parsers.Regex; R = ParserCombinator.Parsers.Regex

for (s, r) in [("abc",
for (s, r) in [
("abc",
[R.Sequence([R.Literal('a'), R.Literal('b'), R.Literal('c')])]),
("a|b",
[R.Choice([R.Literal('a'), R.Literal('b')])]),
("aa|b",
[R.Choice([R.Sequence([R.Literal('a'), R.Literal('a')]), R.Literal('b')])]),
("a|bb",
[R.Choice([R.Literal('a'), R.Sequence([R.Literal('b'), R.Literal('b')])])]),
("(a|b)",
[R.Group(1, R.Choice([R.Literal('a'), R.Literal('b')]))]),
("(a|(b))",
Expand All @@ -16,11 +19,23 @@ for (s, r) in [("abc",
("a|b(?:c|d)",
[R.Choice([R.Literal('a'), R.Sequence([R.Literal('b'), R.Choice([R.Literal("c"), R.Literal("d")])])])]),
("a*",
[R.Repeat(0, typemax(Int), R.Literal('a'))]),
[R.Repeat(R.Literal('a'), 0, typemax(Int))]),
("a+",
[R.Repeat(1, typemax(Int), R.Literal('a'))]),
[R.Repeat(R.Literal('a'), 1, typemax(Int))]),
("ab+",
[R.Sequence([R.Literal('a'), R.Repeat(1, typemax(Int), R.Literal('b'))])])
[R.Sequence([R.Literal('a'), R.Repeat(R.Literal('b'), 1, typemax(Int))])]),
("a?a|b",
[R.Choice([R.Sequence([R.Repeat(R.Literal('a'), 0, 1), R.Literal('a')]), R.Literal('b')])]),
("aa?|b",
[R.Choice([R.Sequence([R.Literal('a'), R.Repeat(R.Literal('a'), 0, 1)]), R.Literal('b')])]),
("a|b?b",
[R.Choice([R.Literal('a'), R.Sequence([R.Repeat(R.Literal('b'), 0, 1), R.Literal('b')])])]),
("a|bb?",
[R.Choice([R.Literal('a'), R.Sequence([R.Literal('b'), R.Repeat(R.Literal('b'), 0, 1)])])]),
("a",
[R.Literal('a')]),
("\\+",
[R.Literal('+')])
]
print("$s...")
pattern = R.make_pattern()
Expand Down
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ module RegexTest
using ParserCombinator
using Base.Test
using Compat
include("regex/pattern.jl")
exit(0)
#include("regex/pattern.jl")
#exit(0)
end

module CoreTest
Expand Down

0 comments on commit 6f5ad06

Please sign in to comment.