Module: Ibex::Codegen::RubyLexer
- Included in:
- Ruby
- Defined in:
- lib/ibex/codegen/ruby_lexer.rb,
sig/ibex/codegen/ruby_lexer.rbs
Overview
Generated lexer tables and action methods.
Instance Method Summary collapse
- #append_lexer(lines) ⇒ void
- #append_lexer_actions(lines, lexer) ⇒ void
- #append_lexer_rules(lines, lexer) ⇒ void
- #lexer_action_source(rule) ⇒ String
- #lexer_rule_literal(rule) ⇒ String
Instance Method Details
#append_lexer(lines) ⇒ void
This method returns an undefined value.
11 12 13 14 15 16 17 18 19 20 |
# File 'lib/ibex/codegen/ruby_lexer.rb', line 11 def append_lexer(lines) # @type self: Ruby lexer = @grammar.lexer return unless lexer lines << " include Ibex::Runtime::GeneratedLexer" lines << " LEXER_STATES = #{lexer.states.inspect}.freeze" append_lexer_rules(lines, lexer) append_lexer_actions(lines, lexer) end |
#append_lexer_actions(lines, lexer) ⇒ void
This method returns an undefined value.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/ibex/codegen/ruby_lexer.rb', line 50 def append_lexer_actions(lines, lexer) # @type self: Ruby lexer.rules.each do |rule| next unless rule.action source = lexer_action_source(rule) if @line_convert location = rule.location lines << " class_eval(#{source.dump}, #{location[:file].inspect}, #{location[:line]})" else source.lines.each { |line| lines << " #{line.rstrip}" } end lines << "" end end |
#append_lexer_rules(lines, lexer) ⇒ void
This method returns an undefined value.
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/ibex/codegen/ruby_lexer.rb', line 23 def append_lexer_rules(lines, lexer) # @type self: Ruby by_state = lexer.states.to_h do |state| rules = lexer.rules.select { |rule| rule.state == state }.map { |rule| lexer_rule_literal(rule) } [state.to_sym, "[#{rules.join(', ')}].freeze"] end source = by_state.map { |state, rules| "#{state.inspect} => #{rules}" }.join(", ") lines << " LEXER_RULES_BY_STATE = { #{source} }.freeze" lines << "" end |
#lexer_action_source(rule) ⇒ String
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ibex/codegen/ruby_lexer.rb', line 67 def lexer_action_source(rule) action = rule.action || "" binding = nil #: String? if (match = action.match(/\A\s*\|([a-z_][a-zA-Z0-9_]*)\|\s*(.*)\z/m)) parameter = match[1] || "s" binding = "#{parameter} = _ibex_lexeme" action = match[2] || "" end lines = ["private def _ibex_lexer_action_#{rule.id}(_ibex_lexeme)"] lines << " #{binding}" if binding lines << " #{action}" lines << "end" "#{lines.join("\n")}\n" end |
#lexer_rule_literal(rule) ⇒ String
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/ibex/codegen/ruby_lexer.rb', line 35 def lexer_rule_literal(rule) # @type self: Ruby flags = 0 flags |= Regexp::IGNORECASE if rule..include?("i") flags |= Regexp::MULTILINE if rule..include?("m") flags |= Regexp::EXTENDED if rule..include?("x") action = rule.action ? ":_ibex_lexer_action_#{rule.id}" : "nil" terminal = rule.token && @grammar.symbol(rule.token) token = terminal ? external_token_expression(terminal) : "nil" regexp = "Regexp.new(#{"\\A(?:#{rule.pattern})".dump}, #{flags}).freeze" "{ id: #{rule.id}, kind: #{rule.kind.inspect}, token: #{token}, " \ "regexp: #{regexp}, action: #{action} }.freeze" end |