lib/textpow/syntax.rb in textpow1x-1.1.0 vs lib/textpow/syntax.rb in textpow1x-1.2.0
- old
+ new
@@ -2,41 +2,36 @@
RUBY_19 = (RUBY_VERSION > "1.9.0")
end
require 'oniguruma' unless Textpow::RUBY_19
module Textpow
+ # at load time we do not know all patterns / all syntaxes
+ # so we store a proxy, that tries to find the correct syntax at runtime
class SyntaxProxy
- def initialize hash, syntax
+ def initialize(included_name, syntax)
@syntax = syntax
- @proxy = hash["include"]
+ @included_name = included_name
end
def method_missing method, *args, &block
- if @proxy
- @proxy_value = proxy unless @proxy_value
- if @proxy_value
- @proxy_value.send(method, *args, &block)
- else
- STDERR.puts "Failed proxying #{@proxy}.#{method}(#{args.join(', ')})"
- end
+ if @proxy ||= proxy
+ @proxy.send(method, *args, &block)
+ else
+ STDERR.puts "Failed proxying #{@proxy_name}.#{method}(#{args.join(', ')})"
end
end
+ private
+
def proxy
- case @proxy
+ case @included_name
when /^#/
- if @syntax.repository && @syntax.repository[@proxy[1..-1]]
- #puts "Repository"
- #@table["syntax"].repository.each_key{|k| puts k}
- return @syntax.repository[@proxy[1..-1]]
- end
- when "$self"
- return @syntax
- when "$base"
- return @syntax
+ @syntax.repository and @syntax.repository[@included_name[1..-1]]
+ when "$self", "$base"
+ @syntax
else
- return @syntax.syntaxes[@proxy]
+ @syntax.syntaxes[@included_name] || Textpow.syntax(@included_name)
end
end
end
class SyntaxNode
@@ -101,11 +96,11 @@
Regexp.new(value)
else
Oniguruma::ORegexp.new(value, :options => Oniguruma::OPTION_CAPTURE_GROUP)
end
instance_variable_set("@#{key}", regex)
- rescue ArgumentError => e
+ rescue RegexpError, ArgumentError => e
raise ParsingError, "Parsing error in #{value}: #{e.to_s}"
end
when "content", "fileTypes", "name", "contentName", "end", "scopeName", "keyEquivalent"
instance_variable_set("@#{key}", value)
when "captures", "beginCaptures", "endCaptures"
@@ -141,24 +136,23 @@
def parse_repository repository
@repository = {}
repository.each do |key, value|
if value["include"]
- @repository[key] = SyntaxProxy.new( value, self.syntax )
+ @repository[key] = SyntaxProxy.new(value["include"], syntax)
else
- @repository[key] = SyntaxNode.new( value, self.syntax, @name_space )
+ @repository[key] = SyntaxNode.new(value, syntax, @name_space)
end
end
end
def create_children patterns
- @patterns = []
- patterns.each do |p|
- if p["include"]
- @patterns << SyntaxProxy.new( p, self.syntax )
+ @patterns = patterns.map do |pattern|
+ if pattern["include"]
+ SyntaxProxy.new(pattern["include"], syntax)
else
- @patterns << SyntaxNode.new( p, self.syntax, @name_space )
+ SyntaxNode.new(pattern, syntax, @name_space)
end
end
end
def parse_captures name, pattern, match, processor
@@ -237,23 +231,28 @@
else
Oniguruma::ORegexp.new( regstring ).match( string, position )
end
end
+ # find earliest matching pattern
def match_first_son(string, position)
return if not patterns
- match = nil
- patterns.each do |p|
- tmatch = p.match_first string, position
- if tmatch
- if not match or match_offset(match[1]).first > match_offset(tmatch[1]).first
- match = tmatch
- end
- #break if tmatch[1].offset.first == position
+ earliest_match = nil
+ earliest_match_offset = nil
+ patterns.each do |pattern|
+ next unless match = pattern.match_first(string, position)
+
+ match_offset = match_offset(match[1]).first
+ return match if match_offset == 0 # no need to look any further
+
+ if not earliest_match or earliest_match_offset > match_offset
+ earliest_match = match
+ earliest_match_offset = match_offset
end
end
- match
+
+ earliest_match
end
def parse_line(stack, line, processor)
processor.new_line line
top, match = stack.last