Skip to content

Instantly share code, notes, and snippets.

@mjackson
Created July 24, 2010 22:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjackson/489025 to your computer and use it in GitHub Desktop.
Save mjackson/489025 to your computer and use it in GitHub Desktop.
require 'citrus'
Citrus.eval(<<'CODE')
grammar RubyString
rule string
single_quoted_string | double_quoted_string
end
# This should be expanded to account for escaped single quotes.
rule single_quoted_string
"'" (!"'" .)* "'"
end
# This should be expanded to account for escaped double quotes.
rule double_quoted_string
('"' (string_interpolation | !'"' .)* '"') {
def interpolations
find(:string_interpolation)
end
def contains_malformed_interpolation?
interpolations.any? {|s| s.malformed? }
end
}
end
rule string_interpolation
('#{' ruby_curly_source '}') {
def malformed?
!! (ruby_curly_source.text =~ /^\s|\s$/)
end
}
end
# Ruby source code that may be contained inside curly braces.
rule ruby_curly_source
(!'}' (ruby_curly_block | .))*
end
rule ruby_curly_block
'{' ruby_curly_source '}'
end
end
CODE
if $0 == __FILE__
require 'test/unit'
class RubyStringTest < Test::Unit::TestCase
def test_ruby_curly_block
m = RubyString.parse('{}', :root => :ruby_curly_block)
assert(m)
m = RubyString.parse('{ some_var }', :root => :ruby_curly_block)
assert(m)
m = RubyString.parse('{ :a => {} }', :root => :ruby_curly_block)
assert(m)
end
def test_ruby_curly_source
m = RubyString.parse('some_call', :root => :ruby_curly_source)
assert(m)
m = RubyString.parse('some_call_with_a_block {}', :root => :ruby_curly_source)
assert(m)
end
def test_string_interpolation
m = RubyString.parse('#{}', :root => :string_interpolation)
assert(m)
m = RubyString.parse('#{some_var}', :root => :string_interpolation)
assert(m)
assert(!m.malformed?)
m = RubyString.parse('#{ some_var }', :root => :string_interpolation)
assert(m)
assert(m.malformed?)
m = RubyString.parse('#{some_call {}.to_s}', :root => :string_interpolation)
assert(m)
assert(!m.malformed?)
m = RubyString.parse('#{ some_call {}.to_s }', :root => :string_interpolation)
assert(m)
assert(m.malformed?)
end
def test_single_quoted_string
m = RubyString.parse("''", :root => :single_quoted_string)
assert(m)
m = RubyString.parse("'a'", :root => :single_quoted_string)
assert(m)
end
def test_double_quoted_string
m = RubyString.parse('""', :root => :double_quoted_string)
assert(m)
m = RubyString.parse('"a"', :root => :double_quoted_string)
assert(m)
m = RubyString.parse('"a #{some_var} string"', :root => :double_quoted_string)
assert(m)
assert(!m.contains_malformed_interpolation?)
m = RubyString.parse('"a #{ some_var} string"', :root => :double_quoted_string)
assert(m)
assert(m.contains_malformed_interpolation?)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment