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