class Rouge::RegexLexer::StateDSL

Attributes

rules[R]

Public Class Methods

new(name, &defn) click to toggle source
# File lib/rouge/regex_lexer.rb, line 45
def initialize(name, &defn)
  @name = name
  @defn = defn
  @rules = []
  @loaded = false
end

Public Instance Methods

appended(&defn) click to toggle source
# File lib/rouge/regex_lexer.rb, line 68
def appended(&defn)
  parent_defn = @defn
  StateDSL.new(@name) do
    instance_eval(&parent_defn)
    instance_eval(&defn)
  end
end
prepended(&defn) click to toggle source
# File lib/rouge/regex_lexer.rb, line 60
def prepended(&defn)
  parent_defn = @defn
  StateDSL.new(@name) do
    instance_eval(&defn)
    instance_eval(&parent_defn)
  end
end
to_state(lexer_class) click to toggle source
# File lib/rouge/regex_lexer.rb, line 52
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

Protected Instance Methods

mixin(state) click to toggle source

Mix in the rules from another state into this state. The rules from the mixed-in state will be tried in order before moving on to the rest of the rules in this state.

# File lib/rouge/regex_lexer.rb, line 139
def mixin(state)
  rules << state.to_s
end
rule(re, tok=nil, next_state=nil, &callback) click to toggle source

Define a new rule for this state.

@overload rule(re, token, next_state=nil) @overload rule(re, &callback)

@param [Regexp] re

a regular expression for this rule to test.

@param [String] tok

the token type to yield if `re` matches.

@param [#to_s] next_state

(optional) a state to push onto the stack if `re` matches.
If `next_state` is `:pop!`, the state stack will be popped
instead.

@param [Proc] callback

a block that will be evaluated in the context of the lexer
if `re` matches.  This block has access to a number of lexer
methods, including {RegexLexer#push}, {RegexLexer#pop!},
{RegexLexer#token}, and {RegexLexer#delegate}.  The first
argument can be used to access the match groups.
# File lib/rouge/regex_lexer.rb, line 96
def rule(re, tok=nil, next_state=nil, &callback)
  if tok.nil? && callback.nil?
    raise "please pass `rule` a token to yield or a callback"
  end

  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
    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)
end

Private Instance Methods

load!() click to toggle source
# File lib/rouge/regex_lexer.rb, line 144
def load!
  return if @loaded
  @loaded = true
  instance_eval(&@defn)
end