Skip to content

Commit

Permalink
Move the grammar into the project, and rake tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Phoenix committed Feb 4, 2011
1 parent 152fb01 commit 130440b
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 65 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
*.rbc
19 changes: 19 additions & 0 deletions Rakefile
@@ -0,0 +1,19 @@
require 'rake/testtask'

$:.unshift "lib"

task :default => :test

desc "Run tests"
Rake::TestTask.new do |t|
t.test_files = FileList['test/test*.rb']
t.verbose = true
end

task :grammar do
require 'kpeg'
require 'kpeg/format'

gr = KPeg::GrammarRenderer.new(KPeg::FORMAT)
gr.render(STDOUT)
end
69 changes: 69 additions & 0 deletions lib/kpeg/format.rb
@@ -0,0 +1,69 @@
require 'kpeg'

module KPeg
FORMAT = KPeg.grammar do |g|
g.sp = g.kleene " "
g.var = g.any("-", /[a-zA-Z][-_a-zA-Z0-9]*/)
g.var_ref = g.seq(:var) { |x| ref(x) }

g.dbl_escape_quote = g.str('\"') { '"' }
g.dbl_not_quote = g.many(g.any(:dbl_escape_quote, /[^"]/)) { |*a| a.join }
g.dbl_string = g.seq('"', g.t(:dbl_not_quote, "str"), '"') { |x| str(x) }

g.sgl_escape_quote = g.str("\\'") { "'" }
g.sgl_not_quote = g.many(g.any(:sgl_escape_quote, /[^']/)) { |*a| a.join }
g.sgl_string = g.seq("'", g.t(:sgl_not_quote, "str"), "'") { |x| str(x) }

g.string = g.any(:dbl_string, :sgl_string)

g.not_slash = g.many(g.any('\/', %r![^/]!)) { |*a| a.join }
g.regexp = g.seq('/', :not_slash, '/') { |_,x,_| reg(Regexp.new(x)) }

g.char = /[a-zA-Z0-9]/
g.char_range = g.seq('[', g.t(:char, "l"), '-', g.t(:char, "r"), ']') {
|l,r| range(l, r)
}

g.range_elem = /([1-9][0-9]*)|\*/
g.mult_range = g.seq('[', :sp, g.t(:range_elem, "l"), :sp, ',',
:sp, g.t(:range_elem, "r"), :sp, ']') {
|a,b|
[a == "*" ? nil : a.to_i,
b == "*" ? nil : b.to_i]
}

g.curly_block = g.seq(:curly) { |a| Array(a[1]).join }
g.curly = g.seq("{", g.kleene(g.any(/[^{}]+/, :curly)), "}")

g.spaces = g.kleene(" ")

g.value = g.seq(:value, ":", :var) { |a,_,b| t(a,b) } \
| g.seq(:value, "?") { |v,_| maybe(v) } \
| g.seq(:value, "+") { |v,_| many(v) } \
| g.seq(:value, "*") { |v,_| kleene(v) } \
| g.seq(:value, :mult_range) { |v,r| multiple(v, *r) } \
| g.seq("&", :value) { |_,v| andp(v) } \
| g.seq("!", :value) { |_,v| notp(v) } \
| g.seq(:value, :spaces, :value) { |a,_,b| seq(a, b) } \
| g.seq("(", g.t(:outer, "o"), ")") { |o| o } \
| g.seq(:curly_block) { |a| action(a) } \
| g.char_range | g.regexp | g.string | g.var_ref

g.bsp = g.kleene g.any(" ", "\n")

g.choose_cont = g.seq(:bsp, "|", :bsp, g.t(:value, "v")) { |x| x }
g.outer = g.seq(:value, g.many(:choose_cont)) {
|a,b| b.kind_of?(Array) ? any(a, *b) : any(a, b)
} \
| g.value

g.assignment = g.seq(:sp, g.t(:var, "v"), :sp, "=", :sp, g.t(:outer, "o")) {
|v,e| set(v, e); [:set, v, e]
}

g.assignments = g.seq(:assignment, g.maybe([:sp, "\n", :assignments])) {
|a,b| b.empty? ? a : [:rules, a, b.last]
}
g.root = g.seq(:assignments, :sp, g.maybe("\n")) { |a,_,_| a }
end
end
67 changes: 2 additions & 65 deletions test/test_kpeg_format.rb
@@ -1,74 +1,11 @@
require 'test/unit'
require 'kpeg'
require 'kpeg/format'
require 'stringio'
require 'rubygems'

class TestKPegFormat < Test::Unit::TestCase
G = KPeg.grammar do |g|
g.sp = g.kleene " "
g.var = g.any("-", /[a-zA-Z][-_a-zA-Z0-9]*/)
g.var_ref = g.seq(:var) { |x| ref(x) }

g.dbl_escape_quote = g.str('\"') { '"' }
g.dbl_not_quote = g.many(g.any(:dbl_escape_quote, /[^"]/)) { |*a| a.join }
g.dbl_string = g.seq('"', g.t(:dbl_not_quote), '"') { |x| str(x) }

g.sgl_escape_quote = g.str("\\'") { "'" }
g.sgl_not_quote = g.many(g.any(:sgl_escape_quote, /[^']/)) { |*a| a.join }
g.sgl_string = g.seq("'", g.t(:sgl_not_quote), "'") { |x| str(x) }

g.string = g.any(:dbl_string, :sgl_string)

g.not_slash = g.many(g.any('\/', %r![^/]!)) { |*a| a.join }
g.regexp = g.seq('/', :not_slash, '/') { |_,x,_| reg(Regexp.new(x)) }

g.char = /[a-zA-Z0-9]/
g.char_range = g.seq('[', g.t(:char), '-', g.t(:char), ']') {
|l,r| range(l, r)
}

g.range_elem = /([1-9][0-9]*)|\*/
g.mult_range = g.seq('[', :sp, g.t(:range_elem), :sp, ',',
:sp, g.t(:range_elem), :sp, ']') {
|a,b|
[a == "*" ? nil : a.to_i,
b == "*" ? nil : b.to_i]
}

g.curly_block = g.seq(:curly) { |a| Array(a[1]).join }
g.curly = g.seq("{", g.kleene(g.any(/[^{}]+/, :curly)), "}")

g.spaces = g.kleene(" ")

g.value = g.seq(:value, ":", :var) { |a,_,b| t(a,b) } \
| g.seq(:value, "?") { |v,_| maybe(v) } \
| g.seq(:value, "+") { |v,_| many(v) } \
| g.seq(:value, "*") { |v,_| kleene(v) } \
| g.seq(:value, :mult_range) { |v,r| multiple(v, *r) } \
| g.seq("&", :value) { |_,v| andp(v) } \
| g.seq("!", :value) { |_,v| notp(v) } \
| g.seq(:value, :spaces, :value) { |a,_,b| seq(a, b) } \
| g.seq("(", g.t(:outer), ")") { |o| o } \
| g.seq(:curly_block) { |a| action(a) } \
| g.char_range | g.regexp | g.string | g.var_ref

g.bsp = g.kleene g.any(" ", "\n")

g.choose_cont = g.seq(:bsp, "|", :bsp, g.t(:value)) { |x| x }
g.outer = g.seq(:value, g.many(:choose_cont)) {
|a,b| b.kind_of?(Array) ? any(a, *b) : any(a, b)
} \
| g.value

g.assignment = g.seq(:sp, g.t(:var), :sp, "=", :sp, g.t(:outer)) {
|v,e| set(v, e); [:set, v, e]
}

g.assignments = g.seq(:assignment, g.maybe([:sp, "\n", :assignments])) {
|a,b| b.empty? ? a : [:rules, a, b.last]
}
g.root = g.seq(:assignments, :sp, g.maybe("\n")) { |a,_,_| a }
end
G = KPeg::FORMAT

def match(str, gram=nil)
parc = KPeg::Parser.new(str, G)
Expand Down

0 comments on commit 130440b

Please sign in to comment.