summaryrefslogtreecommitdiff
path: root/lib/coderay
diff options
context:
space:
mode:
Diffstat (limited to 'lib/coderay')
-rw-r--r--lib/coderay/rule_based_scanner.rb63
1 files changed, 33 insertions, 30 deletions
diff --git a/lib/coderay/rule_based_scanner.rb b/lib/coderay/rule_based_scanner.rb
index 9239cf6..f354c36 100644
--- a/lib/coderay/rule_based_scanner.rb
+++ b/lib/coderay/rule_based_scanner.rb
@@ -2,6 +2,7 @@ module CodeRay
module Scanners
class RuleBasedScanner < Scanner
+ Pattern = Struct.new :pattern
Groups = Struct.new :token_kinds
Kind = Struct.new :token_kind
Push = Struct.new :state
@@ -43,53 +44,51 @@ module CodeRay
end
def on *pattern_and_actions
- if index = pattern_and_actions.find_index { |item| !item.is_a?(Check) }
- preconditions = pattern_and_actions[0..index - 1] if index > 0
- pattern = pattern_and_actions[index] or raise 'I need a pattern!'
- actions = pattern_and_actions[index + 1..-1] or raise 'I need actions!'
+ if index = pattern_and_actions.find_index { |item| !(item.is_a?(Check) || item.is_a?(Regexp) || item.is_a?(Pattern)) }
+ conditions = pattern_and_actions[0..index - 1] or raise 'I need conditions or a pattern!'
+ actions = pattern_and_actions[index..-1] or raise 'I need actions!'
+ else
+ raise "invalid rule structure: #{pattern_and_actions.map(&:class)}"
end
- precondition_expression = ''
- if preconditions
- for precondition in preconditions
- case precondition
+ condition_expressions = []
+ if conditions
+ for condition in conditions
+ case condition
when CheckIf
- case precondition.condition
+ case condition.condition
when Proc
- precondition_expression << "#{make_callback(precondition.condition)} && "
+ condition_expressions << "#{make_callback(condition.condition)}"
when Symbol
- precondition_expression << "#{precondition.condition} && "
+ condition_expressions << "#{condition.condition}"
else
- raise "I don't know how to evaluate this check_if precondition: %p" % [precondition.condition]
+ raise "I don't know how to evaluate this check_if condition: %p" % [condition.condition]
end
when CheckUnless
- case precondition.condition
+ case condition.condition
when Proc
- precondition_expression << "!#{make_callback(precondition.condition)} && "
+ condition_expressions << "!#{make_callback(condition.condition)}"
when Symbol
- precondition_expression << "!#{precondition.condition} && "
+ condition_expressions << "!#{condition.condition}"
else
- raise "I don't know how to evaluate this check_unless precondition: %p" % [precondition.condition]
+ raise "I don't know how to evaluate this check_unless condition: %p" % [condition.condition]
end
+ when Pattern
+ case condition.pattern
+ when Proc
+ condition_expressions << "match = scan(#{make_callback(condition.pattern)})"
+ else
+ raise "I don't know how to evaluate this pattern: %p" % [condition.pattern]
+ end
+ when Regexp
+ condition_expressions << "match = scan(#{condition.inspect})"
else
- raise "I don't know how to evaluate this precondition: %p" % [precondition]
+ raise "I don't know how to evaluate this pattern/condition: %p" % [condition]
end
end
end
- case pattern
- when String
- raise
- pattern_expression = pattern
- when Regexp
- pattern_expression = pattern.inspect
- when Proc
- pattern_expression = make_callback(pattern)
- else
- raise "I don't know how to evaluate this pattern: %p" % [pattern]
- end
-
- @code << " #{'els' unless @first}if #{precondition_expression}match = scan(#{pattern_expression})\n"
+ @code << " #{'els' unless @first}if #{condition_expressions.join(' && ')}\n"
for action in actions
case action
@@ -167,6 +166,10 @@ module CodeRay
Groups.new token_kinds
end
+ def pattern pattern = nil, &block
+ Pattern.new pattern || block
+ end
+
def kind token_kind = nil, &block
Kind.new token_kind || block
end