class Rouge::RegexLexer::StateDSL

def appended(&defn)

def appended(&defn)
  parent_defn = @defn
  StateDSL.new(@name) do
    instance_eval(&parent_defn)
    instance_eval(&defn)
  end
end

def close!

def close!
  @closed = true
end

def context_sensitive?(re)

def context_sensitive?(re)
  source = re.source
  return true if source =~ /[(][?]<?[!=]/
  # anchors count as lookahead/behind
  return true if source =~ /[$^]/
  false
end

def initialize(name, &defn)

def initialize(name, &defn)
  @name = name
  @defn = defn
  @rules = []
  @loaded = false
  @closed = false
end

def load!

def load!
  return if @loaded
  @loaded = true
  instance_eval(&@defn)
end

def mixin(state)

to the rest of the rules in this state.
from the mixed-in state will be tried in order before moving on
Mix in the rules from another state into this state. The rules
def mixin(state)
  rules << state.to_s
end

def prepended(&defn)

def prepended(&defn)
  parent_defn = @defn
  StateDSL.new(@name) do
    instance_eval(&defn)
    instance_eval(&parent_defn)
  end
end

def rule(re, tok=nil, next_state=nil, &callback)

Parameters:
  • callback (Proc) --
  • next_state (#to_s) --
  • tok (String) --
  • re (Regexp) --

Overloads:
  • rule(re, &callback)
  • rule(re, token, next_state=nil)
def rule(re, tok=nil, next_state=nil, &callback)
  raise ClosedState.new(self) if @closed
  if tok.nil? && callback.nil?
    raise "please pass `rule` a token to yield or a callback"
  end
  matches_empty = re =~ ''
  callback ||= case next_state
  when :pop!
    proc do |stream|
      puts "    yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug
      @output_stream.call(tok, stream[0])
      puts "    popping stack: 1" if @debug
      @stack.pop or raise 'empty stack!'
    end
  when :push
    proc do |stream|
      puts "    yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug
      @output_stream.call(tok, stream[0])
      puts "    pushing :#{@stack.last.name}" if @debug
      @stack.push(@stack.last)
    end
  when Symbol
    proc do |stream|
      puts "    yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug
      @output_stream.call(tok, stream[0])
      state = @states[next_state] || self.class.get_state(next_state)
      puts "    pushing :#{state.name}" if @debug
      @stack.push(state)
    end
  when nil
    # cannot use an empty-matching regexp with no predicate
    raise InvalidRegex.new(re) if matches_empty
    proc do |stream|
      puts "    yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug
      @output_stream.call(tok, stream[0])
    end
  else
    raise "invalid next state: #{next_state.inspect}"
  end
  rules << Rule.new(re, callback)
  close! if matches_empty && !context_sensitive?(re)
end

def to_state(lexer_class)

def to_state(lexer_class)
  load!
  rules = @rules.map do |rule|
    rule.is_a?(String) ? lexer_class.get_state(rule) : rule
  end
  State.new(@name, rules)
end