Class: RParsec::Keywords

Inherits:
Object
  • Object
show all
Extended by:
Parsers
Defined in:
lib/rparsec/keywords.rb

Overview

This class helps building lexers and parsers for keywords.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Parsers

alt, among, any, are, arent, char, comment_block, comment_line, eof, failure, get_index, integer, is, isnt, lazy, longest, map, mapn, not_among, not_char, not_string, number, one, range, regexp, satisfies, sequence, set_index, shortest, string, string_nocase, sum, throwp, token, value, watch, watchn, whitespace, whitespaces, word, zero

Constructor Details

#initialize(words, case_sensitive, default_lexer, keyword_symbol, &block) ⇒ Keywords

scanner has to return a string



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rparsec/keywords.rb', line 57

def initialize(words, case_sensitive, default_lexer, keyword_symbol, &block)
  @default_lexer = default_lexer
  @case_sensitive = case_sensitive
  @keyword_symbol = keyword_symbol
  # this guarantees that we have copy of the words array and all the word strings.
  words = copy_words(words, case_sensitive)
  @name_map = {}
  @symbol_map = {}
  word_map = {}
  words.each do |w|
    symbol = "#{keyword_symbol}:#{w}".to_sym
    word_map[w] = symbol
    parser = Parsers.token(symbol, &block)
    @symbol_map["#{w}".to_sym] = parser
    @name_map[w] = parser
  end
  @lexer = make_lexer(default_lexer, word_map)
end

Instance Attribute Details

#keyword_symbolObject (readonly)

The symbol used to identify a keyword token



18
19
20
# File 'lib/rparsec/keywords.rb', line 18

def keyword_symbol
  @keyword_symbol
end

#lexerObject (readonly)

The lexer that parses all the keywords represented



23
24
25
# File 'lib/rparsec/keywords.rb', line 23

def lexer
  @lexer
end

Class Method Details

.case_insensitive(words, default_lexer = word.token(:word), keyword_symbol = :keyword, &block) ⇒ Object

To create an instance that lexes the given keywords case insensitively. default_lexer is used to lex a token first, the token text is then compared with the given keywords. If it matches any of the keyword, a keyword token is generated instead using keyword_symbol. The block parameter, if present, is used to convert the token text to another object when the token is recognized during parsing phase.



52
53
54
# File 'lib/rparsec/keywords.rb', line 52

def self.case_insensitive(words, default_lexer = word.token(:word), keyword_symbol = :keyword, &block)
  new(words, false, default_lexer, keyword_symbol, &block)
end

.case_sensitive(words, default_lexer = word.token(:word), keyword_symbol = :keyword, &block) ⇒ Object

To create an instance that lexes the given keywords case sensitively. default_lexer is used to lex a token first, the token text is then compared with the given keywords. If it matches any of the keyword, a keyword token is generated instead using keyword_symbol. The block parameter, if present, is used to convert the token text to another object when the token is recognized during grammar parsing phase.



39
40
41
# File 'lib/rparsec/keywords.rb', line 39

def self.case_sensitive(words, default_lexer = word.token(:word), keyword_symbol = :keyword, &block)
  new(words, true, default_lexer, keyword_symbol, &block)
end

Instance Method Details

#case_sensitive?Boolean

Do we lex case sensitively?

Returns:

  • (Boolean)


28
# File 'lib/rparsec/keywords.rb', line 28

def case_sensitive? = @case_sensitive

#parser(key) ⇒ Object Also known as: []

Get the parser that recognizes the token of the given keyword during the parsing phase.

Raises:

  • (ArgumentError)


79
80
81
82
83
84
85
86
87
88
89
# File 'lib/rparsec/keywords.rb', line 79

def parser(key)
  result = nil
  if key.kind_of? String
    name = canonical_name(key)
    result = @name_map[name]
  else
    result = @symbol_map[key]
  end
  raise ArgumentError, "parser not found for #{key}" if result.nil?
  result
end