Class: Lex::Lexer::RuleDSL Private

Inherits:
Object
  • Object
show all
Defined in:
lib/lex/lexer/rule_dsl.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Rules DSL used internally by Lex::Lexer

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRuleDSL

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of RuleDSL.



18
19
20
21
22
23
24
25
26
# File 'lib/lex/lexer/rule_dsl.rb', line 18

def initialize
  @state_info    = { initial: :inclusive }
  @state_ignore  = { initial: '' }  # Ignored characters for each state
  @state_error   = {} # Error conditions for each state
  @state_re      = Hash.new { |hash, name| hash[name] = {}} # Regexes for each state
  @state_names   = {} # Symbol names for each state
  @state_lexemes = Hash.new { |hash, name| hash[name] = State.new(name) }
  @lex_tokens    = []  # List of valid tokens
end

Instance Attribute Details

#lex_tokensObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/lex/lexer/rule_dsl.rb', line 9

def lex_tokens
  @lex_tokens
end

#state_errorObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/lex/lexer/rule_dsl.rb', line 9

def state_error
  @state_error
end

#state_ignoreObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/lex/lexer/rule_dsl.rb', line 9

def state_ignore
  @state_ignore
end

#state_infoObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/lex/lexer/rule_dsl.rb', line 9

def state_info
  @state_info
end

#state_lexemesObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/lex/lexer/rule_dsl.rb', line 9

def state_lexemes
  @state_lexemes
end

#state_namesObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/lex/lexer/rule_dsl.rb', line 9

def state_names
  @state_names
end

#state_reObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/lex/lexer/rule_dsl.rb', line 9

def state_re
  @state_re
end

Instance Method Details

#error(states = :initial, &action) ⇒ Object

Define error condition for a state



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/lex/lexer/rule_dsl.rb', line 104

def error(states = :initial, &action)
  state_names = states.to_s.split('_').map(&:to_sym)
  state_names.each do |state_name|
    @state_error[state_name] = action
  end
  @state_info.each do |state_name, state_type|
    if state_name != :initial && state_type == :inclusive
      if !@state_error.key?(state_name)
        @state_error[state_name] = @state_error[:initial]
      end
    end
  end
end

#ignore(states, value = (not_set = true)) ⇒ Object

Define ignore condition for a state

Parameters:

  • states (Symbol)

    the optional state names

  • value (String) (defaults to: (not_set = true))

    the characters to ignore



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/lex/lexer/rule_dsl.rb', line 79

def ignore(states, value = (not_set = true))
  if not_set
    value = states
    state_names = [:initial]
  else
    state_names = states.to_s.split('_').map(&:to_sym)
  end
  if !value.is_a?(String)
    logger.error("Ignore rule '#{value}' has to be defined with a string")
  end
  state_names.each do |state_name|
    @state_ignore[state_name] = value
  end
  @state_info.each do |state_name, state_type|
    if state_name != :initial && state_type == :inclusive
      if !@state_ignore.key?(state_name)
        @state_ignore[state_name] = @state_ignore[:initial]
      end
    end
  end
end

#rule(name, pattern, &action) ⇒ Object

Specify lexing rule

Parameters:

  • name (Symbol)

    the rule name

  • pattern (Regex)

    the regex pattern



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/lex/lexer/rule_dsl.rb', line 51

def rule(name, pattern, &action)
  state_names, token_name = *extract_state_token(name)
  if token_name =~ /^[[:upper:]]*$/ && !@lex_tokens.include?(token_name)
    complain("Rule '#{name}' defined for" \
             " an unspecified token #{token_name}")
  end
  state_names.each do |state_name|
    state = @state_lexemes[state_name]
    state << Lexeme.new(token_name, pattern, &action)
  end
  update_inclusive_states
  state_names.each do |state_name|
    if @state_re[state_name].key?(token_name)
      complain("Rule '#{name}' redefined.")
    end
    @state_re[state_name][token_name] = pattern
  end
end

#states(value) ⇒ Object

Add states to lexer



38
39
40
# File 'lib/lex/lexer/rule_dsl.rb', line 38

def states(value)
  @state_info.merge!(value)
end

#tokens(*value) ⇒ Object

Add tokens to lexer



31
32
33
# File 'lib/lex/lexer/rule_dsl.rb', line 31

def tokens(*value)
  @lex_tokens = value
end