Module: Rbscmlex::Lexer::Identifier

Defined in:
lib/rbscmlex/lexer.rb

Overview

Holds functions to check a literal is valid as an identifier defined in R7RS.

Call identifier? function as follows:

Identifier.identifier?(literal)

It returns true if the literal is valid as an identifier.

Constant Summary collapse

DIGIT =
"0-9"
LETTER =
"a-zA-Z"
SPECIAL_INITIAL =
"!\\$%&\\*/:<=>\\?\\^_~"
INITIAL =
"#{LETTER}#{SPECIAL_INITIAL}"
EXPLICIT_SIGN =
"\\+\\-"
SPECIAL_SUBSEQUENT =
"#{EXPLICIT_SIGN}\\.@"
SUBSEQUENT =
"#{INITIAL}#{DIGIT}#{SPECIAL_SUBSEQUENT}"
REGEXP_INITIAL =
Regexp.new("[#{INITIAL}]")
REGEXP_EXPLICIT_SIGN =
Regexp.new("[#{EXPLICIT_SIGN}]")
REGEXP_SUBSEQUENT =
Regexp.new("[#{SUBSEQUENT}]+")

Class Method Summary collapse

Class Method Details

.dot_identifier?(sub_literal) ⇒ Boolean

Returns:

  • (Boolean)


338
339
340
341
342
343
344
345
346
347
# File 'lib/rbscmlex/lexer.rb', line 338

def self.dot_identifier?(sub_literal)
  return false if sub_literal[0] != "."
  return true if sub_literal.size == 1
  if dot_subsequent?(sub_literal[1])
    return true if sub_literal.size == 2
    subsequent?(sub_literal[2..-1])
  else
    false
  end
end

.dot_subsequent?(sub_literal) ⇒ Boolean

Returns:

  • (Boolean)


349
350
351
352
# File 'lib/rbscmlex/lexer.rb', line 349

def self.dot_subsequent?(sub_literal)
  return true if sub_literal == "."
  sign_subsequent?(sub_literal)
end

.identifier?(literal) ⇒ Boolean

Returns:

  • (Boolean)


294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/rbscmlex/lexer.rb', line 294

def self.identifier?(literal)
  size = literal.size
  c = literal[0]
  case c
  when REGEXP_INITIAL
    return true if size == 1
    subsequent?(literal[1..-1])
  when REGEXP_EXPLICIT_SIGN
    return true if size == 1
    if literal[1] == "."
      dot_identifier?(literal[1..-1])
    else
      if sign_subsequent?(literal[1])
        return true if size == 2
        subsequent?(literal[2..-1])
      else
        false
      end
    end
  when "."
    dot_identifier?(literal)
  else
    false
  end
end

.sign_subsequent?(sub_literal) ⇒ Boolean

Returns:

  • (Boolean)


324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/rbscmlex/lexer.rb', line 324

def self.sign_subsequent?(sub_literal)
  return false if sub_literal.size != 1
  case sub_literal[0]
  when REGEXP_INITIAL
    true
  when REGEXP_EXPLICIT_SIGN
    true
  when "@"
    true
  else
    false
  end
end

.subsequent?(sub_literal) ⇒ Boolean

Returns:

  • (Boolean)


320
321
322
# File 'lib/rbscmlex/lexer.rb', line 320

def self.subsequent?(sub_literal)
  REGEXP_SUBSEQUENT === sub_literal
end