class RuboCop::AST::NodePattern::LexerRex
def action
def action yield end
def location
def location [ (filename || "<input>"), ].compact.join(":") end
def matches
def matches m = (1..9).map { |i| ss[i] } m.pop until m[-1] or m.empty? m end
def next_token
def next_token token = nil until ss.eos? or token do token = case state when nil then case when ss.skip(/\s+/) then # do nothing when ss.skip(/:(#{SYMBOL_NAME})/o) then action { emit :tSYMBOL, &:to_sym } when ss.skip(/"(.+?)"/) then action { emit :tSTRING } when ss.skip(/[-+]?\d+\.\d+/) then action { emit :tNUMBER, &:to_f } when ss.skip(/[-+]?\d+/) then action { emit :tNUMBER, &:to_i } when ss.skip(/#{Regexp.union( %w"( ) { | } [ ] < > $ ! ^ ` ... + * ? ," )}/o) then action { emit ss.matched, &:to_sym } when ss.skip(/#{REGEXP}/o) then action { emit_regexp } when ss.skip(/%(#{CONST_NAME})/o) then action { emit :tPARAM_CONST } when ss.skip(/%([a-z_]+)/) then action { emit :tPARAM_NAMED } when ss.skip(/%(\d*)/) then action { emit(:tPARAM_NUMBER) { |s| s.empty? ? 1 : s.to_i } } # Map `%` to `%1` when ss.skip(/_(#{IDENTIFIER})/o) then action { emit :tUNIFY } when ss.skip(/_/o) then action { emit :tWILDCARD } when ss.skip(/\#(#{CALL})/o) then action { @state = :ARG; emit :tFUNCTION_CALL, &:to_sym } when ss.skip(/#{IDENTIFIER}\?/o) then action { @state = :ARG; emit :tPREDICATE, &:to_sym } when ss.skip(/#{IDENTIFIER}/o) then action { emit :tNODE_TYPE, &:to_sym } when ss.skip(/\#.*/) then action { emit_comment } else text = ss.string[ss.pos .. -1] raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'" end when :ARG then case when ss.skip(/\(/) then action { @state = nil; emit :tARG_LIST } when ss.skip(//) then action { @state = nil } else text = ss.string[ss.pos .. -1] raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'" end else raise ScanError, "undefined state at #{location}: '#{state}'" end # token = case state next unless token # allow functions to trigger redo w/ nil end # while raise LexerError, "bad lexical result at #{location}: #{token.inspect}" unless token.nil? || (Array === token && token.size >= 2) # auto-switch state self.state = token.last if token && token.first == :state token end # def next_token
def parse str
def parse str self.ss = scanner_class.new str self.state ||= nil do_parse end
def parse_file path
def parse_file path self.filename = path open path do |f| parse f.read end end
def scanner_class
def scanner_class StringScanner end unless instance_methods(false).map(&:to_s).include?("scanner_class")