Class: Rouge::RegexLexer::StateDSL

Inherits:
Object
  • Object
show all
Defined in:
lib/rouge/regex_lexer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, &defn) ⇒ StateDSL

Returns a new instance of StateDSL


46
47
48
49
50
51
# File 'lib/rouge/regex_lexer.rb', line 46

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

Instance Attribute Details

#rulesObject (readonly)

Returns the value of attribute rules


45
46
47
# File 'lib/rouge/regex_lexer.rb', line 45

def rules
  @rules
end

Instance Method Details

#appended(&defn) ⇒ Object


69
70
71
72
73
74
75
# File 'lib/rouge/regex_lexer.rb', line 69

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

#mixin(state) ⇒ Object (protected)

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.


140
141
142
# File 'lib/rouge/regex_lexer.rb', line 140

def mixin(state)
  rules << state.to_s
end

#prepended(&defn) ⇒ Object


61
62
63
64
65
66
67
# File 'lib/rouge/regex_lexer.rb', line 61

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

#rule(re, token, next_state = nil) ⇒ Object (protected) #rule(re, &callback) ⇒ Object (protected)

Define a new rule for this state.

Parameters:

  • re (Regexp)

    a regular expression for this rule to test.

  • tok (String) (defaults to: nil)

    the token type to yield if re matches.

  • next_state (#to_s) (defaults to: nil)

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

  • callback (Proc)

    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 Rouge::RegexLexer#push, Rouge::RegexLexer#pop!, Rouge::RegexLexer#token, and Rouge::RegexLexer#delegate. The first argument can be used to access the match groups.


97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/rouge/regex_lexer.rb', line 97

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

#to_state(lexer_class) ⇒ Object


53
54
55
56
57
58
59
# File 'lib/rouge/regex_lexer.rb', line 53

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