class Rouge::RegexLexer::StateDSL

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